Error codes

What each Plexivo API and Plexivo Postgres Data API error code means, its HTTP status, and what to do about it.

When a request fails, the Plexivo API answers with an HTTP status and a stable code your program can act on. This page lists the codes you are most likely to meet: first the Plexivo API that manages your resources, then the Data API, Auth, Realtime and Functions of Plexivo Postgres.

Error format#

json
{
  "error": {
    "code": "validation_failed",
    "message": "one or more fields are invalid",
    "details": { "fields": { "storage_gb": ["can only grow (now 20 GB)"] } }
  }
}
  • code is stable. Build your logic on it.
  • message explains the problem to a person and may change.
  • details carries what you need to fix it, such as the fields that failed, when there is something to say.

Idempotency errors use the application/problem+json format, with code, detail and fix. Every response carries an x-trace-id header; quote it when you contact support.

Sign-in and access#

CodeStatusWhat to do
unauthorized401The token or API key is missing, wrong, revoked or expired. Check the Authorization header, or create a new key.
reauthentication_required401A console session ended. details.reason is idle or absolute. Sign in again.
forbidden403Your role, or the key’s permissions, do not allow this. The message says what was refused; for an API key it names the scope needed.
step_up_required403Confirm your password or authenticator code, then retry.
support_access_required403Someone outside the organisation tried to reveal a secret or data without an approved request. See Support and agency access.
organisation_suspended403The organisation cannot create anything new. Contact support.

Requests#

CodeStatusWhat to do
validation_failed422Fix the fields listed in details.fields and send again.
not_found404The resource does not exist, or you cannot see it.
name_taken409Choose another name.
illegal_transition409The resource is not in a state that allows this. Check its status and retry later.
quote_expired, quote_changed, quote_invalid409Ask for a new estimate and confirm the new price.
price_changed409The price moved since you saw it. Review it and confirm again.
idempotency_key_reused409Use a new Idempotency-Key for a different request.
idempotency_in_flight409The first request with this key is still running. Wait and retry with the same key.
invalid_idempotency_key400Use a key of 256 bytes or fewer.
endpoint_retired410This endpoint is no longer available. The message says what replaced it.

Limits and capacity#

CodeStatusWhat to do
rate_limited429Too many requests. Wait for the Retry-After seconds and retry.
too_many_requests429An API key’s per-minute, concurrent or daily limit was reached. See Limits on every key.
quota_exceeded403Your plan’s limit for this kind of resource is reached. Delete something, or change your plan.
spend_limit_exceeded422The API key’s monthly spend limit would be passed. Raise the limit or use another key.
contact_sales422What you asked for is arranged with sales. Talk to sales.
no_capacity, queued_capacity503There is no room for this in its region right now. Nothing was created or charged. Retry in a few minutes.

Billing#

CodeStatusWhat to do
plan_required402Choose a plan in Settings → Plan.
wallet_empty402Add money to your wallet.
insufficient_funds422The wallet balance is too low for this. Add money.
first_deploy_verification_required428Complete the one-time check the console asks for before your first deployment.
not_eligible422The offer, such as migration credits, does not apply. details.reasons says why.

Plexivo AI#

CodeStatusWhat to do
ai_disabled403Plexivo AI is turned off for this organisation.
ai_daily_cap429Today’s Plexivo AI limit is reached. Try again tomorrow.
plan_expired, plan_stale409The plan you are approving is out of date. Ask Plexivo AI to plan again.
ai_unavailable503Plexivo AI is briefly unavailable. Retry shortly.

Temporary problems#

A 503, such as database_unavailable or payment_provider_unavailable, means something Plexivo depends on is briefly unavailable. Retry with backoff and the same Idempotency-Key. A 500 with internal_server_error is ours to fix: send us the x-trace-id.

Plexivo Postgres#

The Data API, Auth, Realtime and Functions answer with the same shape, plus a trace_id. Database errors also carry PostgreSQL’s sqlstate, and often a hint:

json
{
  "error": {
    "code": "unique_violation",
    "message": "duplicate key value violates unique constraint \"profiles_username_key\"",
    "sqlstate": "23505"
  },
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}

The client libraries raise it as PlexivoError (JavaScript) or PlexivoException (Dart), with status, code, message, hint, sqlstate and traceId. In a transaction or a raw SQL batch, operation is the step that failed, counting from 0.

sql
create table profiles (id uuid primary key default auth.uid(), username text unique not null);
alter table profiles enable row level security;
create policy profiles_read on profiles for select using (true);
create policy profiles_own on profiles for insert to authenticated with check (id = auth.uid());
js
import { createClient, PlexivoError, isUniqueViolation } from '@plexivo/client';

const db = createClient(PLEXIVO_DATA_URL, PLEXIVO_PUBLISHABLE_KEY);
await db.auth.signUp({ email, password });
await db.from('profiles').create({ username: 'asha' });

const other = createClient(PLEXIVO_DATA_URL, PLEXIVO_PUBLISHABLE_KEY, { persistSession: false });
await other.auth.signUp({ email: 'second@example.com', password });
try {
  await other.from('profiles').create({ username: 'asha' });
} catch (error) {
  if (isUniqueViolation(error)) console.log('That username is taken.');
  else if (error instanceof PlexivoError) console.log(error.status, error.code, error.traceId);
  else throw error;
}

Or, as with Supabase, get errors back instead of thrown, by creating the client with throwOnError: false:

