OriginChain docs
01 · quickstart

Quickstart - 5 minutes from zero to your first query

By the end of this page you will have signed up, defined a table, saved data into it, and run four kinds of search against it: SQL for filtering, vector for similarity, full-text for keywords, and graph for relationships - all on the same instance, with no extra setup between them.

Every code example is shown in cURL, Python, TypeScript, and Go. Pick the tab you want and the rest of the page follows that language.

1

Sign up and get your token.

Head to app.originchain.ai/signup. Add a card during signup - every account is billed from day 1 on whichever tier you pick. After signup you will:

  1. Pick a region close to your users. Your data never leaves it.
  2. Pick a tier (you can change it later). Start with the smallest one.
  3. Wait about 90 seconds while your dedicated instance provisions.
  4. Copy three things from the "Connect" panel: your endpoint URL, a one-time bearer token, and your tenant ID.
save them to your shell
# Paste these into your shell. Replace the values with the ones
# from your dashboard after you finish step 1.

export OC_HOST=acme.ap-south-1.db.originchain.ai
export OC_TENANT=acme
export OC_TOKEN=oc_live_xxxxxxxxxxxxxxxx
one-time token

The bearer token is shown once and never again. Paste it into your secrets manager (1Password, AWS Secrets Manager, Doppler, etc.) before you close the tab. If you lose it, rotate it from the dashboard and update your apps.

2

Install an SDK (or skip if you prefer cURL).

The SDKs handle authentication, retries, and request signing for you. You can use raw HTTP too - every example below shows cURL alongside.

install
package manager
# cURL is built into macOS and most Linux distros - check it's there:
curl --version
# On Windows: comes with Git Bash and PowerShell 6+.
connect
create your client
# cURL has no client - every call carries the bearer header.
# Confirm your env vars resolve and the instance is reachable:
curl -s -o /dev/null -w "HTTP %{http_code}\n" \
  "https://$OC_HOST/health" \
  -H "Authorization: Bearer $OC_TOKEN"
# → HTTP 200 if everything is wired up.
SDK coverage today

Python wraps every endpoint on this page. TypeScript and Go wrap SQL, vector, full-text, graph, and the ask endpoint - row reads and writes use raw fetch / net/http for now (helpers ship in the next release).

3

Define your first table.

A schema is the shape of your data - the list of columns, their types, and any extra indexes or extractions you want. OriginChain reads schemas as small TOML files.

Save this as schemas/orders.toml. It declares an orders table that you can later query four ways - SQL, vector, full-text, graph.

schemas/orders.toml
namespace   = "shop"
table       = "orders"
primary_key = ["id"]

[[columns]]
name = "id"
ty   = "str"        # ULIDs / UUIDs travel as text
required = true

[[columns]]
name = "customer"
ty   = "str"

[[columns]]
name = "amount_cents"
ty   = "i64"        # money in minor units - never f64

[[columns]]
name = "status"
ty   = "str"

[[columns]]
name = "notes"
ty   = "str"

[[columns]]
name = "placed_ms"
ty   = "u64"        # epoch milliseconds

# Make WHERE status = ... fast.
[[indexes]]
name    = "by_status"
columns = ["status"]
what each block does
Block What it does
namespace, table A two-part name for your table. You address it as namespace.table in queries (here, shop.orders).
primary_key A list of column names that uniquely identify a row. Most tables use a single ID column - put it in the array.
[[columns]] One column per block. Set required = true on columns that can't be null. Six types: str, i64, u64, f64, bool, bytes.
[[indexes]] Secondary index for fast filtering. Without this, WHERE status = ... scans every row.

Notice there's no column type for vectors or full-text indexes. Those live on separate runtime endpoints - you'll see how in steps 7 and 8. The schema TOML is just for rows. See Schema reference for relations, foreign keys, CHECK constraints, and derived columns.

register it
POST /v1/tenants/:t/schemas
# Save the TOML above as schemas/orders.toml, then:
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/schemas" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: text/plain" \
  --data-binary @schemas/orders.toml
common mistakes
  • Wrong Content-Type. TOML schemas use text/plain, not application/json.
  • No primary key. Every schema needs a top-level primary_key = ["..."] array naming at least one declared column, otherwise registration fails.
4

Save your first row.

