On this page
REST API
REST API basics
How to call the Shipbell API: its address, keys, errors, retries and pages.
Base URL
Every endpoint lives under https://api.shipbell.app/v1. The version is part of the path, and changes within v1 only add things. The API reference lists every endpoint.
curl https://api.shipbell.app/v1/versionconst response = await fetch('https://api.shipbell.app/v1/version');
const data = await response.json();let url = URL(string: "https://api.shipbell.app/v1/version")!
let (data, response) = try await URLSession.shared.data(from: url)AuthenticationComing soon
| Caller | Headers |
|---|---|
| Your app | X-Project-Key: sb_pk_live_… and Authorization: Bearer sb_ses_…, the session from the sign-in exchange |
| Your server | Authorization: Bearer sb_sk_live_…, a secret key with the scopes the call needs |
- The API never uses cookies.
- Browsers may call it only from your project's allowed origins. CORS sends no credentials and caches preflights.
- On a project whose board is private, every read needs a session.
Requests and responses
Requests and responses are JSON with snake_case names. Times are RFC 3339 timestamps in UTC. Ids start with a prefix that names their kind, such as prj_ for a project.
Errors
application/problem+json (RFC 9457), with a stable code field your code can match on.Today an error answers with JSON that holds the status code and a message:
{ "statusCode": 404, "message": "Not Found" }Every endpoint shares these errors:
| Status | Message | When |
|---|---|---|
| 400 | Invalid request body | The body is not valid JSON |
| 404 | Not Found | No endpoint has this method and path |
| 413 | Request body is too large | The body is larger than the endpoint accepts |
| 500 | Internal server error | Something failed on our side |
Retries and idempotencyComing soon
Every POST from an app must carry an Idempotency-Key header, such as a new UUID for each request. Shipbell keeps the key with the request and its response for 24 hours:
- Sending the same key and body again returns the first response, with
Idempotent-Replayed: true. - The same key with a different body answers 422.
- The same key while the first request is still running answers 409.
PaginationComing soon
Lists use cursors. Pass limit, at most 100, and the cursor from the previous page. Each page answers {data, next_cursor}.
Rate limitsComing soon
A request over a rate limit answers 429 with a Retry-After header. Wait that long before you send it again.
OpenAPI documentComing soon
The API reference is built from the API's OpenAPI document, which will also be served at https://api.shipbell.app/v1/openapi.json.