Response envelope
HydraDB core endpoints (/databases, /context/*, /query, /feedback, and /webhooks/indexing*) use the same top-level envelope for successful and failed requests. Connector endpoints (/connectors*) and PATCH /databases/{database}/metadata-schema return their success body without this envelope, but their errors use it too.
Use
error.code for branching and log meta.request_id for every failed request. The HTTP status tells you the class of failure; the error code tells you what to do.HTTP status codes
Common error codes
Endpoint pages list the most common codes for that operation. New codes may be added over time, so clients should handle unknown
error.code values gracefully.PATCH /databases/{database}/metadata-schema currently returns INTERNAL_ERROR for its 400 and 409 errors too, so branch on the HTTP status there.Deprecated
/tenants routes keep their pre-rename error codes. For backward compatibility, a request for a database that does not exist returns NOT_FOUND on the deprecated /tenants routes (not DATABASE_NOT_FOUND), and a duplicate on POST /tenants returns INVALID_INPUT (not DATABASE_ALREADY_EXISTS), whereas the canonical /databases routes return DATABASE_NOT_FOUND and DATABASE_ALREADY_EXISTS as shown above. The HTTP status is identical on both. The route decides the code, so the old tenant_id field sent to a /databases route still gets the new codes. See Migrating from tenant_id and sub_tenant_id.Ingestion error codes
Asynchronous ingestion failures surface a numericE#### code in the error_code field of GET /context/status responses and indexing.status_changed webhook payloads. Unlike the HTTP error.code values above (which describe why a request was rejected), these describe why a specific item failed to index.
Many storage- and capacity-related ingestion errors are transient: the pipeline retries them automatically with backoff, and they typically self-resolve within minutes. A code appearing in error_code does not by itself mean the item has failed permanently; only treat an item as a real failure once it reaches the terminal errored status.
E1002 is the one ingestion code that does not follow the polling advice above. The file is rejected at upload, so it never enters the pipeline and never gets a status record. Polling /context/status for it returns FILE_NOT_FOUND, not E1002. Read error_code on each item in the upload response instead. See Supported file formats for what is accepted, and note that one rejected file does not affect the other files in the same request.Retry pattern
Retry only transient failures:429, 500, and 503. Use exponential backoff with jitter and keep retries bounded. Two other codes clear on their own, so wait instead of backing off blindly: 409 SOURCE_PROCESSING (wait for Retry-After) and 422 TENANT_INFRA_NOT_READY (wait until the database is ready).
Handling errors
Troubleshooting
Authentication failures
Send exactly oneAuthorization header:
API-Version: 2 on raw HTTP requests. The official SDKs set the version header automatically.
Database not found after creation
Database creation is asynchronous. AfterPOST /databases, poll GET /databases/status until infra.scheduler_status, infra.graph_status, infra.vectorstore_status.knowledge, and infra.vectorstore_status.memories are all true (infra.ready_for_ingestion combines them). A query sent earlier returns 422 TENANT_INFRA_NOT_READY.
Ingestion validation errors
Common causes:document_metadatalength does not match thedocumentsarray length.app_knowledge,memories, ordocument_metadatawas sent as an object instead of a JSON-stringified multipart field.- A memory item has neither
textnoruser_assistant_pairs. - A typed metadata value does not match the database metadata schema.
Empty query results
Empty results are not always errors. Check these first:- Context status may still be
queuedorprocessing; pollGET /context/status. metadata_filtersmay be too restrictive or may target the wrong metadata namespace.- The query may be scoped to the wrong
databaseorcollection(formerlytenant_id/sub_tenant_id). - The
typevalue may exclude the store you need. Usetype: "all"when combining knowledge and memories inPOST /query.
Related sections
- API Reference: endpoint inventory and conventions
- Ingestion Status: async ingestion state
- Query: retrieval parameters and response shape
