curl -X PATCH 'https://api.hydradb.com/context/policy_main/metadata' \
-H "Authorization: Bearer $HYDRA_DB_API_KEY" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"collection": "team_docs",
"database_metadata": {
"department": "legal",
"priority": 7
},
"additional_metadata": {
"author": "Legal Team",
"doc_version": 3
}
}'
import requests
response = requests.patch(
"https://api.hydradb.com/context/policy_main/metadata",
headers={
"Authorization": f"Bearer {HYDRA_DB_API_KEY}",
"API-Version": "2",
"Content-Type": "application/json",
},
json={
"database": "acme_corp",
"collection": "team_docs",
"database_metadata": {
"department": "legal",
"priority": 7,
},
"additional_metadata": {
"author": "Legal Team",
"doc_version": 3,
},
},
)
const response = await fetch("https://api.hydradb.com/context/policy_main/metadata", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.HYDRA_DB_API_KEY}`,
"API-Version": "2",
"Content-Type": "application/json",
},
body: JSON.stringify({
database: "acme_corp",
collection: "team_docs",
database_metadata: {
department: "legal",
priority: 7,
},
additional_metadata: {
author: "Legal Team",
doc_version: 3,
},
}),
});
{
"success": true,
"data": {
"id": "policy_main",
"tenant_id": "acme_corp",
"sub_tenant_id": "team_docs",
"updated": true,
"database_metadata_keys": ["department", "priority"],
"tenant_metadata_keys": ["department", "priority"],
"additional_metadata_keys": ["author", "doc_version"],
"vector_sync_required": false,
"milvus_sync_required": false,
"chunk_rows_matched": 4,
"chunk_rows_modified": 4
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": true,
"data": {
"id": "policy_main",
"tenant_id": "acme_corp",
"sub_tenant_id": "team_docs",
"updated": true,
"database_metadata_keys": ["summary_label"],
"tenant_metadata_keys": ["summary_label"],
"additional_metadata_keys": [],
"vector_sync_required": true,
"vector_synced": true,
"vector_rows_synced": 4,
"milvus_sync_required": true,
"milvus_synced": true,
"milvus_rows_synced": 4,
"chunk_rows_matched": 4,
"chunk_rows_modified": 4
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 28.9
}
}
{
"success": false,
"data": null,
"error": {
"code": "BAD_REQUEST",
"message": "invalid metadata edit: tenant_metadata.department must be of type VARCHAR"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 4.8
}
}
Update Source Metadata
Merge tenant metadata and additional metadata for one existing source without re-ingesting its content.
curl -X PATCH 'https://api.hydradb.com/context/policy_main/metadata' \
-H "Authorization: Bearer $HYDRA_DB_API_KEY" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"collection": "team_docs",
"database_metadata": {
"department": "legal",
"priority": 7
},
"additional_metadata": {
"author": "Legal Team",
"doc_version": 3
}
}'
import requests
response = requests.patch(
"https://api.hydradb.com/context/policy_main/metadata",
headers={
"Authorization": f"Bearer {HYDRA_DB_API_KEY}",
"API-Version": "2",
"Content-Type": "application/json",
},
json={
"database": "acme_corp",
"collection": "team_docs",
"database_metadata": {
"department": "legal",
"priority": 7,
},
"additional_metadata": {
"author": "Legal Team",
"doc_version": 3,
},
},
)
const response = await fetch("https://api.hydradb.com/context/policy_main/metadata", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.HYDRA_DB_API_KEY}`,
"API-Version": "2",
"Content-Type": "application/json",
},
body: JSON.stringify({
database: "acme_corp",
collection: "team_docs",
database_metadata: {
department: "legal",
priority: 7,
},
additional_metadata: {
author: "Legal Team",
doc_version: 3,
},
}),
});
{
"success": true,
"data": {
"id": "policy_main",
"tenant_id": "acme_corp",
"sub_tenant_id": "team_docs",
"updated": true,
"database_metadata_keys": ["department", "priority"],
"tenant_metadata_keys": ["department", "priority"],
"additional_metadata_keys": ["author", "doc_version"],
"vector_sync_required": false,
"milvus_sync_required": false,
"chunk_rows_matched": 4,
"chunk_rows_modified": 4
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": true,
"data": {
"id": "policy_main",
"tenant_id": "acme_corp",
"sub_tenant_id": "team_docs",
"updated": true,
"database_metadata_keys": ["summary_label"],
"tenant_metadata_keys": ["summary_label"],
"additional_metadata_keys": [],
"vector_sync_required": true,
"vector_synced": true,
"vector_rows_synced": 4,
"milvus_sync_required": true,
"milvus_synced": true,
"milvus_rows_synced": 4,
"chunk_rows_matched": 4,
"chunk_rows_modified": 4
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 28.9
}
}
{
"success": false,
"data": null,
"error": {
"code": "BAD_REQUEST",
"message": "invalid metadata edit: tenant_metadata.department must be of type VARCHAR"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 4.8
}
}
PATCH /context/{id}/metadata
PATCH /context/sources/{source_id}/metadata still works but is deprecated - migrate to the route above. Both dispatch to the same handler; source_id and id name the same value.curl -X PATCH 'https://api.hydradb.com/context/policy_main/metadata' \
-H "Authorization: Bearer $HYDRA_DB_API_KEY" \
-H "API-Version: 2" \
-H "Content-Type: application/json" \
-d '{
"database": "acme_corp",
"collection": "team_docs",
"database_metadata": {
"department": "legal",
"priority": 7
},
"additional_metadata": {
"author": "Legal Team",
"doc_version": 3
}
}'
import requests
response = requests.patch(
"https://api.hydradb.com/context/policy_main/metadata",
headers={
"Authorization": f"Bearer {HYDRA_DB_API_KEY}",
"API-Version": "2",
"Content-Type": "application/json",
},
json={
"database": "acme_corp",
"collection": "team_docs",
"database_metadata": {
"department": "legal",
"priority": 7,
},
"additional_metadata": {
"author": "Legal Team",
"doc_version": 3,
},
},
)
const response = await fetch("https://api.hydradb.com/context/policy_main/metadata", {
method: "PATCH",
headers: {
Authorization: `Bearer ${process.env.HYDRA_DB_API_KEY}`,
"API-Version": "2",
"Content-Type": "application/json",
},
body: JSON.stringify({
database: "acme_corp",
collection: "team_docs",
database_metadata: {
department: "legal",
priority: 7,
},
additional_metadata: {
author: "Legal Team",
doc_version: 3,
},
}),
});
Request
Path parameters
| Name | Description |
|---|---|
Existing source ID to update. This is the id you supplied at ingest, or the source ID returned by HydraDB. |
Body
| Name | Description |
|---|---|
Owning database. (deprecated alias: tenant_id) | |
Collection that contains the source. This endpoint does not default it. (deprecated alias: sub_tenant_id) | |
Schema-backed metadata fields to merge into the source’s metadata. Keys must satisfy the tenant metadata schema when one exists. (deprecated alias: tenant_metadata) | |
Free-form metadata fields to merge into the source’s additional_metadata. |
database_metadata or additional_metadata is required.
database_metadata for schema-backed source metadata (deprecated alias: tenant_metadata - still accepted, but the canonical field wins if both are sent). The shorter metadata field used by ingestion/list examples is not accepted in this PATCH body. document_metadata is also not accepted; use additional_metadata.Behavior
- The update is a merge/upsert:
- keys present in the request are inserted or overwritten
- keys omitted from the request are preserved
- The source must already exist. This endpoint does not create sources.
- The endpoint edits one source at a time. Bulk metadata edits are not supported.
- Updated metadata is visible to
/querymetadata filters and/context/listfilters. - If an edited tenant metadata field has
enable_dense_embeddingorenable_sparse_embedding, HydraDB synchronously refreshes the relevant vector store metadata search lane. - If the edited fields are
enable_match-only, the edit remains MongoDB-only andvector_sync_requiredisfalse.
Response
{
"success": true,
"data": {
"id": "policy_main",
"tenant_id": "acme_corp",
"sub_tenant_id": "team_docs",
"updated": true,
"database_metadata_keys": ["department", "priority"],
"tenant_metadata_keys": ["department", "priority"],
"additional_metadata_keys": ["author", "doc_version"],
"vector_sync_required": false,
"milvus_sync_required": false,
"chunk_rows_matched": 4,
"chunk_rows_modified": 4
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 12.3
}
}
{
"success": true,
"data": {
"id": "policy_main",
"tenant_id": "acme_corp",
"sub_tenant_id": "team_docs",
"updated": true,
"database_metadata_keys": ["summary_label"],
"tenant_metadata_keys": ["summary_label"],
"additional_metadata_keys": [],
"vector_sync_required": true,
"vector_synced": true,
"vector_rows_synced": 4,
"milvus_sync_required": true,
"milvus_synced": true,
"milvus_rows_synced": 4,
"chunk_rows_matched": 4,
"chunk_rows_modified": 4
},
"error": null,
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 28.9
}
}
{
"success": false,
"data": null,
"error": {
"code": "BAD_REQUEST",
"message": "invalid metadata edit: tenant_metadata.department must be of type VARCHAR"
},
"meta": {
"request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d",
"latency_ms": 4.8
}
}
| Field | Description |
|---|---|
| Updated source ID. | |
| Public tenant ID. | |
| Sub-tenant that contained the source. | |
true when the source metadata was updated. | |
| Database metadata keys included in the request. | |
Deprecated alias for database_metadata_keys; still emitted for backward compatibility. | |
| Additional metadata keys included in the request. | |
true when at least one changed tenant metadata field has dense/sparse embedding enabled. | |
Present when sync was required. true means the sync completed. | |
| Number of chunk rows synced to the vector store when sync was required. | |
Deprecated alias for vector_sync_required; still emitted for backward compatibility. | |
Deprecated alias for vector_synced; still emitted for backward compatibility. | |
Deprecated alias for vector_rows_synced; still emitted for backward compatibility. | |
| Number of MongoDB chunk rows matched by the source update. | |
| Number of MongoDB chunk rows modified by the source update. |
Validation and errors
| Status | When it happens |
|---|---|
400 | Missing database, missing collection, empty metadata payload, document_metadata supplied, unknown tenant metadata key when a schema exists, wrong type, reserved key, over-size payload, too-deep nesting, or null for a dense/sparse-enabled field. |
404 | Source does not exist for the (database, collection, id) scope. |
500 | Metadata was written to MongoDB but dense/sparse vector store sync failed. Retry the same idempotent edit to converge. |
Size limits
database_metadata (and its still-accepted tenant_metadata alias) is capped at
16 KiB; additional_metadata at 1 KiB. Each cap applies to the whole map,
measured on its compact JSON encoding in UTF-8 bytes - keys, quotes and
punctuation count toward the budget, so budget in bytes rather than in characters
of content.
document_metadata has no size limit here because it is not accepted on this
endpoint at all - any non-null value returns 400, whatever its size. It is a
valid alias for additional_metadata on
/context/ingest, but not on this
one. Send additional_metadata.400 and
reports both numbers:
{
"success": false,
"data": null,
"error": {
"code": "INVALID_INPUT",
"message": "invalid metadata edit: additional_metadata is too large (1065 bytes when serialized; the maximum is 1024). Reduce the number or size of metadata fields."
}
}
Related
Authorizations
API key sent as a Bearer token: "Bearer prefix.secret"
Path Parameters
Source ID
"HydraDoc1234"
Body
Metadata update request
ACL, when present, REPLACES the source's access-control list without re-ingestion (PRO-1684): pass the COMPLETE new allow-list (adding a third user means sending all three), an empty list to make the source private, or ["public"] to open it to every identified caller. A pointer so omitted (nil, ACL untouched) is distinguishable from an explicit empty list (private). ACL uses RawMessage so the handler can tell three wire states apart: absent (leave the stored ACL untouched), explicit null (revoke to nobody, JSON-merge-patch semantics), and a list (replace). A plain *[]string cannot: encoding/json leaves the pointer nil for BOTH absent and null, which silently ignored an explicit null revocation.
Free-form key-value pairs to merge into the source's additional_metadata. The only accepted spelling for document metadata on this endpoint. Capped at 1 KiB, measured on the compact JSON encoding of the whole map in UTF-8 bytes — keys, quotes, commas and braces count toward the budget. Over-cap returns 400 with the actual byte count.
Show child attributes
Show child attributes
{ "author": "ada", "doc_version": 3 }
Collection scope. Defaults to the default collection when omitted. Formerly sub_tenant_id; the sub_tenant_id alias is still accepted (deprecated).
"team_docs"
Database/Collection are the canonical v2 names; TenantID/SubTenantID are their deprecated aliases. The TenantAliases middleware reconciles them in the request body before binding, so the handler reads TenantID/SubTenantID.
"acme_corp"
Schema-backed metadata fields to merge into the source's metadata (database metadata). Canonical name; tenant_metadata is a deprecated alias. Capped at 16 KiB, measured on the compact JSON encoding of the whole map in UTF-8 bytes — keys, quotes, commas and braces count toward the budget. Over-cap returns 400 with the actual byte count.
Show child attributes
Show child attributes
{ "department": "legal", "priority": 7 }
Not accepted on this endpoint. Sending any non-null value returns 400 (document_metadata is not accepted; use additional_metadata), regardless of size. Use additional_metadata instead. Accepted as an alias on /context/ingest only.
Show child attributes
Show child attributes
deprecated: use collection
"sub_tenant_4567"
deprecated: use database
"tenant_1234"
Deprecated alias for database_metadata, still accepted here; database_metadata wins when both are sent. Capped at 16 KiB, measured on the compact JSON encoding of the whole map in UTF-8 bytes — keys, quotes, commas and braces count toward the budget. Over-cap returns 400 with the actual byte count.
Show child attributes
Show child attributes
{ "department": "legal", "priority": 7 }
Response
OK
Show child attributes
Show child attributes
{ "acl_drift_recorded": true, "acl_updated": true, "chunk_rows_matched": 1, "chunk_rows_modified": 1, "collection": "team_docs", "database": "acme_corp", "database_metadata_keys": ["department", "priority"], "id": "HydraDoc1234", "milvus_rows_synced": 1, "milvus_sync_required": true, "milvus_synced": true, "sub_tenant_id": "sub_tenant_4567", "tenant_id": "tenant_1234", "updated": true, "vector_acl_synced": true, "vector_rows_synced": 1, "vector_sync_required": true, "vector_synced": true }
Error message, empty string on success.
Show child attributes
Show child attributes
{ "code": "DATABASE_NOT_FOUND", "message": "Database not found" }
Show child attributes
Show child attributes
{ "collection": "team_docs", "database": "acme_corp", "latency_ms": 12.3, "request_id": "9d13aef4-02f4-4e73-8c62-4c2601d04f9d", "source_type": "file", "sub_tenant_id": "sub_tenant_4567", "tenant_id": "tenant_1234" }
Whether the request succeeded.
true
Was this page helpful?
