Skip to main content

Error Codes Reference

Every Urblock API error returns a Stripe-style JSON envelope:

{
"error": {
"type": "invalid_request_error",
"code": "missing_field",
"message": "The 'name' field is required.",
"param": "name",
"status": 400
}
}

Error Types

TypeDescription
invalid_request_errorThe request was malformed, missing required fields, or has invalid parameter values.
authentication_errorMissing, expired, or invalid authentication credentials.
authorization_errorThe API key or token lacks the required scope or permission.
not_found_errorThe requested resource does not exist or is not accessible to this tenant.
rate_limit_errorThe request was rate-limited. Retry after the indicated delay.
conflict_errorThe request conflicts with the current state (e.g., duplicate idempotency key).
blockchain_errorAn on-chain operation failed (reverted, insufficient gas, nonce collision).
api_errorAn internal server error occurred. Contact support if this persists.

Error Codes by Category

Authentication (authentication_error)

CodeStatusDescription
missing_credentials401Authorization header with Bearer token or API key is required.
missing_token401Authorization header with Bearer token is required.
invalid_token401The provided JWT or API key is invalid.
token_expired401The JWT has expired. Refresh using /auth/refresh.
invalid_credentials401Invalid email or password.
invalid_refresh_token401Refresh token is invalid, expired, or has been revoked.
invalid_api_key401The API key does not exist or has been revoked.
session_ip_mismatch401JWT originated from a different IP (when IP binding is enforced).
account_locked423Account temporarily locked due to too many failed login attempts.

Authorization (authorization_error)

CodeStatusDescription
insufficient_scope403The API key does not have the required scope for this operation.
secret_key_required403This endpoint requires a secret key (sk_), not a publishable key.
admin_required403This endpoint requires admin role.
tenant_mismatch403The resource belongs to a different tenant.

Validation (invalid_request_error)

CodeStatusDescription
missing_field400A required field is missing from the request body.
invalid_field400A field value is invalid (wrong type, format, or range).
invalid_id_format400The provided ID does not match the expected format (tok_, wal_, etc.).
invalid_address400The provided Ethereum address is not a valid checksummed address.
chain_id_required400The chain_id query parameter is required for this endpoint.
invalid_chain_id400chain_id must be a positive integer.
invalid_network400The specified network is not supported or not active.
invalid_pagination400Invalid pagination parameters (limit/offset out of range).

Resource Not Found (not_found_error)

CodeStatusDescription
token_not_found404Token with the given ID does not exist for this tenant.
wallet_not_found404Wallet with the given ID does not exist for this tenant.
transaction_not_found404Transaction with the given ID does not exist for this tenant.
nft_not_found404NFT with the given ID does not exist for this tenant.
identity_not_found404Identity with the given ID does not exist for this tenant.
governance_not_found404Governance contract not found for this tenant.
vesting_not_found404Vesting schedule not found for this tenant.
vault_not_found404Vault not found for this tenant.
webhook_not_found404Webhook endpoint not found for this tenant.
network_not_found404The specified network does not exist.
user_not_found404User not found.
connect_account_not_found404Connect smart account not found.

Conflict (conflict_error)

CodeStatusDescription
email_already_exists409An account with this email already exists.
idempotency_conflict409A request with this idempotency key was already processed with different parameters.
token_already_deployed409This token has already been deployed on the specified network.
duplicate_webhook409A webhook with this URL already exists for this tenant.

Rate Limiting (rate_limit_error)

CodeStatusDescription
rate_limited429Too many requests. Check Retry-After and X-RateLimit-* headers.
usage_limit_exceeded429Monthly usage limit exceeded for your plan. Upgrade to continue.

Blockchain (blockchain_error)

CodeStatusDescription
contract_reverted422The smart contract call reverted. Check the message for the revert reason.
insufficient_gas422Transaction ran out of gas. The gas limit was insufficient.
nonce_collision422Nonce has already been used. The transaction may have been submitted twice.
rpc_error502The blockchain RPC node returned an error. Retry after a short delay.
chain_not_supported400The specified chain ID is not configured.
deployment_failed422Contract deployment failed on-chain.

Internal (api_error)

CodeStatusDescription
internal_error500An unexpected internal error occurred.
service_unavailable503The service is temporarily unavailable. Retry with exponential backoff.
request_timeout408The request timed out.

HTTP Status Code Summary

StatusMeaningRetryable?
400Bad Request — fix the requestNo
401Unauthorized — check credentialsNo
403Forbidden — insufficient permissionsNo
404Not Found — resource doesn't existNo
408Timeout — request took too longYes
409Conflict — already existsNo
422Unprocessable — blockchain/business rule failureSometimes
423Locked — account lockedNo (wait)
429Rate LimitedYes (after delay)
500Internal ErrorYes
502Bad Gateway (RPC)Yes
503Service UnavailableYes

SDK Error Handling

import { Urblock, UrblockApiError } from "@urblock/sdk";

const client = new Urblock("sk_live_...");

try {
const token = await client.tokens.create({ /* ... */ });
} catch (err) {
if (err instanceof UrblockApiError) {
console.error(`[${err.type}] ${err.code}: ${err.message}`);
console.error(`Status: ${err.status}`);
if (err.param) console.error(`Param: ${err.param}`);
if (err.rateLimit) {
console.error(`Rate limit: ${err.rateLimit.remaining}/${err.rateLimit.limit}`);
}
}
}