Skip to main content
This walkthrough brings your own rows into a table, enriches them, and reads the results back. To have the agent build a table from a brief instead, follow the agent quickstart.
Building with an AI coding assistant? Download the OpenAPI spec and paste it into your tool, or install the Origami skill.

Prerequisites

  • An Origami account with at least one table set up
  • An API key (create one in Settings → API keys)
export ORIGAMI_API_KEY=og_live_your_key_here

Step 1: Find your table and its columns

List tables to find the one you want to write into. The response is the standard list envelope — objects under items, with nextCursor for paging.
curl "https://origami.chat/api/v2/tables" \
  -H "Authorization: Bearer $ORIGAMI_API_KEY"
Example response
{
  "object": "list",
  "items": [
    {
      "object": "table",
      "id": "d290f1ee-6c54-4b01-90e6-d701748f0851",
      "workspaceId": "9b7c…",
      "name": "Series A SaaS Companies",
      "leadCount": 150,
      "url": "https://origami.chat/workspace/9b7c…?table=d290f1ee…"
    }
  ],
  "nextCursor": null,
  "url": "/api/v2/tables"
}
Then read the table’s columns to get the input-column slugs — you’ll use these as row keys in the next step.
curl "https://origami.chat/api/v2/tables/TABLE_ID/columns" \
  -H "Authorization: Bearer $ORIGAMI_API_KEY"
Columns
{
  "object": "list",
  "items": [
    { "object": "column", "name": "Company Name", "slug": "company-name", "kind": "input" },
    { "object": "column", "name": "Website", "slug": "website", "kind": "input" },
    { "object": "column", "name": "CEO Email", "slug": "ceo-email", "kind": "enrichment", "autoTrigger": true }
  ],
  "nextCursor": null,
  "url": "/api/v2/tables/TABLE_ID/columns"
}
Only input columns are writable. Enrichment, score, and sequence columns are populated automatically.

Step 2: Upsert rows

v2 has one row-write primitive: upsert. Rows are keyed by input-column slug. matchColumns decides identity — a row matching an existing row on every match value updates it; a non-matching row inserts. An insert-only call is just an upsert whose rows match nothing.
curl -X POST https://origami.chat/api/v2/tables/TABLE_ID/rows/upsert \
  -H "Authorization: Bearer $ORIGAMI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "rows": [
      { "company-name": "Acme Corp", "website": "acme.com" },
      { "company-name": "Beta Inc", "website": "beta.io" }
    ],
    "matchColumns": ["website"]
  }'
The response references an enrichment run — the tracked batch of work — that you poll next.
Response
{
  "object": "enrichment_run",
  "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "batchId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "counts": { "inserted": 2, "updated": 0, "skipped": 0 }
}
Set "enrich": false to upsert without triggering enrichment. To also re-enrich rows the upsert updated, set "reenrichUpdated": true.
For safe retries, include a "batchId" (any UUID you generate) in the body, or send an Idempotency-Key header. A retry with the same batchId returns the existing run instead of writing duplicate rows.

Step 3: Poll the enrichment run

Use the run id to check progress. Keep polling until status is terminal.
curl "https://origami.chat/api/v2/enrichment-runs/RUN_ID" \
  -H "Authorization: Bearer $ORIGAMI_API_KEY"
{
  "object": "enrichment_run",
  "id": "f47ac10b-…",
  "tableId": "d290f1ee-…",
  "type": "upsert",
  "status": "running",
  "rowCount": 2,
  "enrichments": { "total": 4, "completed": 1, "pending": 3, "failed": 0 },
  "creditsUsed": 0,
  "createdAt": "2025-07-01T14:30:00Z",
  "completedAt": null
}
For upsert runs, the detail response also carries a per-row outcomes[] ledger telling you exactly which input row inserted, updated, or was skipped.

Step 4: Read the enriched rows

Pull rows from the table. Reads are free. By default cells are typed; add ?cells=flat for the simpler { slug: value } shape, or ?format=csv to download a spreadsheet.
curl "https://origami.chat/api/v2/tables/TABLE_ID/rows?cells=flat" \
  -H "Authorization: Bearer $ORIGAMI_API_KEY"
See reading data for filters, sorting, pagination, and CSV export.

What’s next

Objects and relationships

The objects the API is built from and how they connect.

Agent quickstart

Let the agent build the table from a plain-English brief.

Reading data

Filter, sort, and export your enriched rows.

Authentication

Managing API keys and project scoping.