Work with Sub-accounts
Outcome
Use this guide to determine when the optional X-SubAccount-Id header affects
an operation, keep scope explicit where it matters in a workflow, and avoid
relying on the header where it has no effect. The matrix below is the
authoritative public guide; the API Reference remains the complete schema
source.
What a Sub-account means in this API
A Sub-account is an application scope beneath the authenticated Mailhub
Account. Some public operations allow the caller to select that scope through
X-SubAccount-Id.
Some existing Mailhub product screens may use the term Subcompany. Public API documentation uses Sub-account.
When to use X-SubAccount-Id
The header is optional for every current public operation. When an operation's matrix row supports it, omitting the header uses the authenticated Account context. Send an authorized value only for the operation-specific effect shown below; it is not a universal scope switch.
Header syntax
The public contract declares an optional UUID string header:
X-SubAccount-Id: <SUB_ACCOUNT_ID>
Public-operation behavior matrix
| Operation | Method and path | Header effect | What the caller should do |
|---|---|---|---|
| Login | POST /api/v1/auth/token | Optional: validates the selected Sub-account for token exchange but does not persist that scope in either returned token. | Use only when the token exchange itself needs that validation; do not rely on it to scope later requests. |
| Refresh token | POST /api/v1/auth/token/refresh | The operation does not read the header; a well-formed value does not change behavior. | Omit it; do not use it to establish request scope. |
| Logout | POST /api/v1/auth/token/revoke | The operation does not read the header; a well-formed value does not change behavior. | Omit it; do not use it to establish request scope. |
| Cancel shipping label | DELETE /api/v1/labels/{labelId} | Sending X-SubAccount-Id does not change the behavior of this operation. | Omit it; do not rely on it to scope this operation. |
| Download shipping label | GET /api/v1/labels/{labelId}/download | Sending X-SubAccount-Id does not change the behavior of this operation. | Omit it; do not rely on it to scope this operation. |
| List orders | GET /api/v1/orders | Optional: filters the Order list to the selected Sub-account. | Send it when listing that Sub-account; omit it to use the authenticated Account context. |
| Create an Order | POST /api/v1/orders | Optional: tags the newly created Order and its Shipments with the selected Sub-account. | Send it only when creating in that Sub-account. |
| Get order by ID | GET /api/v1/orders/{orderId} | Sending X-SubAccount-Id does not change the behavior of this operation. | Omit it; do not rely on it to scope this operation. |
| Updates order status. | PATCH /api/v1/orders/{orderId}/status | Sending X-SubAccount-Id does not change the behavior of this operation. | Omit it; do not rely on it to scope this operation. |
| Create shipping label | POST /api/v1/shipments/{shipmentId}/labels | Optional: evaluates the request against the selected Sub-account, which can narrow the carriers available to it. It does not change pricing and does not restrict resource access. | Send it when the request should use that Sub-account’s carrier availability; omit it to use the authenticated Account context. |
| Get shipment rates | POST /api/v1/shipments/{shipmentId}/rates | Optional: evaluates the request against the selected Sub-account, which can narrow the carriers available to it. It does not change pricing and does not restrict resource access. | Send it when the request should use that Sub-account’s carrier availability; omit it to use the authenticated Account context. |
| Create an Order with Rates | POST /api/v2/orders | Optional: tags the newly created Order and its Shipments with the selected Sub-account. | Send it only when creating in that Sub-account. |
Account-scoped example
Use the default Account context by omitting the optional header from the read-only List Orders request:
curl -s "${MAILHUB_API_BASE_URL}/api/v1/orders" \
-H "Authorization: Bearer ${MAILHUB_ACCESS_TOKEN}"
Sub-account-scoped example
For List Orders, the same read-only request can filter to an authorized Sub-account:
curl -s "${MAILHUB_API_BASE_URL}/api/v1/orders" \
-H "Authorization: Bearer ${MAILHUB_ACCESS_TOKEN}" \
-H "X-SubAccount-Id: <SUB_ACCOUNT_ID>"
Carrier operations
For Get Shipment Rates and Create Shipping Label, sending the header evaluates the request against the selected Sub-account, which can narrow the carriers available to it. A Rate you expect may therefore be absent when the header is sent and present when it is omitted.
The header does not change pricing, and it does not decide which Shipments, Rates, or Labels you may act on — that is enforced by Account ownership, whether or not you send it.
When not to use it
For Get Order, Update Order Status, Download Label, and Cancel Label, the
matrix records NoEffect: Sending X-SubAccount-Id does not change the
behavior of this operation. Refresh and revoke do not read the header, and
token exchange validates a supplied value without persisting it in either
returned token.
Errors and inaccessible scope
A malformed header value is rejected with the current public 400 error
envelope. Current verification records 404 for a nonexistent or inaccessible
Sub-account and 409 when it is inactive; inspect the current operation
response and correct the selected scope rather than retrying unchanged.
See Authentication Errors and Validation Errors for general error handling.
Consistency across multi-step workflows
Keep Order, Shipment, Rate, and Label identifiers separate. For each step — create/list/read an Order, request Rates, buy a Label, then download or cancel it — consult the matrix and apply the header only where its row gives it an effect. A scope used for an Order does not make a later Label operation scoped automatically.
Security and production guidance
- Treat Sub-account identifiers as sensitive application identifiers.
- Do not log tokens or secrets.
- Validate application-side scope selection and apply least privilege in your application.
- Keep scope explicit in internal logs or audit context; do not cache one user's selected Sub-account globally.
- Derive behavior per operation from this matrix and the API Reference.
Next steps
- Account and Sub-account Scope
- Authentication
- Order-to-Label Workflow
- Get Shipping Rates
- Buy a Label
- Download a Label
- Cancel a Label
- API Reference
- API Playground guide — select a Sub-account in the browser tool and observe the carrier-availability effect on Rates and Label purchase against a configured Sandbox.