Skip to documentation
Ask the docs

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.

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 routeRequest fieldsResult or behavior
POST Tname; dimension, metric, sparse, text_fields, visibility_fields, deletion_protection, tags, identifier_profileCreate and describe an index. Some options are immutable after creation.
POST T/listname, prefix, limit, cursorindexes and optional next_cursor, limited to accessible indexes.
GET INo bodyIndex description.
PATCH Ideletion_protection, tagsConfigure the mutable index settings.
DELETE INo bodyDelete the index; deletion protection can refuse it.
POST I/records/upsertnamespace, recordsWrite supplied records; count and receipt.
POST I/records/fetchnamespace, ids; include_values, include_sparse, include_metadata, metadata_fields, text_fieldsRecords keyed by ID, missing IDs and receipt_position.
POST I/records/fetch-by-filternamespace and one nonempty filter or filter_expr; limit, cursor, consistency, projection fieldsMatching records and optional next_cursor.
POST I/records/list-idsnamespace; prefix, limit, cursor, consistencyIDs and optional next_cursor.
POST I/records/countnamespace; filter or filter_exprCount and namespace.
POST I/records/updatenamespace, id; metadata_merge, metadata_replace, metadata_remove, values, sparse_values, text_set, text_remove, if_revision_tokenUpdate one ID; receipt.
POST I/records/deletenamespace, ids. The separate delete-all form uses all, confirm and optionally dry_run.Delete selected IDs, or explicitly clear a namespace.
POST I/namespaces/createname; declared_capacityCreate a named namespace.
POST I/namespaces/describename; include_deletingNamespace state, counts and position.
POST I/namespaces/listprefix, limit, cursor, include_deletingnamespaces and optional next_cursor.
POST I/namespaces/configurename; declared_capacityChange declared capacity.
POST I/namespaces/deletename, confirmDelete a named namespace; confirm must match its name. The default namespace cannot be deleted.
GET I/statsNo bodyIndex and namespace statistics.
POST I/searchnamespace, mode, k; dense, sparse, lexical, fusion, filter or filter_expr, supported projection, require_completeRanked 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

  • 501 with reason record_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_insufficient or permission_denied: use a credential with the required identity and grants.
  • 404 index_not_found or namespace_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.