API error codes
Every error response from the Motionworks API uses the same JSON
envelope and carries a docs_url pointing at the section
below that describes the specific error.code. The
X-Request-Id response header always matches the
request_id field in the body — include it when filing
support tickets.
This page documents the auth-related error codes shipped with the v2 API-key flow. See the API reference for the canonical list of stable codes and the authentication & quotas page for the access-tier model.
AMBIGUOUS_AUTH
HTTP 400 Bad Request
Returned when a single request includes both an
X-API-Key header and an Authorization: Bearer
header. The router rejects rather than picking one silently, because
the two auth modes carry different identities and billing contexts.
Example response
{
"error": {
"code": "AMBIGUOUS_AUTH",
"message": "Use either X-API-Key or Authorization: Bearer, not both.",
"status": 400,
"request_id": "req_abc123def456",
"docs_url": "https://mworks.com/developers/docs#ambiguous-auth",
"context": {
"present_headers": ["X-API-Key", "Authorization"],
"choose_one": ["X-API-Key", "Authorization: Bearer <jwt>"]
}
}
} Reproduce
curl -i https://api2.mworks.com/v2/markets \
-H "X-API-Key: $MW_API_KEY" \
-H "Authorization: Bearer $MW_JWT" Remediation
Pick the auth mode appropriate to your call and remove the other header:
-
X-API-Key— server-to-server data calls against product endpoints (Popcast, Placecast, Pathcast, Viewcast, platform). Recommended for backend integrations. -
Authorization: Bearer <jwt>— account-management endpoints under/v2/account/*and/v2/billing/*. Used by the in-app portal flow at app2.mworks.com.
Related
SCOPE_NOT_SUPPORTED
HTTP 400 Bad Request
Returned when an API key's scope attribute is anything
other than 'read'. The v2 MVP only supports read scope;
this gate is the no-op precursor to future scope enforcement (write,
admin) and rejects unknown scopes loudly rather than silently treating
them as read.
Example response
{
"error": {
"code": "SCOPE_NOT_SUPPORTED",
"message": "API key scope is not supported.",
"status": 400,
"request_id": "req_def456abc789",
"docs_url": "https://mworks.com/developers/docs#scope-not-supported",
"context": {
"scope": "write",
"supported": ["read"]
}
}
} Reproduce
The error surfaces when a key minted with a non-read scope is used against any v2 endpoint:
curl -i https://api2.mworks.com/v2/markets \
-H "X-API-Key: mwk_live_write_..." Remediation
Mint a new key with scope: 'read' from the portal at
app2.mworks.com and replace the
offending key in your client configuration. There is no way to "upgrade"
an existing key's scope — keys are immutable. Future MVP releases will
add write and admin scopes; this page will be updated then.
Related
ORIGIN_NOT_ALLOWED
HTTP 403 Forbidden
Returned when an API key has a non-null allowed_origins
list configured and the request's Origin header doesn't
satisfy the per-key allowlist policy. See ADR-25 in
api-mworks-com for the full policy definition.
Example response
{
"error": {
"code": "ORIGIN_NOT_ALLOWED",
"message": "Request Origin is not permitted for this API key.",
"status": 403,
"request_id": "req_789xyz012abc",
"docs_url": "https://mworks.com/developers/docs#origin-not-allowed",
"context": {
"reason": "origin_not_allowed",
"origin": "https://other.example"
}
}
} Reason codes
The context.reason field disambiguates the three rejection paths:
| Reason | Condition |
|---|---|
origin_required | The key has a non-empty allowed_origins list, but the request arrived without an Origin header (typical for server-to-server callers). |
origin_not_allowed | The request's Origin header was present but didn't match any entry in the key's allowlist. |
origin_disabled | The key's allowed_origins is set to an empty array ([]) — browser use is explicitly disabled for this key. |
Reproduce
curl -i https://api2.mworks.com/v2/markets \
-H "X-API-Key: $MW_API_KEY" \
-H "Origin: https://other.example" Remediation
- Server-to-server caller hitting
origin_required— mint a separate key withallowed_origins = NULL(the default) for backend use, or remove the allowlist from the existing key in the portal. - Browser caller hitting
origin_not_allowed— add your deployed origin (exact match, scheme + host + port) to the key'sallowed_originslist at app2.mworks.com. - Browser caller hitting
origin_disabled— the key is server-to-server only. Either mint a new key with a non-empty allowlist or route the call through your backend.