Errors
The Invoance API uses standard HTTP status codes and a consistent JSON error structure across all endpoints. Errors are deterministic - the same invalid request always returns the same error code.
Error format
All error responses return a single JSON object with a machine-readable error code and a human-readable message. Never parse the message field programmatically, use the error field only.
{
"error": "invalid_event_type",
"message": "event_type is required and must be <= 128 chars."
}Rate-limit and quota errors include additional fields to help you handle the condition programmatically:
{
"error": "rate_limited",
"message": "Rate limit exceeded for your plan (builder: 50 req/sec).",
"retry_after": 2,
"plan_tier": "builder",
"limit_per_sec": 50,
"upgrade_url": "/dashboard/plans/upgrade"
}{
"error": "quota_exceeded",
"message": "You've reached your monthly events limit (10000/10000).",
"resource": "events",
"current_usage": 10000,
"plan_limit": 10000,
"plan_tier": "builder",
"upgrade_url": "/dashboard/plans/upgrade"
}HTTP status codes
Error codes
Use the error field to handle specific failure conditions in your integration. The status code provides the HTTP category; the error code provides the exact reason.
Authentication
missing_api_key401invalid_api_key401invalid_api_key_format401invalid_authorization_scheme401api_key_revoked401Authorization
insufficient_scope403ip_not_allowed403feature_not_available403Validation, General
invalid_payload400bad_request400payload_too_large413Validation, Events
invalid_event_type400Validation, Documents
invalid_document_hash400invalid_metadata400metadata_too_large400invalid_original_bytes_base64400original_bytes_empty400original_bytes_too_large400original_bytes_hash_mismatch400Validation, AI Attestations
invalid_attestation_type400empty_payload400invalid_context400subject_too_large400subject_too_many_keys400Validation, Traces
invalid_label400metadata_too_large400trace_empty400Not Found
event_not_found404document_not_found404attestation_not_found404trace_not_found404proof_not_found404Conflict
duplicate_event409idempotency_key_reuse_mismatch409document_already_anchored409trace_sealed409trace_sealing409trace_not_open409Payment
payment_required402Rate Limiting & Quotas
rate_limited429quota_exceeded429Server
db_error500ingest_failed500serialization_failed500Rate-limit headers
Every API response includes standard rate-limit headers. When a 429 is returned the Retry-After header tells you exactly how many seconds to wait before retrying.
Retry-AfterSeconds to wait before retrying (present on 429 responses).X-RateLimit-LimitMaximum requests per second for your plan tier.X-RateLimit-RemainingRequests remaining in the current window.Retry guidance
400 errorsDo not retry. Fix the request before resending.401 / 403 errorsDo not retry. Check your API key, scopes, and IP allowlist.404 errorsDo not retry. The resource does not exist.409 errorsDo not retry writes. The existing record is returned in the response body.413 errorsDo not retry. Reduce the payload size before resending.429 errorsRetry after the number of seconds in the Retry-After header.500 errorsRetry with exponential backoff. Contact support if persistent.