One call saves the row and updates every secondary index that touches its columns - all atomically, behind one fsync. (Vector and full-text indexes are managed separately - we'll do those in steps 7 and 8.)

POST /v1/tenants/:t/rows/:schema
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/rows/shop.orders" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id":           "01JTRX9KQ3YH8K2WMX0F5JZAB7",
    "customer":     "01JTRX1H4Q9P0N2WMX0F5JZ001",
    "amount_cents": 12950,
    "status":       "paid",
    "notes":        "rush delivery, signed by recipient",
    "placed_ms":    1714478049000
  }'

For bulk imports (1k+ rows), see Insert → bulk. The endpoint takes JSON arrays or NDJSON streams.

5

Read it back.

Look up a row by its primary key. This is the fastest read in OriginChain - direct hash lookup, single-digit milliseconds.

GET /v1/tenants/:t/rows/:schema/:pk
curl "https://$OC_HOST/v1/tenants/$OC_TENANT/rows/shop.orders/01JTRX9KQ3YH8K2WMX0F5JZAB7" \
  -H "Authorization: Bearer $OC_TOKEN"
6

Run a SQL query.

Filter, group, and aggregate with regular SQL. This query finds every paying customer and totals their orders.

POST /v1/tenants/:t/sql
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/sql" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "sql": "SELECT customer, SUM(amount_cents) AS total FROM shop.orders WHERE status = '\''paid'\'' GROUP BY customer LIMIT 10"
  }'
what you can use today

The SQL surface supports SELECT, WHERE, GROUP BY, aggregates (COUNT, SUM, AVG, MIN, MAX), INNER / LEFT / RIGHT / FULL OUTER JOIN (up to 32 tables), LIMIT, plus INSERT, UPDATE, DELETE, and transactions.

Not yet supported: HAVING, ORDER BY, WITH (CTEs), window functions, and correlated subqueries. See SQL reference for the full status.

7

Vector search.

Vector data lives on its own endpoint, separate from rows. You store one embedding per row (linked by the row's primary key) and then run top-k similarity search against the query embedding.

save the embedding (cURL only - SDK examples below)
POST /v1/tenants/:t/vector/:table/put
# Save an embedding for the order. dim + metric are set per-call;
# the first put locks them in for the table.
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/vector/shop.orders/put" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id":        "01JTRX9KQ3YH8K2WMX0F5JZAB7",
    "embedding": [0.12, -0.04, 0.91, 0.33, -0.18, 0.05, 0.42, -0.27],
    "dim":       8,
    "metric":    "cosine"
  }'
search
POST /v1/tenants/:t/vector/:table/topk
# Find the 10 orders whose embeddings are closest to a query vector.
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/vector/shop.orders/topk" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "query":  [0.10, -0.05, 0.88, 0.30, -0.20, 0.07, 0.40, -0.25],
    "k":      10,
    "dim":    8,
    "metric": "cosine"
  }'

Recall and latency are tunable. See Vector reference for index choice (HNSW vs IVF), mode=fast vs mode=high_recall, and metadata filtering.

8

Full-text search.

Same pattern as vectors: full-text data lives on its own endpoint. You index the text once (linked to the row's primary key as doc_id), then search. mode=bm25 ranks hits by relevance (the same algorithm Elasticsearch and Lucene use).

index the text (cURL only - SDK examples below)
POST /v1/tenants/:t/fts/:table/:field
# Index the text under (table, field, doc_id). doc_id = the row's PK.
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/fts/shop.orders/notes" \
  -H "Authorization: Bearer $OC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "doc_id": "01JTRX9KQ3YH8K2WMX0F5JZAB7",
    "text":   "rush delivery, signed by recipient"
  }'
search
GET /v1/tenants/:t/fts/:table/:field
# Then search.
curl "https://$OC_HOST/v1/tenants/$OC_TENANT/fts/shop.orders/notes?q=rush+delivery&mode=bm25&k=10" \
  -H "Authorization: Bearer $OC_TOKEN"

Other modes: mode=boolean (every term must match, no ranking), mode=phrase (exact phrase). See Full-text reference for fuzzy search, highlights, and facets.

9

Walk a graph.

The customer column links every order to a customer. Any column you'd later use as a graph edge needs a [[relations]] block on the schema (we'll add one in Insert → graph). Then walking is one call:

GET /v1/tenants/:t/graph/:schema/neighbors
curl "https://$OC_HOST/v1/tenants/$OC_TENANT/graph/shop.orders/neighbors?rel=customer&pk=01JTRX1H4Q9P0N2WMX0F5JZ001" \
  -H "Authorization: Bearer $OC_TOKEN"

More than one hop? See Graph reference for BFS, shortest path, PageRank, and community detection.

Where to go next.