Cancel a Label
Send a Label identifier and read data.isSuccess. That boolean is the entire
documented outcome of this operation.
What you'll build
- One request that asks Mailhub to cancel a Label you already purchased.
- A read of the one field the public contract defines for the result.
- A branch that stops rather than repeating the request after an ambiguous transport outcome.
Prerequisites
- An access token — see Authentication.
- A Label identifier —
data.postageLabel.idfrom Buy a Label from a Selected Rate, ordata.labelIdfrom Recover a Label Purchase After 202. They are the same value. - Python examples use the
requestspackage.
Step 1 — Send the cancellation
DELETE/api/v1/labels/{labelId}
The operation takes no request body. labelId is the path parameter.
- cURL
- JavaScript
- Python
- Java
curl -s -X DELETE \
"${MAILHUB_API_BASE_URL}/api/v1/labels/${LABEL_ID}" \
-H "Authorization: Bearer ${MAILHUB_ACCESS_TOKEN}"
const response = await fetch(
`${process.env.MAILHUB_API_BASE_URL}/api/v1/labels/${labelId}`,
{
method: 'DELETE',
headers: {Authorization: `Bearer ${process.env.MAILHUB_ACCESS_TOKEN}`},
},
);
const payload = await response.json();
// The one documented result. Record it; do not derive anything else from it.
const cancellationResult = payload.data?.isSuccess;
import os
import requests
response = requests.delete(
f"{os.environ['MAILHUB_API_BASE_URL']}/api/v1/labels/{label_id}",
headers={"Authorization": f"Bearer {os.environ['MAILHUB_ACCESS_TOKEN']}"},
)
payload = response.json()
# The one documented result. Record it; do not derive anything else from it.
cancellation_result = (payload.get("data") or {}).get("isSuccess")
// Java 11+ java.net.http — no MailHub package to install and no third-party client.
var request = HttpRequest.newBuilder()
.uri(URI.create(System.getenv("MAILHUB_API_BASE_URL") + "/api/v1/labels/" + labelId))
.header("Authorization", "Bearer " + System.getenv("MAILHUB_ACCESS_TOKEN"))
.DELETE()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
// Parse response.body() with your own JSON library and record data.isSuccess.
// Do not derive anything else from it.
Response
A successful cancellation answers with the public envelope, and the payload is one field:
{
"success": true,
"data": {
"isSuccess": true
},
"errors": null
}
That is the complete documented result. The public contract describes no carrier confirmation, no Label state transition, no financial field, and no Order or Shipment change here — see Cancel a Label for the boundary in full.
Use this next
Nothing. Cancellation is the end of the Label's documented workflow in this API. Keep the Label identifier in your own records alongside the result you read.
Expected result
A 200 whose data.isSuccess you have recorded against
f6c7d8e9-0a1b-4c2d-8e3f-4a5b6c7d8e9f in your own application.
Common outcomes
| Status | What it means | What to do |
|---|---|---|
200 | The operation completed. | Record data.isSuccess. |
404 | The Label was not found for your account. | Confirm you sent postageLabel.id and not the Shipment or Order identifier. |
422 | The Label cannot be cancelled as it stands — its Shipment has no tracking code to cancel against. | Do not resend the same request. See Label Errors. |
400, 401, 403, 409, and 500 follow the standard public error
envelope — see Error Handling.
Handle an ambiguous outcome
If the request times out or the response is lost, you cannot tell from the missing response whether the cancellation was applied. Do not blindly repeat it. No public reconciliation workflow is defined for this operation; route the case through your own operational process and see Retries and Ambiguous Outcomes.
Next steps
- Cancel shipping label in the API Reference — the complete parameter and response detail.
- Cancel a Label — eligibility, state boundaries, and every documented failure.
- Label Errors — the failure table for all three Label operations.
- Recipes — back to the section.