Skip to main content

REST

This page is the low-level HTTP reference for a deployed data product's API surface only. Ingest and outlet are not available over REST. For normal development, use the client libraries, MCP, or gRPC via those clients; use raw REST when you need plain HTTP (e.g. curl, minimal stacks, or generated OpenAPI-style callers).

A data product’s REST API is HTTP/1.1 over TLS with the same JWT rules as gRPC: Authorization: Bearer <jwt> on every call unless your deployment is configured for additional mechanisms (e.g. mTLS). Optional client certificates are supported when enabled for the data plane.

Route patterns

The exact paths are generated from the data product’s published API. Two families are common.

Function-style (RPC) API

For an operation named like <namespace>.<name> at version <v>:

  • If the request type is empty (a “void” list-style call):
    GET /api/v1/{namespace}.{name}@v{version}
  • Otherwise:
    POST /api/v1/{namespace}.{name}@v{version} with the request body in the message body.

Example: com.acme.orders.ListOrders v1 may be GET /api/v1/com.acme.orders.ListOrders@v1. com.acme.orders.PlaceOrder is typically POST /api/v1/com.acme.orders.PlaceOrder@v1.

Key–value API

When an API is bound to a key–value store, you may see:

  • GET /api/v1/{namespace}.{name}@v{version} for list, when a list operation exists.
  • GET /api/v1/{namespace}.{name}@v{version}/{key} for get-by-key.
  • DELETE on the same path pattern for delete, when exposed.

The {key} segment is interpreted as JSON (quoted strings, numbers, or other JSON values as needed).

Built-in routes

  • GET /.well-known/oauth-protected-resourceRFC 9728 metadata: resource, authorization_servers, bearer_methods_supported, scopes_supported, etc. Values come from the data product’s configuration; responses may be cacheable (e.g. one hour).
  • /mcp/* — Model Context Protocol entry points for tooling integration, when enabled.

Content negotiation (API operations)

The data plane supports these payload media types for generated API operations:

  • application/vnd.dataspine.v0+binary — internal binary v0 (see Internal binary serialization (v1))
  • application/vnd.dataspine.v0+json — Dataspine JSON v0
  • application/json — treated like Dataspine JSON v0

Generated handlers fall into two patterns:

Standard JSON request, typed response

For typical RPC-style operations:

  • Request Content-Type is usually application/json. Other types may be rejected with 400.
  • Response depends on Accept:
    • application/json or application/vnd.dataspine.v0+json — JSON body with Content-Type: application/json.
    • application/vnd.dataspine.v0+binary — binary v0 body with the matching Content-Type.
    • Unrecognized Accept400.

The HTTP status is often 200 even when the logical result is an error: check the ApiResponse.status / typed error field, which uses the same ApiStatusCode values as gRPC (see the gRPC page).

Raw response operations

Operations declared with raw HTTP responses return a RawHttpResponseV1 structure (type, bytes) from the handler. Negotiation:

  • Accept: application/json or application/vnd.dataspine.v0+json — JSON encoding of that wrapper.
  • Accept: application/vnd.dataspine.v0+binary — binary encoding of the wrapper.
  • Other Accept values (e.g. application/pdf, image/png) — if they match the operation’s declared response content type, the body is the raw bytes and Content-Type matches that declaration (e.g. file download without wrapping the file in a second JSON layer).
  • Missing Accept may yield 400.

HTTP status mapping (errors)

Mapping is consistent with common REST expectations, for example:

  • Malformed or unsupported request → 400
  • Missing/invalid auth at the edge → 401
  • Not found / unknown resource where applicable → 404
  • Server or unexpected handler failure → 5xx

As with gRPC, many API-level outcomes still appear inside the ApiResponse body with an application-level status code on 200.

Examples

POST with binary Accept:

curl -sS \
-X POST \
-H "Authorization: Bearer $JWT" \
-H "Content-Type: application/json" \
-H "Accept: application/vnd.dataspine.v0+binary" \
--data '{"customerId":"00000000-0000-0000-0000-000000000000","items":[]}' \
https://orders.example.com/api/v1/com.acme.orders.PlaceOrder@v1

GET JSON:

curl -sS \
-H "Authorization: Bearer $JWT" \
-H "Accept: application/json" \
https://orders.example.com/api/v1/com.acme.orders.ListOrders@v1

OAuth protected-resource metadata:

curl -sS https://orders.example.com/.well-known/oauth-protected-resource

Application integration

Typed wrappers and the TypeScript RestApiClient for raw responses: Application integration.