Skip to content

Making Requests ​

This page covers the conventions and patterns you need to know when interacting with the Chainabit API: base URL, headers, response format, pagination, error handling, and idempotency.


Base URL ​

All endpoints are relative to:

https://api.chainabit.com/api/v1

For example, the AI sessions endpoint resolves to {API_URL}/api/v1/ai/sessions.


Environment Variables ​

Set these variables before running any example on this page:

bash
export BASE_URL="https://api.chainabit.com/api/v1"
export TOKEN="your-access-token"

Required Headers ​

Every request should include:

HeaderValueRequired
Content-Typeapplication/jsonFor POST, PUT, and PATCH requests
AuthorizationBearer <accessToken>For all authenticated endpoints

Response Envelope ​

Every API response follows a consistent envelope structure:

json
{
  "data": { ... },
  "meta": { ... },
  "error": null
}
FieldDescription
dataThe requested resource or result. null when an error occurs.
metaAdditional metadata such as pagination info. null when not applicable.
errorError details. null when the request succeeds.

For a deeper explanation of the envelope design, see Response Envelope.

Successful Response ​

json
{
  "data": {
    "id": "c9f8e7d6-5432-10fe-dcba-0987654321fe",
    "title": "Research Assistant",
    "status": "active"
  },
  "meta": null,
  "error": null
}

Error Response ​

json
{
  "data": null,
  "meta": null,
  "error": {
    "statusCode": 404,
    "message": "Chain not found",
    "code": "NOT_FOUND"
  }
}

Pagination ​

List endpoints support offset-based pagination with two query parameters:

ParameterDefaultDescription
limit20Number of items to return (max varies by endpoint).
offset0Number of items to skip.

Example ​

bash
curl "https://api.chainabit.com/api/v1/ai/sessions?limit=10&offset=20" \
  -H "Authorization: Bearer $TOKEN"
js
const response = await fetch(
  `${BASE_URL}/ai/sessions?limit=10&offset=20`,
  {
    headers: { Authorization: `Bearer ${TOKEN}` },
  }
);
const { data, meta } = await response.json();
python
import requests

response = requests.get(
    f"{BASE_URL}/ai/sessions",
    params={"limit": 10, "offset": 20},
    headers={"Authorization": f"Bearer {TOKEN}"},
)
result = response.json()
data, meta = result["data"], result["meta"]
txt
Open AI → GET List Sessions
Add query params: limit=10, offset=20

Response

json
{
  "data": [
    { "id": "...", "title": "Developer Pipeline" },
    { "id": "...", "title": "Research Assistant" }
  ],
  "meta": {
    "total": 42,
    "limit": 10,
    "offset": 20
  },
  "error": null
}

Use meta.total to calculate the number of pages or determine whether more items exist. For full pagination details, see Pagination.


Error Handling ​

Always check the error field in the response. Common HTTP status codes:

StatusMeaning
400Bad request -- invalid or missing parameters.
401Unauthorized -- missing or expired token.
403Forbidden -- insufficient permissions or captcha failure.
404Not found -- the resource does not exist.
409Conflict -- duplicate resource or idempotency key collision.
422Unprocessable entity -- validation error.
429Too many requests -- rate limit exceeded.
500Internal server error.

Rate Limiting ​

When you exceed the rate limit, the API returns 429 Too Many Requests with a Retry-After header indicating how many seconds to wait:

json
{
  "data": null,
  "meta": null,
  "error": {
    "statusCode": 429,
    "message": "Rate limit exceeded. Try again in 30 seconds.",
    "code": "RATE_LIMITED"
  }
}

Best practice: implement exponential backoff and respect the Retry-After header. For rate limit tiers and quotas, see Rate Limiting.

For the full error code reference, see Errors.


Idempotency ​

Some mutating endpoints (such as creating transactions or logging events) accept an Idempotency-Key header. Sending the same idempotency key for the same endpoint returns the original response without creating a duplicate resource.

bash
curl -X POST https://api.chainabit.com/api/v1/ai/sessions \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
  -d '{"title": "Pipeline session"}'
js
const response = await fetch(`${BASE_URL}/ai/sessions`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${TOKEN}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': crypto.randomUUID(),
  },
  body: JSON.stringify({ title: 'Pipeline session' }),
});
const { data } = await response.json();
python
import requests
import uuid

response = requests.post(
    f"{BASE_URL}/ai/sessions",
    headers={
        "Authorization": f"Bearer {TOKEN}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={"title": "Pipeline session"},
)
data = response.json()["data"]
txt
Open AI → POST Create Session
Set Idempotency-Key header to {{$randomUUID}}

Guidelines:

  • Use a UUID v4 as the idempotency key.
  • Keys are scoped to your account and the specific endpoint.
  • Keys expire after 24 hours. After that, the same key can be reused.
  • If the original request is still being processed, a subsequent request with the same key returns 409 Conflict.

Full Request-Response Example ​

Here is a complete example that creates an AI session, handles potential errors, and demonstrates proper header usage:

bash
curl -s -w "\nHTTP_STATUS:%{http_code}" \
  -X POST https://api.chainabit.com/api/v1/ai/sessions \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -d '{
    "title": "Research Assistant"
  }'

Success -- 201 Created

json
{
  "data": {
    "id": "sess_01HQ3K5N2P4R7T9V1X3Z5A7C9E",
    "title": "Research Assistant",
    "status": "active",
    "createdAt": "2026-05-04T20:00:00.000Z"
  },
  "meta": null,
  "error": null
}

Validation error -- 422 Unprocessable Entity

json
{
  "data": null,
  "meta": null,
  "error": {
    "statusCode": 422,
    "message": "Validation failed",
    "code": "VALIDATION_ERROR",
    "details": [
      {
        "field": "title",
        "message": "title must be a string and is required"
      }
    ]
  }
}

Token expired -- 401 Unauthorized

json
{
  "data": null,
  "meta": null,
  "error": {
    "statusCode": 401,
    "message": "Unauthorized",
    "code": "UNAUTHORIZED"
  }
}

When you receive a 401, refresh your token (see Authentication) and retry the request.


Next Steps ​

Built with purpose.