Skip to main content
Version: 2026-05

Get a campaign

GET /campaigns/:id

Description

Retrieves a single campaign by its id. A campaign is the gift collection offered on a send: the products a recipient can be given, and the configuration that drives how a gift request built against it behaves.

The campaign is returned as a single JSON object that includes its product, variant, stock-level, and warehouse details inline, so one call gives you everything, with no follow-up requests and no include parameter.

When to use

Use this endpoint when you already know which campaign you want, for example to show its products before creating a gift request, or to check current stock. To discover campaigns or to find an id in the first place, use List campaigns; the list returns the identical per-campaign shape, so anything documented here applies to each item there too.

Parameters

Path

id (string · uuid · required) is the campaign to retrieve. An id that matches no campaign in your account returns 404, not an empty body.

Headers

AndOpen-API-Version (string · required) is the API version this request targets. Always send 2026-05. Requests authenticate with a bearer token; see Authentication for how to present it and Environments for the regional base URL to send it to.

Worked examples

The cURL version is the raw HTTP call; the JavaScript, Python, and Ruby versions are idiomatic equivalents. Replace the path id with the campaign you want.

curl -X GET "https://api.andopen.co/campaigns/a1b2c3d4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer <api_key>" \
-H "AndOpen-API-Version: 2026-05"

Response shape

A successful call returns 200 OK with the campaign as a flat top-level JSON object. The gift-collection associations are returned inline rather than as references you have to fetch separately.

FieldDescription
status (string · required)The public-facing status, one of available, archived. Internal hidden states are collapsed to available for API consumers.
description (string · required · nullable)The long-form description. Always present as a key, but null when none has been set.
archived_at (string · date-time · required · nullable)When the campaign was archived, or null if it has not been.
web_url (string · uri · required)The campaign's page in the &Open web app, on your organization's own domain. It needs a signed-in session, so it's a link for your own users.
offering (object · required)How the campaign puts its gifts to a recipient. offering.selection_mode (string · required) is one of all, one, and offering.visible_at_redemption (boolean · required) says whether the recipient sees the gifts when they redeem.
owner (object · required · nullable)The user who owns the campaign, embedded as an { id, name, email } summary. Read their team and budget with Get a user.
supported_country_codes (array · required)The ISO 3166-1 alpha-2 countries the campaign can ship to. Check a destination against it before you create a gift request.
shipping_from (array · required)The countries it ships from: its warehouse's country, or one entry per On-Demand vendor.
default_email_message (object · required)The campaign's default invitation copy. Its subject and body are each null until the campaign sets them, and a send's own email_message overrides both.
gift_request_statistics (object · required)A roll-up of the campaign's sends by public status, as total, redeemed, dispatched, and delivered counts.
products (array · required)The products on offer, returned inline. products.variants (array · required) holds each product's variants, and products.variants.stock_levels (array · required) holds each variant's stock levels down to the warehouse. Products also carry an images array, and variants a price.
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"name": "Q2 Customer Appreciation",
"description": "Send a thank-you gift to our top accounts.",
"status": "available",
"web_url": "https://acme.andopen.co/sender/gift-history/campaigns/a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"default_email_message": {
"subject": "A gift for you",
"body": "Thanks for being a valued customer. Enjoy your gift!"
},
"owner": {
"id": "9f8e7d6c-5b4a-3210-fedc-ba9876543210",
"name": "Dana Okafor",
"email": "dana@acme.example"
},
"supported_country_codes": [
"IE",
"GB",
"US"
],
"shipping_from": [
"IE"
],
"gift_request_statistics": {
"total": 120,
"redeemed": 84,
"dispatched": 12,
"delivered": 70
},
"offering": {
"selection_mode": "one",
"visible_at_redemption": true
},
"archived_at": null,
"products": [
{
"id": "b2c3d4e5-f6a7-8901-bcde-f01234567890",
"name": "Leather Notebook",
"enabled": true,
"images": [
{
"name": "leather-notebook.jpg",
"url": "https://files.andopen.co/rndd63mwgj94j2vf3v2ngnye0hkn",
"urls": {
"thumbnail": "https://files.andopen.co/vw2mvwevyqxh98l7esf67nvunr4h",
"large": "https://files.andopen.co/mz4rc8kx1nvq7j93wtf5bd2hs0yl",
"large_wide": "https://files.andopen.co/q7pz3n8htv2ke0d5rjw94flxs6cb"
}
}
],
"variants": [
{
"id": "c3d4e5f6-a7b8-9012-cdef-012345678901",
"name": "Medium / Black",
"sku": "NB-LTHR-MED-BLK",
"enabled": true,
"position": 1,
"price": {
"amount": 1500,
"currency": "EUR"
},
"stock_levels": [
{
"id": "d4e5f6a7-b8c9-0123-defa-123456789012",
"quantity": 42,
"warehouse": {
"id": "e5f6a7b8-c901-2345-efab-234567890123",
"name": "EU Central — Frankfurt",
"enabled": true,
"created_at": "2026-04-16T10:30:00.000Z",
"updated_at": "2026-04-16T10:30:00.000Z"
},
"created_at": "2026-04-16T10:30:00.000Z",
"updated_at": "2026-04-16T10:30:00.000Z"
}
],
"created_at": "2026-04-16T10:30:00.000Z",
"updated_at": "2026-04-16T10:30:00.000Z"
}
],
"created_at": "2026-04-16T10:30:00.000Z",
"updated_at": "2026-04-16T10:30:00.000Z"
}
],
"created_at": "2026-04-16T10:30:00.000Z",
"updated_at": "2026-04-16T10:30:00.000Z"
}

