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.

FieldTypeDescription
winners:readscope · optionalList and fetch winners.
winners:writescope · optionalUpdate a winner's prize fulfilment status.
orders:readscope · optionalList and fetch orders.
customers:readscope · optionalList and fetch customers.
competitions:readscope · optionalList and fetch competitions.
*scope · optionalFull 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

FieldTypeDescription
UNAUTHENTICATED401 · optionalMissing or invalid API key.
INSUFFICIENT_SCOPE403 · optionalThe key lacks the scope this endpoint requires.
NOT_FOUND404 · optionalThe resource does not exist, or does not belong to your store.
VALIDATION_ERROR422 · optionalThe request body failed validation. See details.validationErrors.
WINNER_NOT_FULFILLABLE422 · optionalThe winner cannot be fulfilled (not claimed, converted to cash/credit, or has no shipping address).
RATE_LIMITED429 · optionalToo many requests.
GET/api/v1/private/winnersAPI key120 requests / minute

List winners

Returns the store's winners, newest first, each with its prize, competition and customer. Cursor-paginated.

Query parameters

FieldTypeDescription
fulfillment_statusstring · optionalFilter by pending, processing, shipped, delivered or unfillable.
statusstring · optionalFilter by winner status (e.g. won, claimed).
typestring · optionalFilter by instant_win or main_prize.
sincestring · optionalOnly winners created on or after this date.
limitinteger · optionalPage size, 1-100 (default 25).
cursorstring · optionalmeta.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 key120 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 key120 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

FieldTypeDescription
fulfillment_statusstring · optionalOne of: processing, shipped, delivered, unfillable. Required unless supplier_order_number is supplied, in which case the winner is marked shipped automatically.
supplier_order_numberstring · optionalThe supplier's own order reference. Recording one (with no fulfillment_status) marks the prize shipped and emails the winner.
tracking_numberstring · optionalCarrier tracking number.
tracking_urlstring · optionalCarrier tracking URL.
notesstring · optionalInternal fulfilment note.
unfillable_reasonstring · optionalRequired when fulfillment_status is unfillable.
notify_customerboolean · optionalWhether 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/ordersAPI key120 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

FieldTypeDescription
statusstring · optionalFilter by order status.
sincestring · optionalOnly orders created on or after this date.
limitinteger · optionalPage size, 1-100 (default 25).
cursorstring · optionalmeta.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 key120 requests / minute

Get order

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

GET/api/v1/private/customersAPI key120 requests / minute

List customers

Returns the store's customers, newest first. Cursor-paginated.

Query parameters

FieldTypeDescription
statusstring · optionalFilter by customer status.
emailstring · optionalFilter by exact email address.
sincestring · optionalOnly customers created on or after this date.
limitinteger · optionalPage size, 1-100 (default 25).
cursorstring · optionalmeta.nextCursor from the previous page.
Request
curl "https://basecomp.io/api/v1/private/customers?email=jane@example.com" \ -H "Authorization: Bearer sk_your_api_key"
GET/api/v1/private/customers/{id}API key120 requests / minute

Get customer

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

GET/api/v1/private/competitionsAPI key120 requests / minute

List competitions

Returns the store's competitions, newest first. Cursor-paginated.

Query parameters

FieldTypeDescription
statusstring · optionalFilter by competition status.
sincestring · optionalOnly competitions created on or after this date.
limitinteger · optionalPage size, 1-100 (default 25).
cursorstring · optionalmeta.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 key120 requests / minute

Get competition

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

Create your free account