Skip to main content

Auth — Mailhub API Reference

Exchange a Mailhub API key for a short-lived access token and a longer-lived refresh token, then use the access token as a Bearer credential on every other request. Refreshing is a true rotation (the spent refresh token is invalidated); revoking is idempotent. The optional `X-SubAccount-Id` header is validated at token exchange but is not persisted in either token, so it changes nothing about the session — see each operation's own header description for that operation's exact effect. Never log an access token, refresh token, or API key in application logs, error trackers, or support tickets.

Operations

POST /api/v1/auth/token

Create access token

Authenticates the client with an API key

Authentication: none — this operation does not require a bearer credential.

Parameters

NameInTypeRequiredDescription
X-SubAccount-Idheaderstring (uuid)optionalOptional. Validates that the given sub-account exists and is active for your account (404/409 if not), but the result is not persisted — it is never embedded in the returned access token, the refresh token, or the response, and has no effect on any later request.

Example: 3a7d9e21-6b48-4c15-9f2e-7d0c5b83a614

Request body (required)

application/json — CreateAccessTokenRequest

{
  "apiKey": "<your-mailhub-api-key>"
}

Responses

StatusDescriptionBody
200Authenticated successfully

application/json — CreateAccessTokenResponseEnvelope

400Invalid request data

application/json — ErrorEnvelope

401Invalid API key or token

application/json — ErrorEnvelope

404Sub-account not found

application/json — ErrorEnvelope

409Sub-account inactive

application/json — ErrorEnvelope

415The request was sent with a `Content-Type` other than `application/json`. Answered by middleware ahead of authentication, so it is reachable on every write operation.

application/json — ErrorEnvelope

422Validation errors

application/json — ErrorEnvelope

500The request could not be completed because of an unexpected server-side failure.

application/json — ErrorEnvelope

POST /api/v1/auth/token/refresh

Refresh access token

Refreshes the access token using a refresh token

Authentication: none — this operation does not require a bearer credential.

Parameters

NameInTypeRequiredDescription
X-SubAccount-Idheaderstring (uuid)optionalNot read by this operation. A malformed value still fails with 400 (checked globally, ahead of routing); a well-formed value has no effect — refresh never reads or persists a sub-account scope.

Example: 3a7d9e21-6b48-4c15-9f2e-7d0c5b83a614

Request body (required)

application/json — RefreshAccessTokenRequest

{
  "refreshToken": "<your-refresh-token>"
}

Responses

StatusDescriptionBody
200Token refreshed successfully

application/json — RefreshAccessTokenResponseEnvelope

400Invalid request data

application/json — ErrorEnvelope

401Invalid or expired refresh token

application/json — ErrorEnvelope

415The request was sent with a `Content-Type` other than `application/json`. Answered by middleware ahead of authentication, so it is reachable on every write operation.

application/json — ErrorEnvelope

422Validation errors

application/json — ErrorEnvelope

500The request could not be completed because of an unexpected server-side failure.

application/json — ErrorEnvelope

POST /api/v1/auth/token/revoke

Revoke refresh token

Revokes the refresh token

Authentication: none — this operation does not require a bearer credential.

Parameters

NameInTypeRequiredDescription
X-SubAccount-Idheaderstring (uuid)optionalNot read by this operation. A malformed value still fails with 400 (checked globally, ahead of routing); a well-formed value has no effect — revoke never reads or persists a sub-account scope.

Example: 3a7d9e21-6b48-4c15-9f2e-7d0c5b83a614

Request body (required)

application/json — RevokeRefreshTokenRequest

{
  "refreshToken": "<your-refresh-token>"
}

Responses

StatusDescriptionBody
200Logout completed successfully

application/json — RevokeRefreshTokenResponseEnvelope

400Invalid request data

application/json — ErrorEnvelope

401Invalid refresh token

application/json — ErrorEnvelope

415The request was sent with a `Content-Type` other than `application/json`. Answered by middleware ahead of authentication, so it is reachable on every write operation.

application/json — ErrorEnvelope

422Validation errors

application/json — ErrorEnvelope

500The request could not be completed because of an unexpected server-side failure.

application/json — ErrorEnvelope

Schemas

The public schemas the operations above reference. Each is listed once; a type name in the tables above links to its fields here.

ApiError

One thing that went wrong.

FieldTypeRequiredDescription
codestringrequiredMachine-readable error identifier, dotted and stable — for example Order.NotFound. Branch on this rather than on message.
messagestringrequiredReadable explanation of the failure. Wording may change; do not parse it.
metaDataobject nullableoptionalExtra detail about this particular failure. Its shape depends on code.

