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.

Base URL
https://basecomp.io/api/v1

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.

Example request
curl https://basecomp.io/api/v1/private/me \ -H "Authorization: Bearer sk_your_api_key"

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.

List response shape
{ "data": [ /* ... */ ], "meta": { "perPage": 25, "nextCursor": "eyJpZCI6...", "prevCursor": null, "hasMore": true } }

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.

Error shape
{ "error": { "message": "The given data was invalid.", "code": "VALIDATION_ERROR", "details": { "validationErrors": { "fulfillment_status": ["..."] } } } }

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.
GET /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.
Request
curl "https://basecomp.io/api/v1/private/winners?fulfillment_status=shipped&limit=25" \ -H "Authorization: Bearer sk_your_api_key"
Response
{ "data": [ { "id": "win_abc123", "status": "claimed", "type": "instant_win", "fulfillmentStatus": "shipped", "prize": { "id": "prz_...", "name": "PlayStation 5" }, "competition": { "id": "raf_...", "title": "..." }, "customer": { "id": "cus_...", "email": "...", "name": "..." } } ], "meta": { "perPage": 25, "nextCursor": "eyJ...", "prevCursor": null, "hasMore": true } }
GET /api/v1/private/winners/{id} API key 120 requests / minute

Get winner

Fetch a single winner by id, scoped to your store.

Request
curl https://basecomp.io/api/v1/private/winners/win_abc123 \ -H "Authorization: Bearer sk_your_api_key"
PATCH /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.
Request
curl -X PATCH https://basecomp.io/api/v1/private/winners/win_abc123 \ -H "Authorization: Bearer sk_your_api_key" \ -H "Content-Type: application/json" \ -d '{ "fulfillment_status": "shipped", "tracking_number": "AB123456789GB", "tracking_url": "https://royalmail.com/track/AB123456789GB" }'
Response
{ "data": { "id": "win_abc123", "fulfillmentStatus": "shipped", "trackingNumber": "AB123456789GB", "trackingUrl": "https://royalmail.com/track/AB123456789GB", "supplierOrderNumber": "CC-998877", "fulfillmentNotes": null, "sentToSupplierAt": null, "unfillableReason": null, "unfillableAt": null, "updatedAt": "2026-06-26T12:30:00+00:00" }, "meta": { "emailSent": true } }
GET /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.
Request
curl "https://basecomp.io/api/v1/private/orders?status=completed" \ -H "Authorization: Bearer sk_your_api_key"
GET /api/v1/private/orders/{id} API key 120 requests / minute

Get order

Fetch a single order by id, scoped to your store.

GET /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.
Request
curl "https://basecomp.io/api/v1/private/[email protected]" \ -H "Authorization: Bearer sk_your_api_key"
GET /api/v1/private/customers/{id} API key 120 requests / minute

Get customer

Fetch a single customer by id, scoped to your store.

GET /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.
Request
curl "https://basecomp.io/api/v1/private/competitions?status=active" \ -H "Authorization: Bearer sk_your_api_key"
GET /api/v1/private/competitions/{id} API key 120 requests / minute

Get competition

Fetch a single competition by id, scoped to your store.

Create your free account