Skip to main content

Response envelope

HydraDB core endpoints (/databases, /context/*, and /query) use the same top-level envelope for successful and failed requests. Webhook management endpoints (/webhooks/indexing*) return their documented response object directly and do not include this envelope.
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.
Missing database returns DATABASE_NOT_FOUND. A request for a database that does not exist returns DATABASE_NOT_FOUND on both the canonical /databases routes and the deprecated /tenants routes. The deprecated /tenants routes otherwise keep their pre-rename error contract for backward compatibility: a duplicate on POST /tenants returns INVALID_INPUT (not DATABASE_ALREADY_EXISTS), whereas the canonical POST /databases returns DATABASE_ALREADY_EXISTS as shown above. The HTTP status is identical on both. See Migrating from tenant_id and sub_tenant_id.

Ingestion error codes

Asynchronous ingestion failures surface a numeric E#### 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.
E6001 is transient, not terminal. If you observe it on an in-flight item, keep polling /context/status — the item normally advances to graph_creation / completed on a subsequent retry with no action on your part. Only contact support if the item is still reported as errored after retries are exhausted.

Retry pattern

Retry only transient failures: 429, 500, and 503. Use exponential backoff with jitter and keep retries bounded.

Handling errors

Troubleshooting

Authentication failures

Send exactly one Authorization header:
Also send API-Version: 2 on raw HTTP requests. The official SDKs set the version header automatically.

Database not found after creation

Database creation is asynchronous. After POST /databases, poll GET /databases/status until infra.scheduler_status, infra.graph_status, infra.vectorstore_status.knowledge, and infra.vectorstore_status.memories are all true.

Ingestion validation errors

Common causes:
  • document_metadata length does not match the documents array length.
  • app_knowledge, memories, or document_metadata was sent as an object instead of a JSON-stringified multipart field.
  • A memory item has neither text nor user_assistant_pairs.
  • A typed tenant_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 queued or processing; poll GET /context/status.
  • metadata_filters may be too restrictive or may target the wrong metadata namespace.
  • The query may be scoped to the wrong database or collection (formerly tenant_id / sub_tenant_id).
  • The type value may exclude the collection you need. Use type: "all" when combining knowledge and memories in POST /query.