CreateAccessTokenRequest

Exchanges an API key for an access token.

FieldTypeRequiredDescription
apiKeystringrequiredThe API key issued to your Mailhub account. It is exchanged here for a short-lived access token and is not accepted as credentials on any other operation.

CreateAccessTokenResponse

A freshly issued token pair and the account and key it belongs to.

FieldTypeRequiredDescription
accessTokenstringrequiredBearer token to send as the Authorization: Bearer <token> header on subsequent calls.
accessTokenExpiresAtUtcstring (date-time)requiredUTC instant after which the access token is no longer accepted.

Format: date-time

accountIdstring (guid)requiredIdentifier of the Mailhub account the API key belongs to. Orders, shipments and labels created with the issued token are scoped to this account.

Format: guid

apiKeyIdstring (guid)requiredIdentifier of the API key the token was issued from. Distinguishes which of an account's keys produced this token when several are in use.

Format: guid

refreshTokenstringrequiredToken that buys a new access token without re-sending the API key. Send it to the token refresh operation.
refreshTokenExpiresAtUtcstring (date-time)requiredUTC instant after which the refresh token can no longer be exchanged and a new API-key exchange is needed.

Format: date-time

CreateAccessTokenResponseEnvelope

The envelope every JSON operation answers with: a success flag and either a result or errors.

FieldTypeRequiredDescription
dataCreateAccessTokenResponse nullablerequiredThe operation's result. Absent when the call failed.
errorsApiError[] nullablerequiredWhat went wrong. Absent when the call succeeded.
successbooleanrequiredWhether the operation succeeded. When false, read errors.

ErrorEnvelope

The envelope every JSON operation answers with: a success flag and either a result or errors.

FieldTypeRequiredDescription
dataobject nullablerequiredThe operation's result. Absent when the call failed.
errorsApiError[]requiredWhat went wrong. Absent when the call succeeded.
successbooleanrequiredWhether the operation succeeded. When false, read errors.

RefreshAccessTokenRequest

Exchanges a refresh token for a new token pair.

FieldTypeRequiredDescription
refreshTokenstringrequiredThe refresh token returned by a previous token or refresh call.

RefreshAccessTokenResponse

A replacement token pair. The refresh token sent in the request is consumed.

FieldTypeRequiredDescription
accessTokenstringrequiredReplacement bearer token to send as the Authorization: Bearer <token> header.
accessTokenExpiresAtUtcstring (date-time)requiredUTC instant after which the access token is no longer accepted.

Format: date-time

accountIdstring (guid)requiredIdentifier of the Mailhub account the API key belongs to. Orders, shipments and labels created with the issued token are scoped to this account.

Format: guid

apiKeyIdstring (guid)requiredIdentifier of the API key the token was issued from. Distinguishes which of an account's keys produced this token when several are in use.

Format: guid

refreshTokenstringrequiredReplacement refresh token. Use this one for the next refresh — the token sent in the request is consumed.
refreshTokenExpiresAtUtcstring (date-time)requiredUTC instant after which the refresh token can no longer be exchanged and a new API-key exchange is needed.

Format: date-time

RefreshAccessTokenResponseEnvelope

The envelope every JSON operation answers with: a success flag and either a result or errors.

FieldTypeRequiredDescription
dataRefreshAccessTokenResponse nullablerequiredThe operation's result. Absent when the call failed.
errorsApiError[] nullablerequiredWhat went wrong. Absent when the call succeeded.
successbooleanrequiredWhether the operation succeeded. When false, read errors.

RevokeRefreshTokenRequest

Revokes a refresh token.

FieldTypeRequiredDescription
refreshTokenstringrequiredThe refresh token to revoke. Revoking stops any further refresh; an access token already issued from it stays usable until its own expiry.

RevokeRefreshTokenResponse

The outcome of revoking a refresh token.

FieldTypeRequiredDescription
isSuccessbooleanrequiredWhether the refresh token was revoked.

RevokeRefreshTokenResponseEnvelope

The envelope every JSON operation answers with: a success flag and either a result or errors.

FieldTypeRequiredDescription
dataRevokeRefreshTokenResponse nullablerequiredThe operation's result. Absent when the call failed.
errorsApiError[] nullablerequiredWhat went wrong. Absent when the call succeeded.
successbooleanrequiredWhether the operation succeeded. When false, read errors.