Skip to main content

Conventions

These hold across every module; a module page calls out exceptions.

Base URL and versioning​

https://api.naturali.ai/v1. The API is versioned in the path; within a version, changes are additive — new fields, new routes, new enum values — so a client should ignore what it does not recognise.

Resources that belong to a project live under /v1/projects/{project_id}/…. Account-level ones — your user, API keys, billing — live directly under /v1.

Fields and IDs​

Wire casing is snake_case (project_id, created_at). Timestamps are ISO 8601 date-times.

Public IDs are prefixed per resource — proj_, agent_, tool_, ses_, … — so an ID says what it names. Treat the rest as opaque.

Pagination​

Every list endpoint is paginated, in one of two styles. Each operation's page in the API Reference says which.

StyleRequestResponseEnd of the list
Offset — most project resourceslimit, offset{ data, total, limit, offset }offset + data.length reaches total
Cursor — account resources, channels, webhooks, the marketplace, activitylimit, cursor{ data, next_cursor }next_cursor is null

A cursor is opaque: pass back the next_cursor you were given, never one you built.

naturali list-agents \
--project-id proj_V1StGXR8Z5jdHi6B \
--limit 50 \
--offset 50

Idempotency​

Where a duplicate would be expensive, a mutating POST takes an idempotency_key in its body: the first request under a key does the work, a repeat returns that same result. It is on creating a project, connecting a channel and starting an orchestration run, not on every POST — a module page says so where it applies.