ReferenceGenerated

Error codes

Every stable error code the API can return, and what each one means.

When a request fails, the response body carries a stable machine-readable code alongside the human-readable message:

{
  "error": {
    "error": "App database is not provisioned yet",
    "code": "APP_NOT_PROVISIONED",
    "details": { "appUid": "..." }
  }
}

Branch on error.code, never on error.error. The code is the contract and will not change; the message is prose and may be reworded at any time. details carries whatever context is useful for that specific failure.

The Status column is the HTTP status the code is actually thrown with, verified against the real throw sites by a test in the backend suite rather than maintained by hand.

Not every failure carries a code. A generic policy denial returns 403 with code: null, so treat error.code as present-or-absent rather than assuming one is always there.

There are 179 codes.

App lifecycle

CodeStatusMeaning
APP_NOT_PROVISIONED409The target app has no provisioned database yet. Provision the app before calling its API.
APP_NOT_FOUND404No such app within your organization. Returned identically for an app that does not exist and one owned by another organization.

AutoCRUD write failures

CodeStatusMeaning
CREATE_REQUIRED_FIELD_MISSING400A column the table requires was absent from the request body.
CREATE_DUPLICATE409The row violates a unique constraint on the table.

The row edge (helpers/rowEdge.js)

CodeStatusMeaning
ROW_FIELD_NOT_ACCEPTED400A field the data API does not take: a row's internal id, its uid (minted by the platform), a scope or actor column, or a raw foreign-key column. The message names the field to use instead.
ROW_REFERENCE_NOT_FOUND400A <column>_uid reference names no row in the table it points at. The message names the column.
ROW_EDGE_COLLISION409The table cannot be served: a foreign-key column's uid name (<column>_uid) is also the name of a real column. Rename one of them.
ROW_ORG_REQUIRED400The table's rows belong to an organization: name the app organization a new row belongs to (orgUid in the console and agent tools, the row's org_uid in a handler acting for the app's owner). An app with no organizations yet cannot take rows in such a table.
ROW_ORG_NOT_FOUND400orgUid (or a row's org_uid) names no organization in the target app that the caller reaches.
PAGE_CURSOR_INVALID400A page read with after was given a cursor this API did not issue for that table (changed, from another table, or sealed under a retired secret), or a sort or offset, which keyset paging does not take.
PAGE_CURSOR_UNAVAILABLE500The server has no secret to seal page cursors with (ACCESS_TOKEN_SECRET is not set).
AGENT_ORG_UNRESOLVED403The agent belongs to no organization of the app it is acting on, and is not the app owner's.
APP_ORG_UNBOUND500Platform code tried to reach an app's data without saying which app organization it acts in.
ORG_REACH_OWNER_ONLY403Only the app's owner, in the console, can change what its agents, jobs and keys may reach.
ORG_REACH_NOT_APPLICABLE409This agent, job or key belongs to one of the app's organizations and acts only there; org reach is for the owner's own.
STORAGE_SHARED_READ_ONLY403This was shared with you by the app's owner: you can open and download it, and add your own files beside it, but not change it or add folders inside it.
STORAGE_SHARING_OWNER_ONLY403Only the app's owner decides what its folders and files are shared with.
STORAGE_SHARING_NOT_APPLICABLE409This belongs to one of the app's organizations; sharing is for the owner's own folders and files.
STORAGE_OUT_OF_REACH403That reaches organizations outside the caller's org reach.

Handler resolution (helpers/handlerResolver.js)

CodeStatusMeaning
HANDLER_NOT_FOUND404No live handler in this app has that name.
HANDLER_NAME_AMBIGUOUS409More than one live handler in this app has that name, so none of them runs. Rename or archive one.
HANDLER_KIND_BOUND409An endpoint still runs this handler: unassign it from its endpoint actions before marking it job-only.
HANDLER_TRIGGER_REQUIRED500Platform code dispatched a handler without saying why it runs it. A defect, never a caller's mistake.
HANDLER_PLATFORM_ONLY403This handler runs only for the platform: its scheduled jobs, or the app owner testing it in the console.

Table protection

CodeStatusMeaning
TABLE_LOCKED423The table is locked against this operation by its protection settings.
POLICY_IS_SYSTEM423That policy is seeded platform wiring and cannot be unbound or edited. Bind or unbind your own policy instead.

Custom handlers / execution

CodeStatusMeaning
HANDLER_NOT_IMPLEMENTED501The action is registered on the endpoint but has no handler implementation published.
HANDLER_WORKER_UNAVAILABLE503The isolated handler runtime could not be reached. Transient — retry.
HANDLER_WORKER_BUSY503The isolated handler runtime is at capacity (overall, or for this app). Transient — retry.
HANDLER_GIT_AUTHORED409The handler is authored from a linked repository. Change it there, or turn off require_git_authorship for that repository to edit it in the console.

Billing / plan changes

CodeStatusMeaning
PLAN_CHANGE_BLOCKED409The target plan does not fit the organization's current usage. Raised in EITHER direction: a plan's rank decides how it is billed, not which way each individual limit moved, so an upgrade that tightens one limit is refused too. details.blockers lists every resource that is over, with the usage and the target limit, so the customer can free them all at once instead of being refused repeatedly.
PLAN_CHANGE_ALREADY_SCHEDULED409A plan change is already scheduled for the end of the current period. Cancel it before scheduling another — a second would orphan the first schedule in Stripe.
NO_PENDING_PLAN_CHANGE409There is no scheduled plan change to cancel.
PLAN_PAYMENT_FAILED402The card could not be charged for an upgrade, so the plan was NOT changed — the whole change is rolled back rather than granted unpaid. Update the payment method and retry.

Billing / plan limits

CodeStatusMeaning
SUBSCRIPTION_LIMIT_REACHED402The organization's plan limit for this resource is reached. Upgrade the plan or free capacity.
AI_SPEND_CAP_REACHED402An AI spend limit set by this account has been reached. Raise the limit in settings to continue.
FEATURE_NOT_INCLUDED402The organization's plan does not include this feature. Upgrade the plan to enable it.

Account lifecycle locks

CodeStatusMeaning
ACCOUNT_RESTRICTED423The account is read-only because a payment failed. Reads still work; bring the subscription current to write again. details: { state, reason: 'lifecycle', stateReason }
ACCOUNT_PAUSED423The app is paused — for inactivity (restore it from the console) or for non-payment (bring the subscription current). details.stateReason says which. details: { state, reason: 'lifecycle', stateReason }
APP_WAKING503The app was asleep after a period of no traffic and this request started waking it. Retry after the Retry-After interval. details: { retryAfterSeconds, state, stateReason }
APP_RESTORING503The app is being restored from its archive and cannot serve yet. Retry after the Retry-After interval. details: { appUid, retryAfterSeconds }
ACCOUNT_TORN_DOWN423The app's live data was removed after a long pause. It can still be restored from its archive until the archive expires. details: { state, reason: 'lifecycle', stateReason }

Data placement

CodeStatusMeaning
APP_MIGRATING423The app is being moved to different infrastructure and is briefly read-only. Reads continue; writes resume automatically when the move completes.
PLACEMENT_NOT_ENTITLED403The organization's plan does not include the requested data placement tier.
PLACEMENT_PREFLIGHT_FAILED402The app does not fit the requested placement tier — free capacity or choose a larger tier.
PLACEMENT_MIGRATION_IN_PROGRESS409Another placement move is already running for this app. Only one may run at a time.
PLACEMENT_DESTINATION_UNAVAILABLE409The requested placement tier is not available on this deployment yet (for example, S3 is not configured). A queued move resumes once it is.

Platform configuration

CodeStatusMeaning
EMAIL_NOT_CONFIGURED500This deployment has no email sender configured. An operator must configure one.

Email connections and app email (notes/email-connections-and-branding-plan.md)

CodeStatusMeaning
EMAIL_CONNECTION_INVALID400An email connection's server settings are not usable: a mail host, an SMTP submission port, and starttls or tls.
EMAIL_SENDER_INVALID400A sender is not an address (name@example.com) or a domain (@example.com), or the default sender is not one of the connection's senders.
EMAIL_HOST_BLOCKED400The mail host resolves to a private or reserved address, which the platform never dials.
EMAIL_CONNECTION_FAILED502The mail server could not be reached, refused the login, or failed the secure connection. The message says which.
EMAIL_CONNECTION_NOT_FOUND404No email connection or grant by that uid in this org or app.
EMAIL_CONNECTION_UNVERIFIED409The email connection has not passed a test since it was connected or last edited, so it cannot be granted or used.
EMAIL_ALIAS_IN_USE409That alias already names another email connection in this app. Revoke it first to point it elsewhere.
EMAIL_NOT_GRANTED403The app has no email connection by that name (or no default): its owner grants one under App settings.
EMAIL_FROM_NOT_ALLOWED403The from address is not one of the email connection's senders.
EMAIL_PLACEHOLDER_MISSING400A {key} or {{key}} placeholder in the message names no value in its data, so nothing was sent.
EMAIL_MESSAGE_INVALID400The message is missing what every email needs (a recipient, a subject, some content) or has a malformed address.
EMAIL_SEND_FAILED502The app's mail server did not accept the message. It is logged as failed, with the server's reason.

App branding (notes/email-connections-and-branding-plan.md §5)

CodeStatusMeaning
BRANDING_INVALID400A branding field is not usable: a color that is not #rrggbb, a URL that is not https, an address that is not an email address, or text past its length. The message names the field.
BRANDING_ASSET_NOT_FOUND404No file by that uid among the app owner's own files, so it cannot be the logo or icon.
BRANDING_ASSET_NOT_PUBLIC400The file is in a private storage, so an email cannot show it. Move it to a public storage, or make its storage public.
SMS_NOT_CONFIGURED500This deployment has no SMS sender configured. An operator must configure one.
SMS_CHANNEL_UNSUPPORTED501The configured SMS provider cannot send this kind of message. Switch to the Programmable Messaging adapter.
SMS_SUPPRESSED409That number has opted out of messages from this sender and cannot be texted.
ARBITER_NO_LLM409No AI provider is connected for this organization. Connect one in Integrations.
AI_NO_LLM409No AI provider is connected for this organization. Connect one in Integrations.
AI_MODEL_UNAVAILABLE409The configured AI model is no longer available from this provider. Choose a replacement to resume.
LLM_MODEL_NOT_APPROVED400That AI model is not approved for this provider. Choose one from the model list.
AI_TIER_INVALID400sdk.ai takes a tier ("fast" or "default"), not a model. Set the models on your AI connection.

Sign-up doors (api/notes/staff-members-and-authz-hardening-plan.md §2.1)

CodeStatusMeaning
SIGNUP_ORG_NOT_ALLOWED400Sign-up cannot join an existing organization; accept an invitation to join one.
STAFF_SIGNUP_NOT_ALLOWED403Staff accounts are created by setup or by existing staff, never by a public sign-up.

First-run setup (api/notes/staff-members-and-authz-hardening-plan.md §5)

CodeStatusMeaning
STAFF_SETUP_DONE409Setup has already been completed on this install.
STAFF_SETUP_TOKEN_MISSING403This install has no setup token; run npm run staff:setup on the server.
STAFF_SETUP_TOKEN_INVALID403The setup token is not valid.
STAFF_SETUP_INVALID400Setup needs a valid email and a password of at least 8 characters.
STAFF_EMAIL_TAKEN409A staff member with that email already exists.
STAFF_SETUP_REQUIRED409Setup has not run on this install; there is no staff organization yet.
CodeStatusMeaning
INVITE_TOKEN_INVALID400That invitation link is not valid, has expired, or was already used.
INVITE_EMAIL_MISMATCH403This invitation was sent to a different email address.
INVITE_ACCOUNT_TYPE_MISMATCH403This invitation is for a different kind of account.
INVITE_REQUIRED403Staff accounts are created by invitation only.

Platform access (notes/platform-access-plan.md)

CodeStatusMeaning
FEEDBACK_EMPTY400Write something before sending (up to 5,000 characters).
FEEDBACK_NO_SENDER401Sign in to send feedback.
FEEDBACK_NOT_FOUND404That feedback does not exist, or it was removed.
FEEDBACK_STATE400Feedback is new, read or archived.
FEEDBACK_ATTACHMENT_INVALID400Attach up to 3 images (PNG, JPEG or WebP), up to 5 MB each.
BOT_CHECK_FAILED403Please complete the bot check and try again.
BOT_CHECK_UNAVAILABLE503The bot check could not be completed. Try again in a moment.
SIGNUP_INVITE_ONLY403Authoric is invite-only right now. Request access, or use the sign-up link from your invitation.
PLATFORM_ACCESS_REVOKED403Access to Authoric has been revoked for this account.
PLATFORM_ACCESS_LINK_INVALID400That sign-up link is not valid, has expired, or was already used.
PLATFORM_ACCESS_NOT_FOUND404No such access record.
PLATFORM_ACCESS_STATE409That change does not fit this person's current access.

Scheduled jobs: arming (api/notes/staff-members-and-authz-hardening-plan.md §2.4)

CodeStatusMeaning
CRON_ROLE_OUTSIDE_ORG403A scheduled job can only be given a role your organization owns.
CRON_BUSY409The job is running right now. Try again once its current turn has finished.
JOB_ITEM_TIMEOUT504One item of a scheduled job took longer than the per-item limit (60 seconds), and was skipped.

Roster changes from handler code (sdk.roles)

CodeStatusMeaning
PRINCIPAL_NOT_HUMAN403Only people are given roles from handler code.
ROLE_ORG_MISMATCH403A role is granted inside the caller's own organization.
ROLE_NOT_FOUND404That role does not exist.
MEMBER_NOT_FOUND404That member is not in this organization.
USER_NOT_FOUND404That user does not exist.

App creation (api/notes/staff-members-and-authz-hardening-plan.md §2.3)

CodeStatusMeaning
CREATE_APP_ORG_MISMATCH403An app can only be created in your active organization.
CREATE_APP_TENANT_SELECTOR400tenantId / tenantEmail are not accepted; the app is created for your organization's own account.

Policy scope (api/notes/staff-members-and-authz-hardening-plan.md §2.2)

CodeStatusMeaning
POLICY_ROLE_SCOPE_MISMATCH403An organization's policy can only be bound to that organization's own roles; shared roles take only seeded policies.

Staff (api/notes/staff-members-and-authz-hardening-plan.md)

CodeStatusMeaning
ORG_NOT_ADMITTED403This account cannot be a member of that organization.
STAFF_CAPABILITY_NOT_GRANTABLE403Those actions belong to Authoric staff and can only be granted inside the staff organization.
ORG_NOT_BILLED404This organization is not billed; it has no plan or usage to show.
STAFF_ONLY403This action is for Authoric staff only.
PLATFORM_TARGET_STAFF_ONLY403The platform database is not an app target; name one of your organization's apps as targetAppUid.
ACT_AS_INVALID400That act-as request names something we cannot act on.
ACT_AS_REASON_REQUIRED400Say why you need access to this organization; the reason is recorded and shown to the customer.
ACT_AS_NOT_HUMAN403Only a person can act as an organization.
ACT_AS_STAFF_ORG400The staff organization is not something to act as.
ACT_AS_NOT_A_MEMBERSHIP409You are acting as this organization, not a member of it — switch back to stop.
MEMBER_TOKEN_SELF_ONLY403An approver token can only be minted for your own account.
MEMBER_TOKEN_STAFF_ORG403Approver tokens cannot be minted in the staff organization; staff act through sessions.
AI_MODEL_INVALID400The AI model catalog change is invalid; the message says which field and why.
AI_MODEL_NOT_FOUND404No such model in the AI model catalog.
AI_MODEL_EXISTS409That provider and model id are already in the AI model catalog.
AI_MODEL_IN_USE409The model is still in use. It fills a platform role (reassign the role first), or AI connections chose it and the change needs confirming. details lists what points at it.
AI_MODEL_NOT_VERIFIED409Verify the model before approving it: a verification run proves it works through the platform's adapter.
AI_MODEL_UNPRICED409The model has no price, so its spend would not count toward AI spend caps. Add a price, or confirm running it unpriced.
LLM_CONNECTION_NOT_FOUND404No such AI connection in the active organization.
AI_SOURCE_REDACTED400A derived column cannot read from a redacted column. Remove it from the source list or un-redact it.
AI_DERIVED_COLUMN_INVALID400The derived-column configuration is invalid.
AI_EMBEDDINGS_UNSUPPORTED409The connected AI provider does not offer embeddings. Semantic search needs a provider that does.
APPROVAL_SELF_APPROVAL403The caller raised this approval request and cannot approve it themselves.
HANDLER_RUN_NO_PRINCIPAL409Run live executes as a principal of the app, and a console session is not one. Use the dry run, or call the endpoint as one of the app's users.
APPROVAL_CONSUMED409This approval was already used by another run of the same work. An approval runs its work once.
APPROVAL_ORG_REQUIRED403Approvals belong to an organization, and this caller has no active organization.
STEP_ALREADY_DECIDED409This approval step was already decided by another surface. Refresh to see the current state.
API_KEY_INVALID401The API key is missing, malformed, unknown, revoked, or expired. Returned identically for all five.

SDK-capability governance (notes/handler-sdk-capability-governance.md)

CodeStatusMeaning
SDK_CAP_NOT_GRANTED403You lack an SDK capability the handler's code uses. Request the capability to author it. details: { missing: [{ capability, label, risk, methods }], actor } — the capabilities required but not held.
DDL_NOT_DRY_RUNNABLE422A dry-run tried to execute schema-changing SQL. DDL cannot be rolled back, so it is never dry-runnable.
SDK_CAP_NOT_IN_MANIFEST403The handler called an SDK power absent from the manifest frozen at publish time. Republish to refresh it.
SDK_UNKNOWN_METHOD400The handler called an SDK method that does not exist. Check the spelling against the editor's autocomplete — the contract d.ts is the full surface.
LINK_TOKEN_INVALID404The link is invalid, expired, already used, revoked, or minted for a different purpose. Returned identically for all five.

Agent/arbiter charts (services/charts/chartSpec.js + the chart handlers)

CodeStatusMeaning
CHART_SPEC_INVALID422The chart spec failed structural validation. details: { issues: string[] } — the specific validation failures.
CHART_SNAPSHOT_TOO_LARGE413The chart is well-formed but its frozen data snapshot exceeds the storage/serve cap. details: { maxRows, maxBytes } — the caps that were exceeded.
CHART_NOT_FOUND404No such chart within your scope. Returned identically for a chart that does not exist and one owned by another organization.
CROSS_PLANE_FORBIDDEN403An app-plane caller tried to address another plane. An app may only touch its own database.
GRANT_EXCEEDS_HOLDER403You tried to grant capabilities you do not hold yourself. The response names which ones; ask someone who holds them, or have them granted to you first.
ROLE_PROTECTED400Built-in roles cannot be deleted. Create a custom role instead, or unbind this one from whoever holds it.

Agent run lifecycle (notes/agent-run-lifecycle-and-reliability-plan.md)

CodeStatusMeaning
AGENT_RUN_NOT_FOUND404No such agent run within your scope. Returned identically for a run that does not exist and one belonging to another organization.
AGENT_RUN_CONCURRENCY_LIMIT429The organization already has its maximum number of agent runs in flight. Retry after the interval in the Retry-After header. details: { limit, retryAfterSeconds } — the ceiling and when to retry.
AGENT_RUN_NOT_ACTIVE409That run has finished, so a message can no longer be sent to it. Send it to the conversation instead to start new work.
AGENT_SESSION_BUSY409This conversation already has a run in progress that you did not start. Wait for it to finish, or use a new conversation.
STALE_APPROVAL409The rows this approved step would change have changed since it was approved, so it was not run. Read them again and propose it afresh.
CHANGE_SET_NOT_FOUND404No recorded change with that handle in your runs. It may belong to someone else, or be older than the retention window.

Auth-method expansion (services/auth/*)

CodeStatusMeaning
OAUTH_PROVIDER_UNAVAILABLE400The sign-in provider is unknown or not configured on this deployment.

Sessions and tokens

CodeStatusMeaning
AUTH_TOKEN_EXPIRED401The access token has expired. Exchange the refresh token for a new pair, then retry.
AUTH_TOKEN_INVALID401The access token is not valid. Exchange the refresh token for a new pair, then retry.
SESSION_ENDED401This session has ended. Sign in again. details: { reason: 'expired' | 'revoked' | 'reused' | 'signed_out' | 'invalid' | 'legacy' }
SESSION_IS_CURRENT409This is the session making the request. Use sign-out to end it.

Two-factor authentication

CodeStatusMeaning
MFA_REQUIRED401This account has two-factor authentication enabled. Answer the challenge to finish signing in.
MFA_CODE_INVALID400The submitted two-factor code did not match.
MFA_ALREADY_ENROLLED409A factor of this kind is already set up. Remove it before adding another.
MFA_NOT_ENROLLED400This account has no second factor set up.
MFA_LAST_FACTOR409This is the only method protecting the account, so it cannot be switched off.
MFA_ENROLLMENT_REQUIRED403This organization requires two-factor authentication. Set up a second factor to continue.
ORG_MFA_ENABLE_BLOCKED409Set up your own two-factor authentication before requiring it for the organization.
OAUTH_EMAIL_UNVERIFIED400The provider returned no verified email address, so the account cannot be matched safely.
OAUTH_SIGNUP_DISABLED400No account matches the verified address and sign-up via this provider is disabled.
OAUTH_EXCHANGE_FAILED400The token exchange or profile fetch failed at the provider. Usually transient — retry.
OAUTH_METHOD_DISABLED400This sign-in method is switched off for the account. Use another method or re-enable it in Settings.

Product tours

CodeStatusMeaning
TOUR_NO_SUBJECT401The request carries no signed-in principal, so there is no tour progress to read or record.
TOUR_INVALID_KEY400The tour key must be 1-64 characters of lowercase letters, digits, dot, underscore or hyphen, starting with a letter or digit.
TOUR_INVALID_VERSION400The tour version must be a positive integer.
TOUR_INVALID_STATUS400The tour status must be either completed or dismissed.

Console banners & announcements

CodeStatusMeaning
BANNER_NO_SUBJECT401Console notices are per person; sign in to read or dismiss them.
BANNER_INVALID_KEY400The banner key is not well formed.
BANNER_NOT_FOUND404That banner is not currently being shown to you, so it cannot be dismissed.
BANNER_NOT_DISMISSIBLE409That notice cannot be dismissed; it goes away when the condition it describes is resolved.
ANNOUNCEMENT_NO_ORG400Choose an organization first.
ANNOUNCEMENT_INVALID400The announcement is invalid: check severity, title length, the action link, and the dates.
ANNOUNCEMENT_NOT_FOUND404No announcement has that uid.
TOUR_LIMIT_REACHED409This account has recorded the maximum number of distinct tours; a new one cannot be added.

On this page