Per-field notes

  • The gift collection is filtered to the campaign's warehouse. When a campaign has a fulfillment warehouse, products, variants, and stock levels with no stock at that warehouse are omitted. Each variant then exposes a single stock level scoped to that warehouse. Campaigns without a warehouse (for example voucher- or charity-only campaigns) return the gift collection unfiltered, and a variant may then carry several stock_levels.
  • stock_levels[].quantity is the in-stock figure. It's the net units fulfillable for the variant at that warehouse. When pending stock is enabled it nets expected inflow against backorders; otherwise it's units on hand. It's always positive for a stock level that appears in a response, so it's the number that decides whether a variant is offerable.
  • variants are ordered by position ascending. Render them in array order to match how the campaign is configured.
  • name and sku can be null on a variant. A single-variant product often has no own variant name; treat null as "inherits the product name".
  • variants[].price is a money object: an integer amount in the smallest unit of the currency, so { "amount": 1500, "currency": "EUR" } is €15.00. It is the gift's value on this campaign, and it is what a send draws against the sender's budget.
  • products[].images and each line item's images carry three pre-generated sizes under urls, alongside the full-resolution url. Each size is a separate file, so read the one you want from urls and don't try to derive it from url.
  • supported_country_codes and shipping_from are empty arrays, never null, when the campaign has no fulfillment warehouse or no resolvable origin. An empty supported_country_codes means the campaign can't tell you where it ships, so validate the address on the send instead.
  • The campaign's offering is its configured mode, and a send from it can still differ. Voucher and cause gifts always let the recipient choose one, whatever the campaign says. A gift request's own offering is what actually happened on that send, so read it from Get a gift request when the answer matters.
  • gift_request_statistics counts every send on the campaign, archived campaigns included, and reads 0 across the board for a campaign with no sends. Its delivered count includes partially fulfilled requests, matching the delivered status on a gift request.
  • Server-set fields are read-only. id, status, archived_at, gift_request_statistics, and the timestamps are assigned by &Open; this endpoint only reads them.

Error cases

Every failure uses the shared error model: a top-level errors array of objects carrying type, code, message, and (for field-level problems) param. See Errors for the full type/code taxonomy and how to handle each category; the codes below are the ones this endpoint produces.

StatusMeaning
400The request is malformed or violates a precondition. Typical triggers are a missing or unsupported `AndOpen-API-Version` header, a request body that is not valid JSON, or pagination parameters that fail server-side validation (`limit` non-numeric or non-positive, `after` referencing a record that does not exist).
401Authentication failed: missing or invalid bearer token.
403Authorized but not permitted to access this resource.
404The requested resource does not exist.
429Too many requests. Rate limit exceeded.
500Internal server error.
503Service unavailable. The account may be under maintenance. Check the `Retry-After` header.

Every error carries a type, one of: validation_error, authentication_error, authorization_error, not_found_error, rate_limit_error, api_error.

The ones you'll meet in practice:

  • 404 not_found_error: no campaign with that id exists in your account (not_found).
  • 400 api_error: unsupported_api_version when the AndOpen-API-Version header is missing or unsupported (returned before authentication).
  • 401 authentication_error: the bearer token is missing, invalid, or expired (unauthorized).
  • 403 authorization_error: the token is valid but not permitted to read this campaign (forbidden).
  • 429 rate_limit_error: too many requests; back off and retry (rate_limited). The RateLimit-* response headers tell you the budget and reset time.