Overview
The Obeya Cloud API is built on tRPC, providing end-to-end type-safe access to all platform features. For clients that cannot use tRPC directly, a REST-compatible HTTP interface is also available.
Base URL
All API requests are made to your organization’s subdomain:
https://YOUR_ORG.obeya.cloud/api
For tRPC procedure calls:
https://YOUR_ORG.obeya.cloud/api/trpc/PROCEDURE_NAME
Authentication
Authenticate API requests using a Bearer token in the Authorization header:
curl https://acme.obeya.cloud/api/trpc/items.list \
-H "Authorization: Bearer oby_pat_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"json": {"boardId": "brd_01HXK5..."}}'
Generate API tokens from Settings > API Tokens in the Obeya Cloud dashboard. See Authentication for details.
tRPC Queries (GET)
For read operations (queries), use GET with URL-encoded input:
# Query with input
GET /api/trpc/items.list?input={"json":{"boardId":"brd_01HXK5..."}}
tRPC Mutations (POST)
For write operations (mutations), use POST with a JSON body:
POST /api/trpc/items.create
Content-Type: application/json
{
"json": {
"boardId": "brd_01HXK5...",
"groupId": "grp_01HXK5...",
"name": "New task"
}
}
Batch Requests
tRPC supports batching multiple calls in a single HTTP request:
GET /api/trpc/boards.get,items.list?batch=1&input={"0":{"json":{"id":"brd_01HXK5..."}},"1":{"json":{"boardId":"brd_01HXK5..."}}}
All responses follow the tRPC response format:
{
"result": {
"data": {
"json": {
"id": "itm_01HXK5...",
"name": "Task name",
"boardId": "brd_01HXK5...",
"createdAt": "2026-03-19T14:30:00.000Z"
}
}
}
}
Error Responses
{
"error": {
"message": "Item not found",
"code": -32004,
"data": {
"code": "NOT_FOUND",
"httpStatus": 404,
"path": "items.get"
}
}
}
Error Codes
| HTTP Status | tRPC Code | Description |
|---|
| 400 | BAD_REQUEST | Invalid input parameters |
| 401 | UNAUTHORIZED | Missing or invalid authentication |
| 403 | FORBIDDEN | Insufficient permissions |
| 404 | NOT_FOUND | Resource does not exist |
| 409 | CONFLICT | Concurrent modification conflict |
| 429 | TOO_MANY_REQUESTS | Rate limit exceeded |
| 500 | INTERNAL_SERVER_ERROR | Unexpected server error |
Rate Limiting
API requests are rate-limited per token:
| Plan | Rate Limit |
|---|
| Free | 60 requests/minute |
| Pro | 300 requests/minute |
| Business | 1,000 requests/minute |
| Enterprise | 5,000 requests/minute |
Rate limit headers are included in every response:
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 295
X-RateLimit-Reset: 1711032060
List endpoints support cursor-based pagination:
GET /api/trpc/items.list?input={"json":{"boardId":"brd_01HXK5...","cursor":"itm_01HXK5...","limit":50}}
Response includes a nextCursor for fetching the next page:
{
"result": {
"data": {
"json": {
"items": [...],
"nextCursor": "itm_01HXK6..."
}
}
}
}
The default page size is 50 items. Maximum is 200. Use the limit parameter to adjust.
TypeScript Client
For TypeScript projects, use the tRPC client for full type safety:
import { createTRPCClient, httpBatchLink } from "@trpc/client";
import type { AppRouter } from "@obeya/api";
const client = createTRPCClient<AppRouter>({
links: [
httpBatchLink({
url: "https://acme.obeya.cloud/api/trpc",
headers: {
Authorization: "Bearer oby_pat_xxxxxxxxxxxxx",
},
}),
],
});
// Fully typed API calls
const items = await client.items.list.query({ boardId: "brd_01HXK5..." });
const newItem = await client.items.create.mutate({
boardId: "brd_01HXK5...",
name: "New task",
});