Calling the API
The request and response format for the action API, with curl examples and error codes.
Calling the API
The action API exposes every workspace action as its own endpoint under
/api/v1/trpc. Each endpoint is named <router>.<procedure> (for example
leads.getAll, tasks.create, invoices.update).
https://<your-workspace-domain>/api/v1/trpc/<router>.<procedure>
- Reads are
GET. - Writes are
POST.
The input and output are wrapped in a small JSON envelope ({ "json": ... })
so that richer types (dates, etc.) round-trip cleanly.
Reads (GET)
Pass the input as a URL-encoded input query parameter wrapping the value in
{"json": ...}. Omit it entirely for endpoints that take no input.
# No input
curl "https://<your-workspace-domain>/api/v1/trpc/leads.getAll" \
-H "Authorization: Bearer sk_xxx"
# With input
curl -G "https://<your-workspace-domain>/api/v1/trpc/leads.getById" \
-H "Authorization: Bearer sk_xxx" \
--data-urlencode 'input={"json":{"id":"lead_123"}}'
Writes (POST)
Send the input as a JSON body wrapping the value in {"json": ...}:
curl -X POST "https://<your-workspace-domain>/api/v1/trpc/leads.create" \
-H "Authorization: Bearer sk_xxx" \
-H "Content-Type: application/json" \
-d '{"json":{"name":"Acme Co","phone":"+15551234567"}}'
Response shape
On success the payload is under result.data.json:
{ "result": { "data": { "json": { "id": "lead_123", "name": "Acme Co" } } } }
On error you get a tRPC error envelope, and the HTTP status reflects the failure:
{
"error": {
"json": {
"message": "This API key is missing the \"invoices.create\" scope.",
"data": { "code": "FORBIDDEN", "httpStatus": 403 }
}
}
}
Status codes
| Status | Meaning |
|---|---|
200 | Success. |
401 | Missing / malformed Authorization header, or an invalid, expired, or revoked key. |
403 | The workspace is not on the max tier, the endpoint is not exposed to the API, or the key lacks the required scope. |
400 | Input failed validation (the error data includes the field issues). |
404 | The referenced record does not exist in this workspace. |
500 | Unexpected server error. |
Finding endpoint names and inputs
Endpoint names mirror the app's routers, and each endpoint takes the same input
the app uses. The Developer page lists your keys and their scopes; the
required scope for any endpoint is "<resource>.<action>", which a 403 will
also tell you. See Scopes & permissions for the resource list and
how actions map.
Notes
- The API key is the only auth - never send cookies.
- One action per request; the endpoint does not require client-side batching.
- For the plain-REST leads surface and pagination, see Pagination.