js
const quiet = createClient(PLEXIVO_DATA_URL, PLEXIVO_PUBLISHABLE_KEY, { throwOnError: false });
const { data, error } = await quiet.from('no_such_table');
console.log(data, error.code);   // null 'table_not_exposed'
dart
import 'package:plexivo_client/plexivo_client.dart';

final db = PlexivoClient(dataUrl, publishableKey);
await db.signUp(email: email, password: password);
try {
  await db.from('profiles').create({'username': 'asha'});
} on PlexivoException catch (e) {
  if (e.isUniqueViolation) print('That username is taken.');
  print('${e.statusCode} ${e.code} ${e.traceId}');
}

Keys, tokens and limits#

CodeStatusWhat to do
invalid_api_key401The apikey header is missing or wrong, or names another project. Copy the key again from the Connect tab. The secret key is never accepted in a URL.
origin_denied403The web page’s origin is not in the Data API’s allowed origins. Add the exact address, such as https://app.example.com or http://localhost:5173.
secret_key_in_browser403The secret key arrived with a browser’s Origin header. Use the publishable key in browsers. On your server, do not forward the browser’s Origin header with the secret key. If the key was ever in a web page, rotate it. The client libraries throw the same code if you create a client with the secret key in a browser.
secret_key_required403Raw SQL and user import need the secret key, from a server, with no user’s token.
token_expired401The access token has run out. The client libraries refresh it and retry once by themselves; over HTTPS, call /auth/refresh and retry.
invalid_access_token401The token is not valid for this project, or its session was ended. Sign in again.
sign_in_required401This needs a signed-in user: a private room, a function, or a client call such as getUser().
rate_limited429Too many requests a minute from one address for this project; the rate depends on your plan. Wait for the Retry-After seconds, then retry.
project_request_cap_reached429The project used its monthly requests. It resets at the start of the next month (UTC); a bigger plan includes more.
too_large413The request body is over its limit: 5 MB for reads and writes, 1 MB for auth and GraphQL. Send fewer rows at once.
project_not_ready503The Data API is still being set up. Retry in a moment.

Data#

CodeStatusWhat to do
table_not_exposed404The table does not exist, or is not in the Data API: turn on row-level security and add a policy. A view needs security_invoker.
function_not_exposed404The database function has no @expose in its comment, is overloaded, or has unnamed arguments.
not_found404No row has that primary key, on /rest/v1/<table>/<id>.
invalid_request400The query is not valid: an unknown column, operator or relation, a limit over 1,000, more than 1,000 rows, or an update or delete without a filter. The message says which.
permission_denied403Row-level security or a grant refused the write. Check the policy’s with check and the row’s owner column.
unique_violation409A row with that unique value exists. Ask for another value, or upsert.
foreign_key_violation409The related row does not exist, or other rows still point at this one.
exclusion_violation409An exclusion constraint, such as overlapping bookings, refused the row.
retry409Two transactions collided. Run it again.
not_null_violation400A required column is missing. Send it, or give it a default.
check_violation400A check constraint refused the value.
raised400Your SQL function raised an exception; its message is in message.
invalid_value400PostgreSQL refused the value or statement; message and sqlstate say why.
statement_timeout504The query ran past its time: 8 seconds through the Data API, 30 for raw SQL. Add an index, or read fewer rows.
database_unavailable503The database is restarting or unreachable. Retry with backoff.

Auth#

CodeStatusWhat to do
email_taken409An account has that email. Offer sign-in or password recovery.
weak_password422Passwords are 10 to 128 bytes.
invalid_email422The address is not a valid email.
metadata_too_large422user_metadata is over 4 KB.
invalid_credentials401The email or password is wrong.
invalid_refresh_token401The refresh token was used, revoked or has run out. Sign in again.
mfa_required401The user has two-step verification. Ask for their authenticator code and send it as mfaCode.
invalid_mfa_code401The authenticator code is wrong or was used already.
invalid_passwordless_code401The email code is wrong, used or expired. Ask for a new one.
invalid_recovery_code401The password recovery code is wrong, used or expired. Ask for a new one.
anonymous_disabled403Guests are off. Turn on Guests under Sign-in methods.
not_anonymous409Only a guest can add an email with linkEmail.
redirect_not_allowed400Add the address to Return URLs.
provider_disabled403Turn the provider on under Social sign-in.
invalid_code401The OAuth code is wrong, used, older than 60 seconds, or its PKCE verifier does not match. Start the sign-in again.

Functions and Realtime#

CodeStatusWhat to do
function_not_found404No deployed function has that name.
function_unavailable502The Functions runtime did not answer. Check it is running on the Functions tab.
body_too_large413A function’s request body is over 6 MB.

A realtime join the server refuses reports its reason as the code, such as table_not_exposed, sign_in_required or invalid (realtime is off for the table, or the filter is not valid), through onError and ready().

From the client libraries#

These are raised by the client before or instead of a request:

CodeWhat to do
missing_whereAn update or delete without a filter, stopped before it was sent. Add where(), or allowGlobalUpdate().
record_not_foundfirst(), take(), sole() or single() found no row. Use firstOrNull() or maybeSingle() when none is fine.
multiple_rowssole(), single() or maybeSingle() found more than one row.
network_errorThe Data API could not be reached. Retry when the device is online.
abortedYour abortSignal cancelled the request.

Updated 28 October 2026