Developers
API Documentation
Build integrations with the Basecomp API. Update prize fulfilment, sync data, and automate your workflows.
Introduction
The Basecomp API is organised around REST. It uses predictable resource-oriented URLs, accepts and returns JSON, and uses standard HTTP response codes and verbs. Field names are camelCase; requests may send either camelCase or snake_case.
Base URL
All requests are made to the following base URL, over HTTPS.
Authentication
Authenticate every request with a secret API key in the Authorization header as a Bearer token. Create and manage keys in your dashboard under Settings → API Keys. A key is shown only once at creation, so store it securely and never expose it in client-side code.
A missing or invalid key returns 401.
Scopes
Each key carries a set of scopes that limit what it can do. Give a third party (e.g. a supplier automating dispatch in Zapier) a fulfilment-only key so a leak can never touch the rest of your store. A request whose key lacks the required scope returns 403 with code INSUFFICIENT_SCOPE.
| Field | Type | Description |
|---|---|---|
winners:read
|
scope · optional | List and fetch winners. |
winners:write
|
scope · optional | Update a winner's prize fulfilment status. |
orders:read
|
scope · optional | List and fetch orders. |
customers:read
|
scope · optional | List and fetch customers. |
competitions:read
|
scope · optional | List and fetch competitions. |
*
|
scope · optional | Full access to every endpoint. Use only for your own server-side integrations. |
Pagination
List endpoints return newest-first and use cursor pagination. Pass ?limit (1-100, default 25) to size each page, and ?cursor with the meta.nextCursor value to fetch the next page. meta.hasMore is false on the last page. Cursors are stable as new records are created, which makes them safe for polling.
Rate limits
Authenticated endpoints are limited to 120 requests per minute, per key. Exceeding the limit returns 429 with code RATE_LIMITED.
Errors
The API uses conventional HTTP status codes: 2xx for success, 4xx for a problem with the request, and 5xx for a server error. Every error returns the same JSON shape with a stable, machine-readable code.
Common codes
| Field | Type | Description |
|---|---|---|
UNAUTHENTICATED
|
401 · optional | Missing or invalid API key. |
INSUFFICIENT_SCOPE
|
403 · optional | The key lacks the scope this endpoint requires. |
NOT_FOUND
|
404 · optional | The resource does not exist, or does not belong to your store. |
VALIDATION_ERROR
|
422 · optional | The request body failed validation. See details.validationErrors. |
WINNER_NOT_FULFILLABLE
|
422 · optional | The winner cannot be fulfilled (not claimed, converted to cash/credit, or has no shipping address). |
RATE_LIMITED
|
429 · optional | Too many requests. |
/api/v1/private/winners
API key
120 requests / minute
List winners
Returns the store's winners, newest first, each with its prize, competition and customer. Cursor-paginated.
Query parameters
| Field | Type | Description |
|---|---|---|
fulfillment_status
|
string · optional | Filter by pending, processing, shipped, delivered or unfillable. |
status
|
string · optional | Filter by winner status (e.g. won, claimed). |
type
|
string · optional | Filter by instant_win or main_prize. |
since
|
string · optional | Only winners created on or after this date. |
limit
|
integer · optional | Page size, 1-100 (default 25). |
cursor
|
string · optional | meta.nextCursor from the previous page. |
/api/v1/private/winners/{id}
API key
120 requests / minute
Get winner
Fetch a single winner by id, scoped to your store.
/api/v1/private/winners/{id}
API key
120 requests / minute
Update fulfilment status
Update a winner's prize fulfilment status. The most common use is marking a claim as shipped from a supplier's system: when the status becomes shipped, the winner is automatically emailed (once) with any tracking details, and a prize.shipped webhook fires.
The {id} is the winner id (win_...) from your prize.claimed webhook or supplier export. The winner must belong to your store, and be a claimed, non-converted physical prize with a shipping address.
Body
| Field | Type | Description |
|---|---|---|
fulfillment_status
|
string · optional | One of: processing, shipped, delivered, unfillable. Required unless supplier_order_number is supplied, in which case the winner is marked shipped automatically. |
supplier_order_number
|
string · optional | The supplier's own order reference. Recording one (with no fulfillment_status) marks the prize shipped and emails the winner. |
tracking_number
|
string · optional | Carrier tracking number. |
tracking_url
|
string · optional | Carrier tracking URL. |
notes
|
string · optional | Internal fulfilment note. |
unfillable_reason
|
string · optional | Required when fulfillment_status is unfillable. |
notify_customer
|
boolean · optional | Whether to email the winner when shipping. Defaults to true. Does not affect the webhook. |
/api/v1/private/orders
API key
120 requests / minute
List orders
Returns the store's orders, newest first. Cursor-paginated. Amounts are integers in the smallest currency unit (e.g. pence).
Query parameters
| Field | Type | Description |
|---|---|---|
status
|
string · optional | Filter by order status. |
since
|
string · optional | Only orders created on or after this date. |
limit
|
integer · optional | Page size, 1-100 (default 25). |
cursor
|
string · optional | meta.nextCursor from the previous page. |
/api/v1/private/orders/{id}
API key
120 requests / minute
Get order
Fetch a single order by id, scoped to your store.
/api/v1/private/customers
API key
120 requests / minute
List customers
Returns the store's customers, newest first. Cursor-paginated.
Query parameters
| Field | Type | Description |
|---|---|---|
status
|
string · optional | Filter by customer status. |
email
|
string · optional | Filter by exact email address. |
since
|
string · optional | Only customers created on or after this date. |
limit
|
integer · optional | Page size, 1-100 (default 25). |
cursor
|
string · optional | meta.nextCursor from the previous page. |
/api/v1/private/customers/{id}
API key
120 requests / minute
Get customer
Fetch a single customer by id, scoped to your store.
/api/v1/private/competitions
API key
120 requests / minute
List competitions
Returns the store's competitions, newest first. Cursor-paginated.
Query parameters
| Field | Type | Description |
|---|---|---|
status
|
string · optional | Filter by competition status. |
since
|
string · optional | Only competitions created on or after this date. |
limit
|
integer · optional | Page size, 1-100 (default 25). |
cursor
|
string · optional | meta.nextCursor from the previous page. |
/api/v1/private/competitions/{id}
API key
120 requests / minute
Get competition
Fetch a single competition by id, scoped to your store.