Errors
Partner API failures contain success: false, a machine-readable error, a human-readable detail and meta.requestId. Validation failures can add fields; rate limits add retryAfter and a Retry-After header. OAuth token endpoints use a separate format with error and error_description.
Trading and Management calls keep their own response contracts. In particular, delegated Trading errors do not consistently include meta.requestId; retain operationId and X-Operation-Id when present. See the Trading reference and Management errors for endpoint-specific failures.
Response shapes
A validation failure can identify invalid fields with a path and a code:
{
"success": false,
"error": "validation_failed",
"detail": "One or more fields are invalid.",
"fields": [
{
"path": "external_id",
"code": "invalid"
},
{
"path": "authorization",
"code": "object_required"
}
],
"meta": {
"requestId": "preq_1f2e3d4c5b6a7980"
}
}
Field codes include invalid, object_required, out_of_range, not_enabled_for_partner, not_registered, outside_member_scope and schema-validation codes such as missing or extra_forbidden. This is not a closed list. path identifies the field, query parameter or header. Some failures have only detail.
A rate limit carries the wait in the body and in a header:
HTTP/1.1 429 Too Many Requests
Retry-After: 7
X-Request-Id: preq_9e8d7c6b5a4f3e21
Cache-Control: no-store
{
"success": false,
"error": "rate_limited",
"detail": "Too many requests. Retry after the indicated delay.",
"retryAfter": 7,
"meta": {
"requestId": "preq_9e8d7c6b5a4f3e21"
}
}
A bearer failure adds the RFC 6750 challenge, which names the resource and its metadata document (RFC 9728):
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="crosstrade", resource="https://app.crosstrade.io/v1/api/partner", resource_metadata="https://app.crosstrade.io/.well-known/oauth-protected-resource/v1/api/partner", error="invalid_token", error_description="Missing, expired or invalid access token."
{
"success": false,
"error": "unauthorized",
"detail": "Missing, expired or invalid access token.",
"meta": {
"requestId": "preq_2a3b4c5d6e7f8091"
}
}
The OAuth token endpoint answers in the RFC 6749 shape, with Cache-Control: no-store, and a 401 adds WWW-Authenticate: Basic realm="crosstrade":
{
"error": "invalid_client",
"error_description": "client authentication method mismatch"
}
For the Partner control plane, a refused bearer uses unauthorized in the JSON body and invalid_token in the challenge. Use error for program logic and detail for diagnosis. Include the request id when contacting CrossTrade support; do not log bearer tokens, client secrets, Connect links or authorization codes.
Common API failures
| Status | Code | Meaning |
|---|---|---|
| 400 | validation_failed | A field, header or query parameter is invalid; see fields |
| 413 / 415 | validation_failed | Body exceeds 64 KiB, or its content type, encoding or character set is unsupported |
| 401 | unauthorized / invalid_token | Bearer missing, expired, revoked or for another resource |
| 403 | insufficient_scope | The token lacks the required scope |
| 403 | partner_not_enabled | Your partner is not enabled for the API yet |
| 403 | partner_not_active / partner_past_due / partner_suspended / partner_disabled | Your service state blocks this operation |
| 403 | environment_not_allowed | That trading environment is not enabled for your partner |
| 403 | identity_not_consented | The account belongs to an identity the member did not share |
| 403 | operation_not_delegated | This operation is never available to connected applications |
| 403 | plan_not_entitled | The member's funded plan does not include the requested API feature |
| 404 | member_not_found / account_not_found / not_found | No such member, account or operation |
| 409 | external_id_conflict | The external id already belongs to a member with different details |
| 409 | email_in_use | The email already has a CrossTrade account of its own; enroll the member with a different address |
| 409 | email_ambiguous | More than one existing account matches the email; contact support |
| 409 | partner_tag_required | Set your business name in the Partner Platform dashboard before creating members or links |
| 409 | existing_account_ineligible | A released account cannot be reopened, for example because it now has its own paid plan |
| 409 | conflict | The member's state does not allow this action, such as reopening an active seat |
| 409 | grant_required | A relink needs an existing active grant; use a new authorization flow |
| 409 | account_ambiguous | Two accounts share the name; use the account id |
| 409 | idempotency_conflict / idempotency_in_progress / idempotency_key_expired | Idempotency-Key reuse rules |
| 409 / 503 | outcome_unknown | Trading dispatch may be uncertain (409), or a database result could not be confirmed (503). Follow detail and any statusUrl; retain the original key |
| 409 | resource_not_delegated | The resource is not managed by your application |
| 409 | resource_in_use | A monitor has dependencies your app cannot remove |
| 409 | automation_limit_reached | Your app reached the member's monitor/copier limit |
| 409 | seat_cap_reached | Your seat limit is reached |
| 410 | cursor_expired / flow_closed / ticket_invalid | The cursor, flow or link is no longer usable |
| 412 / 428 | precondition_failed | If-Match stale or missing on reopen |
| 429 | rate_limited / too_many_concurrent_requests | Partner or lane budget exceeded; honor Retry-After |
| 502 / 503 | broker_unavailable | Tradovate could not be reached; retry the read after a delay |
| 503 | partner_api_unavailable / policy_unavailable / auth_unavailable / storage_unavailable / terms_unavailable | Service or dependency unavailable; retry with backoff |
| 503 | secrets_unavailable / partner_config_invalid | Configuration needs attention; contact support if it persists |
| 500 | internal_error | Contact support with the request id |
Choosing a recovery action
For 401, first check that you selected the correct token type and API audience. Renew an expired partner token with client credentials, or refresh the affected member's token. Refresh cannot add missing audiences or permissions; changed consent requires a new Connect flow.
For 429, wait at least Retry-After seconds. Partner budgets are shared, so requesting more tokens does not increase capacity. Retry an idempotent mutation with the same key and unchanged request.
For a Trading 409 outcome_unknown, inspect the operation status, orders and positions before taking further action. Do not create a fresh key to resend a possibly executed command. OAuth errors and refresh recovery are covered in Partner Authentication.