OriginChainDB / Guides
Vector record API
Create vector indexes, write dense or sparse records with metadata, fetch by ID and search within a namespace.
Indexes, namespaces and credentials
This API stores records in vector indexes and namespaces. It is separate from the vector-table API, where vectors are associated with SQL row IDs. A write through one API does not automatically populate the other.
Use the instance HTTPS endpoint, tenant ID and a bearer credential with an authenticated subject and the required vector grants. Read, write, delete and manage permissions are distinct. Creating an index requires tenant-level manage permission. A generic instance credential without the required subject or grant can be refused; ask your administrator to provision an appropriate credential.
Set the server environment values OC_ENDPOINT, OC_TENANT, OC_TOKEN and, after creating or selecting an index, OC_INDEX_ID. Use the returned index identity in requests. Record IDs are scoped to their namespace. A newly created index includes the __default__ namespace.
Create a small index
Send this JSON body to POST /v1/tenants/:tenant/vector-indexes. The example uses three-dimensional vectors for readability; choose the dimension produced by your embedding model.
{
"name": "catalog-vectors",
"dimension": 3,
"metric": "cosine"
} The response describes the index, including index_id, name, state, dimension and metric. Dense metric values are cosine, dot, l2 and manhattan. Enable sparse storage with sparse: true when needed. Generated-embedding index configuration is not available through this API.
Upsert records
Send this body to POST /v1/tenants/:tenant/vector-indexes/:index/records/upsert. Each record needs an ID and the representations required by its index. Supplied dense values must match the index dimension.
{
"namespace": "__default__",
"records": [
{
"id": "item-1",
"values": [
1,
0,
0
],
"metadata": {
"category": "notebook"
}
},
{
"id": "item-2",
"values": [
0.8,
0.2,
0
],
"metadata": {
"category": "planner"
}
}
]
} Records can contain values, sparse_values, metadata, and text for configured text fields. Sparse values use an indices array and a matching values array. The response includes upserted_count, namespace_created and a write receipt.
Fetch by ID
Fetch is a POST request, with projection flags specifying which data to return.
curl "$OC_ENDPOINT/v1/tenants/$OC_TENANT/vector-indexes/$OC_INDEX_ID/records/fetch" \
-H "Authorization: Bearer $OC_TOKEN" \
-H "Content-Type: application/json" \
--data '{"namespace":"__default__","ids":["item-1"],"include_metadata":true}' {
"namespace": "__default__",
"ids": [
"item-1",
"item-2"
],
"include_values": true,
"include_metadata": true
} The response’s records object is keyed by record ID; missing lists requested IDs not returned. Record details include a revision token, and the response includes its namespace and read position. Retain the revision token when you need a conditional update.
Search the index
Send this body to POST /v1/tenants/:tenant/vector-indexes/:index/search. Search is a sibling of records, not a records/query route.
{
"namespace": "__default__",
"mode": "semantic",
"k": 5,
"dense": {
"vector": [
1,
0,
0
]
},
"include_metadata": true
} Search modes are semantic, lexical, hybrid and dense_with_text_filter, subject to the index’s configuration. Dense queries accept a vector or a record ID; sparse queries use indices and values. Lexical queries use a configured field and query text.
Inspect hits, returned, completeness, the individual legs and the reported read position. Requesting a number of results does not guarantee that many matches. Dense quality defaults to approximate high_recall; fast and exact are additional modes subject to caller eligibility. Search does not use cursors or paginate.
Search currently refuses expected_generation and the body field timeout_ms. Stored-text projection is unavailable, and queries with a lexical leg cannot return projected values or metadata through this search route. Some plans also refuse filters or require_complete when they cannot enforce them; handle the named refusal instead of dropping the option silently.
Update or delete selected IDs
Use records/update to update one record by ID. Metadata merge, replacement and removal are separate fields; select the operation you intend. Conditional writes accept if_revision_token.
{
"namespace": "__default__",
"id": "item-1",
"metadata_merge": {
"category": "journal"
}
} Use records/delete to remove specified IDs. Its response includes counts of deleted and missing IDs plus a receipt. This example removes only item-2.
{
"namespace": "__default__",
"ids": [
"item-2"
]
} Route reference
Let T mean /v1/tenants/:tenant/vector-indexes and I mean T/:index. Send JSON bodies on POST and PATCH requests. The table lists the main request fields; unknown or unsupported fields can be refused.
| Method and route | Request fields | Result or behavior |
|---|---|---|
POST T | name; dimension, metric, sparse, text_fields, visibility_fields, deletion_protection, tags, identifier_profile | Create and describe an index. Some options are immutable after creation. |
POST T/list | name, prefix, limit, cursor | indexes and optional next_cursor, limited to accessible indexes. |
GET I | No body | Index description. |
PATCH I | deletion_protection, tags | Configure the mutable index settings. |
DELETE I | No body | Delete the index; deletion protection can refuse it. |
POST I/records/upsert | namespace, records | Write supplied records; count and receipt. |
POST I/records/fetch | namespace, ids; include_values, include_sparse, include_metadata, metadata_fields, text_fields | Records keyed by ID, missing IDs and receipt_position. |
POST I/records/fetch-by-filter | namespace and one nonempty filter or filter_expr; limit, cursor, consistency, projection fields | Matching records and optional next_cursor. |
POST I/records/list-ids | namespace; prefix, limit, cursor, consistency | IDs and optional next_cursor. |
POST I/records/count | namespace; filter or filter_expr | Count and namespace. |
POST I/records/update | namespace, id; metadata_merge, metadata_replace, metadata_remove, values, sparse_values, text_set, text_remove, if_revision_token | Update one ID; receipt. |
POST I/records/delete | namespace, ids. The separate delete-all form uses all, confirm and optionally dry_run. | Delete selected IDs, or explicitly clear a namespace. |
POST I/namespaces/create | name; declared_capacity | Create a named namespace. |
POST I/namespaces/describe | name; include_deleting | Namespace state, counts and position. |
POST I/namespaces/list | prefix, limit, cursor, include_deleting | namespaces and optional next_cursor. |
POST I/namespaces/configure | name; declared_capacity | Change declared capacity. |
POST I/namespaces/delete | name, confirm | Delete a named namespace; confirm must match its name. The default namespace cannot be deleted. |
GET I/stats | No body | Index and namespace statistics. |
POST I/search | namespace, mode, k; dense, sparse, lexical, fusion, filter or filter_expr, supported projection, require_complete | Ranked hits, completeness and read position; some options are refused for particular plans. |
For paged reads, pass the returned next_cursor unchanged with the same request scope. Consistency is read_committed; snapshot pagination is unavailable. Search has no next cursor. Namespace-wide deletion requires an explicit confirmation equal to the namespace name; review a dry run before an intended bulk removal.
Dry runs are supported for the delete-all form, not for upsert, update by ID, delete by IDs or namespace deletion. Record writes refuse expected_generation; use the record’s if_revision_token for supported conditional writes.
Availability, permissions and errors
501with reasonrecord_api_not_enabled: this engine has not enabled the API.501 unsupported_topology: the requested deployment topology is not supported. The record API does not support tenants spread across multiple engine stores.403 key_scope_insufficientorpermission_denied: use a credential with the required identity and grants.404 index_not_foundornamespace_not_found: check the identity and your access. These answers do not disclose whether an inaccessible resource exists.403 record_level_policy_unsupported: the record operation cannot honor the caller’s row-level policy. It refuses rather than bypassing that policy.503 record_api_restore_pending: the record API is waiting for restore processing to finish. Follow the reported retry guidance.
Inspect error codes, reasons and retry guidance before retrying. Filter-based update and delete jobs, a Pinecone-compatible endpoint, and Pinecone SDK compatibility are not available. There is no throughput or dataset-scale guarantee implied by these examples.