API refusals
Goal: Read a refusal from
/ox-apiand know what to change.
The plain 401
A call refused before the workspace knows who is calling gets one answer, whatever the reason:
{ "Message": "This request could not be authorized." }
It is the same on purpose, so a caller cannot learn the workspace's mode or whether a workspace exists. The reason is written only to OpenX's own service log, as one of the codes below. No window shows that log today, so start with the list below.
A plain 401: check these in order
- The token is in the
Authorization: Bearer <token>header, and not in the URL. - The token has not expired. Make a new key, or sign in again.
- The workspace's mode takes this kind of token: a team key or sign-in in Team or Hybrid, a token from an App Identity in Hybrid or App Identity (Secure your workspace API).
- With a token from an App Identity,
x-oi-workspaceis sent and holds your workspace id, the ID shown in Workspace -> Settings. - That App Identity is ticked under Trusted App Identities, and is ready for app calls.
- A person's token is an access token, asked for with the scope the API Manager shows, through the directory's own sign-in app or a sign-in app registered under Sign-in apps in App Identity.
- A job is set up in App Identity with its own client id.
- Until the access rules are saved, a person holds an access card in this workspace that grants at least one right. Once rules are saved, a person needs no card to get past this point; the rules decide the rest (Who may call, for App Identity callers).
- At a hosted workbench address, and on the job token swap, the caller holds an access card in this workspace. A person's card grants at least one right.
The codes behind each step are below.
Reasons at the front door
| Log code | What went wrong | What to do |
|---|---|---|
TOKEN_MISSING | No Authorization: Bearer <token> header | Send the token in that header |
TOKEN_IN_QUERY | A token in the URL, as an Authorization query key in any casing | Send it in the header, never the URL |
TOKEN_MALFORMED | The bearer is not a readable signed token | Send the token itself |
TOKEN_ALG_REFUSED | The token is signed in a way the door does not route | Use an OpenX key or token, or a token from a trusted App Identity |
TOKEN_INVALID | An OpenX token did not verify, for example it has expired | Make a new one |
TEAM_FOREIGN_CLAIM | A token of another kind was sent as a team token | Send the token the call is meant for |
TEAM_CLAIMS_MISSING | The token names no user or no workspace | Make a new key in the workspace |
WORKSPACE_MISMATCH | x-oi-workspace names a workspace other than the token's | Send the token's own workspace, or leave the header out for a team key |
WORKSPACE_REQUIRED | A token from an App Identity came without x-oi-workspace | Add x-oi-workspace: <your workspace id> |
JOB_CLAIMS_MISSING | A swapped job token names no workspace | Swap the job's directory token again |
SWAP_ARM_REFUSED | /ox-api/auth/token was sent something other than a job's own directory token | Send the job's directory token |
Reasons at the API
| Log code | What went wrong | What to do |
|---|---|---|
OXAPI_MODE_REFUSED | The workspace's mode does not take this caller: an App Identity token in Team, or a team key or sign-in in App Identity | Change the mode in Secure your workspace API, or use the other kind of token |
TOKEN_ISSUER_UNKNOWN | The token is not from an App Identity this workspace trusts | Tick a ready App Identity under Trusted App Identities |
OXAPI_NO_ACCESS_UNTIL_RULES_SET | No access rules are saved yet, and the person holds no right in this workspace | Give them an access card that grants at least one right, or save the access rules |
OXAPI_CALLER_UNGRANTED | At a hosted workbench address or the job token swap: the person holds no right here, or the job holds no access card | Give them an access card; a person's must grant at least one right |
OXAPI_JOB_NOT_ADMITTED | An app-only token that is not a live job of this workspace, a job on the directory's own sign-in client, or a person whose name starts app: | Set the job up in App Identity, with its own client id |
OXAPI_RIGHTS_UNREADABLE | The workspace could not be read before the token was checked (once the caller is known, the same code is a 503 below) | Try again shortly |
OXAPI_TOKEN_IN_QUERY | A token in the URL | Send it in the header |
OXAPI_SWAP_NOT_A_SWAP_CALL | A swap was tried on a route other than POST /ox-api/auth/token | Call that route |
OXAPI_SWAP_TOKEN_REUSED | A swapped token was sent to be swapped again | Swap the job's directory token instead |
OXAPI_SWAP_TOKEN_SPENT | The directory token has less than a second left | Get a fresh directory token |
OXAPI_SWAP_BEARER_REFUSED | A swapped token was sent somewhere other than /ox-api | Call through /ox-api |
| API key reasons | API_KEY_TOKEN_INVALID, API_KEY_AUDIENCE_MISMATCH, API_KEY_SUBJECT_MISSING, API_KEY_CLAIMED_RIGHTS, API_KEY_DELEGATED, API_KEY_UNKNOWN, API_KEY_REVOKED | Make a new key; a revoked or unknown key is refused on its next call |
A team key calling outside its own rights is not refused. The call is logged, and goes through.
A token from an App Identity is checked by the directory rules, and a failure there is logged with its own code,
such as TOKEN_EXPIRED ("The token has expired. Sign in again or request a new token."),
TOKEN_AUDIENCE_MISMATCH, TOKEN_CLIENT_MISMATCH, TOKEN_SIGNATURE_INVALID, TOKEN_NOT_ACCESS_TOKEN or
TRUST_NOT_PREPARED ("This directory has not been prepared for app calls. Open App Identity and choose Configure
for app calls.").
Refused by the access rules
Once the API knows an App Identity caller, the API Manager's access rules decide each endpoint it lists (Who may call, for App Identity callers). The rights an endpoint asks for in its own code are not checked. A refusal here is a 403 with its code, so your app can act on it.
| Code | What the caller sees | What to do |
|---|---|---|
OXAPI_ENDPOINT_CLOSED | "This workspace's API is closed to your App Identity." | The whole API is Closed. Ask a manager to open it |
OXAPI_ENDPOINT_CLOSED | "This endpoint's tab is closed to your App Identity in this workspace." | The endpoint's tab is Closed |
OXAPI_ENDPOINT_CLOSED | "This endpoint is closed to your App Identity in this workspace." | The endpoint is Closed |
OXAPI_ENDPOINT_CLOSED | "Your App Identity has no API access rules in this workspace yet, so it cannot call this endpoint." | With a rule set per App Identity, this one has none yet. Ask a manager to set its rules |
OXAPI_REQUIRED_RIGHTS_MISSING | "You need every one of the access rights in MissingRights to call this endpoint in this workspace." with MissingRights | An All of these rule failed. MissingRights lists the rights you lack. Ask for an access card with them |
OXAPI_REQUIRED_RIGHTS_MISSING | "You need at least one of the access rights in MissingRights to call this endpoint in this workspace." with MissingRights | An Any of these rule failed. MissingRights lists all of that rule's rights; one is enough |
Who can give access cards is the workspace owner, or someone with Workspace.Access.Manage. Who can change the
rules is the owner, or someone with Workspace.API.Manage.
Other named answers
These come back with their code too.
| Status | Code | What the caller sees | What to do |
|---|---|---|---|
| 403 | OXAPI_REQUIRED_RIGHTS_MISSING | "You do not hold every access right this route requires in this workspace." with no MissingRights | The route is not in this workspace's API. Use a route listed in the API Manager |
| 403 | OXAPI_API_MANAGE_REQUIRED | "You do not hold every access right this route requires in this workspace." with MissingRights naming Workspace.API.Manage | In App Identity mode, OpenX's own window reaches the API only for the owner or someone with Workspace.API.Manage |
| 403 | OX_DOOR_ROUTE_NOT_SERVED | "This route is not available to directory callers." | Use a route listed in the API Manager |
| 403 | OX_LIVE_STREAM_DIRECTORY_REFUSED | "The live stream is not available to directory sign-ins yet." | Use a team key for the live stream |
| 403 | OXAPI_SCOPE_REFUSED | "A call through ox-api can only act inside this workspace, and this request is outside what your access here allows." | An App Identity caller cannot list workspaces or create one, and reads the whole workspace record only with Workspace.Access.Manage; use the /ox-api routes |
| 503 | OXAPI_RIGHTS_UNREADABLE | "Your access in this workspace could not be read right now. Try again shortly." | Try again shortly |
| 503 | ACCESS_RIGHTS_UNREADABLE | "Your access rights could not be read right now, so nothing was done." | Try again shortly |
| 503 | API_KEY_STATUS_UNREADABLE | "Your API key could not be checked right now, so nothing was done." | Try again shortly |
| 503 | WORKSPACE_EAC_UNAVAILABLE | "This workspace could not be loaded, so the request cannot be answered." | Try again; check the caller is entitled to this workspace |
| 502 | a DOOR_TOKEN_... code | "The workspace store refused this write, so nothing was saved." | Try again; check the caller's rights |
| 500 | none | "API root not configured." | The workspace host is missing its API address; tell whoever runs it |
Hosted workbenches
A call to /ox-api/w/<workspace id>/workbenches/<apiSlug>/<mode> follows the workspace's mode. A token the door cannot read gets
the plain 401, and so does a token the workspace's mode does not take: an App Identity token on a Team
workspace, or a team key on an App Identity workspace. The API's own check turns those away first. Past it, a
missing mode, a mode that does not take this caller, or a workbench that cannot answer gets:
| Status | Code / message | What to do |
|---|---|---|
| 403 | WORKBENCH_APP_MODE_OFF | A second check a caller normally never sees: an App Identity caller on a Team workspace. Switch to Hybrid or App Identity |
| 403 | WORKBENCH_TEAM_MODE_OFF | A second check a caller normally never sees: a team key on an App Identity workspace. Use an App Identity token |
| 403 | WORKBENCH_PROVIDER_NOT_HONOURED | The mode lists the App Identities it takes, and the caller's is not one. Use one it lists, or add it to the mode |
| 401 | AUTHORIZATION_REQUIRED | Send a token |
| 404 | "Mode '...' not enabled for workbench '...'." | Turn the mode on in the workbench |
| 503 | "Workbench '...' mode '...' is not deployed yet." | Deploy, then try again |
| 404 | "Workbench '...' mode '...' has no HTTP endpoint; it runs without ingress." | That mode takes no calls |
| 404 | "Workbench not found." | Check the workbench's APISlug |
The three 403s and the 401 above carry their code with "This workbench mode does not admit this caller."
The job token swap
Every refusal of POST /ox-api/auth/token is the plain 401; the log codes are SWAP_ARM_REFUSED,
OXAPI_MODE_REFUSED, TOKEN_ISSUER_UNKNOWN, OXAPI_JOB_NOT_ADMITTED, OXAPI_CALLER_UNGRANTED,
OXAPI_SWAP_TOKEN_REUSED, OXAPI_SWAP_TOKEN_SPENT and the directory checks above. The access rules do not
decide the swap. A swapped token that has been tampered with, or that names another workspace, is refused
the same way.
Saving the access settings
Save access settings and Save the access rules in the API Manager can be refused. The window shows the server's sentence, followed by the field names when there are some.
| Status | Code | Message |
|---|---|---|
| 400 | none | "The OX API settings are invalid. Fix the fields listed, then save again." with the field names |
| 400 | ENDPOINT_ACCESS_RULE_EMPTY | The same sentence. A rule names no access right. To ask for none, leave the level Open with no right picked |
| 400 | ENDPOINT_ACCESS_OVERRIDE_AT_API | The same sentence. The whole API has nothing above it, so it cannot replace the settings above |
| 400 | ENDPOINT_ACCESS_RIGHT_UNKNOWN | "'...' is not one of this workspace's access rights. Pick a right the workspace defines." |
| 400 | ENDPOINT_ACCESS_GROUP_UNKNOWN | "'...' is not a tab of this workspace's API. Clear it, or pick a tab the API lists." |
| 400 | ENDPOINT_ACCESS_ENDPOINT_UNKNOWN | "'...' is not an endpoint of this workspace's API. Clear it, or pick an endpoint the API lists." |
| 400 | ENDPOINT_ACCESS_IDENTITY_UNKNOWN | "'...' is not a trusted App Identity of this workspace. Trust it first, or clear its rules." |
| 400 | PROVIDER_LOOKUP_INVALID | "Provider lookup must be lowercase letters, numbers and single hyphens between them, like contoso-b2c. It cannot start or end with a hyphen, or contain two in a row." |
| 400 | CLIENT_ID_SHARED | "A client id sits in at most one connected app per App Identity, of any kind and even when revoked. Give each app its own client id." |
| 400 | OWN_CLIENT_REFUSED | "That is the App Identity's own sign-in client. A job needs its own client id." |
| 400 | TRUST_NOT_PREPARED | "App and Hybrid modes need at least one trusted App Identity that is enabled, not revoked and ready for ox-api calls (it has a user scope). Prepare one, then save again." |
| 403 | OXAPI_CHANGE_NOT_ALLOWED | "Only the workspace owner or someone with the 'Workspace.API.Manage' right can change how ox-api is secured." |
The window hides Manage from anyone who cannot change these settings, so the last one is rare. Save the access rules with nothing changed is not sent; the window says "Nothing has changed."
Next steps
- Send the right token -> Call the API from your app
- Change who may call -> Secure your workspace API