-
Notifications
You must be signed in to change notification settings - Fork 2
REST API
Matt Dula edited this page Apr 18, 2026
·
1 revision
Nakatomi's REST surface is fully documented by its OpenAPI spec — it's the canonical reference because it stays in sync with the code automatically.
When Nakatomi is running:
-
Swagger UI:
GET /docs -
ReDoc:
GET /redoc -
Raw OpenAPI:
GET /openapi.json
Import /openapi.json into:
- Postman / Insomnia — full collection, one click
- ChatGPT Custom GPT Actions — becomes the tool list
- Your IDE's OpenAPI plugin
- Code generators (openapi-generator, etc.)
| Prefix | Purpose | Wiki link |
|---|---|---|
/auth |
signup, login, /me
|
Authentication |
/workspace |
workspace settings, members, API keys | Authentication |
/contacts |
CRUD + bulk upsert + search | — |
/companies |
CRUD + bulk upsert + search | — |
/pipelines |
pipelines + stages | — |
/deals |
CRUD, status transitions | — |
/activities |
call / meeting / email_log entries | — |
/notes |
markdown notes on any entity | — |
/tasks |
assignable tasks with due dates | — |
/relationships |
typed graph edges + neighbors BFS | — |
/timeline |
append-only event stream | — |
/webhooks |
subscriptions + delivery log | Webhooks |
/files |
upload / download / list | — |
/memory |
recall / link / trace / inbound webhook | Memory-Connectors |
/ingest |
normalize external data into CRM rows | Ingest |
/custom-fields |
workspace-scoped field registry | Custom-Fields |
/export + /import
|
portable JSON dumps | Export-Import |
/schema, /llms.txt, /.well-known/agent.json
|
discovery | — |
/health |
liveness | — |
/dashboard |
optional local UI | Dashboard |
-
Auth:
Authorization: Bearer nk_<key>(API keys) orBearer <jwt> + X-Workspace: <slug>(user JWTs). See Authentication. -
Pagination: every list endpoint returns
{"items": [...], "next_cursor": "...", "count": N}. Pass?limit=(1-500) and?cursor=<next_cursor>to page. -
Idempotency: any mutating request can carry an
Idempotency-Keyheader. Replays return the original response if the body matches. -
Soft delete:
DELETE /contacts/{id}soft-deletes by default;?hard=trueto bypass. -
Bulk upsert:
POST /contacts/bulk_upsert+/companies/bulk_upsert. Matches onexternal_idfirst, then email/domain. -
Filtering: each list endpoint accepts resource-specific query params
(e.g.
?email=,?tag=,?status=). See Swagger for the per-endpoint catalog.
If an API key carries a rate_limit_per_minute, over-limit requests get
429 Too Many Requests with a Retry-After header. See Rate-Limiting.
Shape:
{"error": "human-readable string"}Status codes:
-
400— validation error (bad input shape) -
401— missing or invalid token -
403— authenticated but not allowed (role check) -
404— resource not found -
409— conflict (e.g. unique-constraint hit, idempotency-key reused with a different body) -
422— semantic validation (bad enum value, unsupported schema_version) -
429— rate limit exceeded -
5xx— bug; see logs
KEY=nk_abc_123
BASE=http://localhost:8000
# List contacts
curl -s $BASE/contacts -H "Authorization: Bearer $KEY"
# Create a contact
curl -s -X POST $BASE/contacts \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"first_name":"Ada","email":"ada@example.com","external_id":"ada-1"}'
# Bulk upsert
curl -s -X POST $BASE/contacts/bulk_upsert \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '[{"external_id":"a1","email":"a@ex.com"},{"external_id":"a2","email":"b@ex.com"}]'
# Move a deal
curl -s -X PATCH $BASE/deals/<id> \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{"stage_id":"<won-stage-id>","status":"won"}'
# Fetch timeline for an entity
curl -s "$BASE/timeline/deal/<id>?limit=100" -H "Authorization: Bearer $KEY"For richer examples see MCP-Tools (the MCP tool set has the same shapes).
Repository · Issues · MIT licensed · maintained by Matt Dula