Next Commerce

Campaigns Admin API

Set up and manage campaigns programmatically instead of clicking through the dashboard.

Use the Admin API to set up and manage campaigns from a server or an AI agent instead of the dashboard. It covers campaigns, packages, offers, and shipping methods, and returns the api_key your funnel pages use.

Never Call the Admin API From a Campaign Page

Admin API tokens have full access to your store, so keep them on a server. Funnel pages call the Campaign Cart API with a per-campaign key, the only credential safe to ship in browser code.

Permissions

ScopeNeeded to
campaigns:readRead campaigns and their packages, offers, and shipping methods
campaigns:writeCreate, update, and delete campaigns and their packages, offers, and shipping methods
catalogue:readLook up the product_id and product_variant_ids for a package with productsList and productsVariantList
gateways:readRead gateway groups and their payment method codes with gatewayGroupsList
shipping_methods:readRead the store's shipping method codes with shippingMethodsList

See Admin API permissions for every scope and Admin API → Getting Started to create an OAuth app.

Only Available on 2024-04-01 API Version

Campaign endpoints need API version 2024-04-01 or later.

Campaign Provisioning Flow

  1. Get the gateway group id and its payment methods from gatewayGroupsList.
  2. Create the campaign with campaignsCreate.
  3. Add a package for each sellable item with campaignsPackagesCreate.
  4. Add offers with campaignsOffersCreate.
  5. Configure your funnel pages with the api_key from the create response.

Create a Campaign

name, currency, language, and payment_gateway_group_id are required. This example is a US English campaign that also accepts CAD.

POST/api/admin/campaigns/2024-04-01
{
  "name": "Spring Widget Launch US", // internal reference name
  "currency": "USD", // default currency for orders on this campaign
  "language": "en", // preferred customer language
  "payment_gateway_group_id": 4, // from gatewayGroupsList, is_default marks the store default
  "additional_currencies": ["CAD"], // currencies supported beyond the default
  "available_payment_methods": ["card_token", "paypal"], // codes from gatewayGroupsList
  "available_express_payment_methods": ["apple_pay"], // express codes from gatewayGroupsList
  "available_shipping_countries": ["US", "CA"], // ISO 3166-1 alpha-2 codes
  "statement_descriptor": "WIDGETCO" // shown on the customer's card statement
}
  • Prefill payment_gateway_group_id with the group whose is_default is true.
  • Payment methods must be ones that group supports.
  • The response includes the campaign id and api_key.

Clone a Campaign

  • Copies settings, packages and prices, shipping methods, and offers.
  • Package and shipping method IDs stay the same, so existing pages only need the new api_key.
  • The copy is named <source>-COPY. Rename it with campaignsPartialUpdate.
POST/api/admin/campaigns/{id}/clone/2024-04-01
{}

Add Packages to a Campaign

A package is the campaign's sellable reference to a product or variant. Its id is the data-next-package-id in your funnel markup.

  • Only name and product_id are required.
  • Create packages before the offers that use them.
  • The dashboard creates packages when you pick products in an offer. Call campaignsPackagesList first to avoid duplicates.
POST/api/admin/campaigns/{id}/packages/2024-04-01
{
  "name": "Widget Single", // package name
  "product_id": 184, // product linked to the package
  "product_variant_ids": [512], // product variants linked to the package
  "price": "49.95" // price per product variant unit
}

Use Offers for Quantity Tiers

Don't create 1x, 2x, and 3x packages. Create one package at the base price and discount quantities with offers. The cart and order APIs return before and after totals for showing savings. See Concepts → Offers.

Create a Subscription Package

Add price_recurring, interval (day or month), and interval_count to make a package recurring.

POST/api/admin/campaigns/{id}/packages/2024-04-01
{
  "name": "Widget Monthly Refill",
  "product_id": 184,
  "product_variant_ids": [512],
  "price": "49.95", // charged on the initial order
  "price_recurring": "39.95", // charged on each renewal
  "interval": "month", // day or month
  "interval_count": 1 // renew every 1 month
}

Set a Package Image

campaignsPackagesImageUpdate replaces the package's catalogue image from a URL (src) or base64 data (attachment). Send one, not both.

PUT/api/admin/campaigns/{id}/packages/{packageId}/image/2024-04-01
{
  "src": "https://cdn.example.com/widget-single-hero.png", // image URL to fetch
  "file_name": "widget-single-hero" // optional, the extension is taken from the image
}

Use attachment when your store can't reach the image URL.

PUT/api/admin/campaigns/{id}/packages/{packageId}/image/2024-04-01
{
  "attachment": "iVBORw0KGgoAAAANSUhEUgAA...", // base64-encoded image
  "file_name": "widget-single-hero" // optional, the extension is taken from the image
}
  • Formats: JPG, PNG, ICO, GIF, and WebP, up to 10 MB and 25 megapixels.
  • The response is the full package with the new image URL.
  • campaignsPackagesImageDestroy removes the image.
DELETE/api/admin/campaigns/{id}/packages/{packageId}/image/2024-04-01
{}

Package Images Reach Your Funnel Pages

The Campaign Cart API returns this image as the package image, and as package_image on cart and order lines. Pages pick up the change without a deploy.

Repricing Across Currencies

campaignsPackagesCreate takes a single price and price_recurring. campaignsPackagesPartialUpdate takes a prices array with one entry per currency. Currencies you leave out don't change.

PATCH/api/admin/campaigns/{id}/packages/{packageId}/2024-04-01
{
  "prices": [
    {
      "currency": "USD",
      "price": "44.95",
      "price_recurring": "34.95"
    }
  ],
  "recalculate_prices": true // derive the other currencies from the default currency price
}

With recalculate_prices set to true, the currencies you left out are converted from the default currency if you included it, otherwise from the first currency listed. Include the default currency or send a single price so the source is clear.

Read Prices Back From the Response

price and price_recurring are write-only. Read the prices array instead. Create takes a product_variant_ids array, update takes one product_variant_id.

Why Offers

Offers move pricing logic out of your funnel's JavaScript and into the Campaigns API, where it is calculated reliably and managed in one place. Keep one package per product at its base price, and let offers set every other price:

  • One automatic offer per quantity (1x, 2x, 3x, 4x) sets the price at each tier. When tiers overlap, the larger quantity wins.
  • A shipping_percentage offer discounts the shipping price, for example at 3 or more.
  • A coupon offer (offer_type of voucher) on an exit pop discounts on top of the tier price.
  • Upsell pages skip automatic offers, so discount upsells with coupon offers.

See Concepts → Offers for a worked tier example.

Add Offers to a Campaign

An offer needs a name, a condition (which packages, and what quantity), and a benefit (the percentage off). It applies automatically at checkout unless offer_type is voucher.

POST/api/admin/campaigns/{id}/offers/2024-04-01
{
  "name": "Buy 2 Save 30%", // unique within the campaign
  "condition": {
    "type": "count", // any, count for a minimum quantity, or count_equal for an exact quantity
    "value": 2, // package quantity, required when type is count or count_equal
    "package_ids": [2231] // package ids from campaignsPackagesCreate, or send all_packages: true
  },
  "benefit": {
    "type": "package_percentage", // package_percentage, shipping_percentage, or order_percentage
    "value": "30.00", // percentage off
    "price_rounding": "0.95" // round each discounted unit price to XX.95, omit for no rounding
  }
}

Automatic offers run only at checkout. Upsell, downsell, and exit-pop discounts need a code offer (offer_type of voucher):

  • It applies when the customer enters the code, or your page sends it in vouchers (see Campaigns API → Offers).
  • Codes are unique within a campaign, ignoring case. A duplicate returns 400.
POST/api/admin/campaigns/{id}/offers/2024-04-01
{
  "name": "Upsell 10% Off",
  "offer_type": "voucher", // offer (automatic) or voucher (code offer, code required)
  "code": "UPSELL10", // required when offer_type is voucher, submit it from the upsell or exit-pop page
  "condition": {
    "type": "any", // no quantity requirement
    "all_packages": true // apply to all current and future packages
  },
  "benefit": {
    "type": "order_percentage",
    "value": "10.00"
  }
}

Package IDs Read Back as Packages

package_ids is write-only. The response returns a packages array instead.

Add Shipping Methods to a Campaign

A campaign shipping method sets a campaign price for a shipping method configured on the store. shipping_method and price are required.

  • shipping_method is a store shipping method code from shippingMethodsList.
  • name is filled in from that shipping method.
POST/api/admin/campaigns/{id}/shipping-methods/2024-04-01
{
  "shipping_method": "default-shipping", // code from the store's configured shipping methods
  "price": "4.95" // price in the campaign's default currency
}

The campaign's other currencies are converted from this price. To change prices later, campaignsShippingMethodsPartialUpdate takes the same prices array and recalculate_prices flag as packages.

PATCH/api/admin/campaigns/{id}/shipping-methods/{shippingMethodId}/2024-04-01
{
  "prices": [
    { "currency": "USD", "price": "5.95" }
  ],
  "recalculate_prices": true // convert the other currencies from the price above
}

Find Campaigns to Act On

campaignsList is cursor paginated. Follow next until it is null.

FilterMatches
nameCampaign name contains this text, case-insensitive
currencyDefault currency, as an ISO 4217 code
languageCampaign language, as an ISO 639-1 code
created_date_from / created_date_toCreated within a date range (YYYY-MM-DD, UTC)
updated_date_from / updated_date_toLast updated within a date range (YYYY-MM-DD, UTC)
GET/api/admin/campaigns/?currency=EUR&updated_date_from=2026-08-01&page_size=502024-04-01
{}

Audit Packages Against Your Catalogue

campaignsPackagesList filters on name, product_name, and product_sku, so you can find every package that sells a discontinued SKU.

GET/api/admin/campaigns/{id}/packages/?product_sku=WIDGET-BLU2024-04-01
{}

Check product_purchase_availability and product_inventory_availability on each package to find products customers can no longer buy.

Retire a Campaign or Package

campaignsDestroy deletes a campaign's settings. campaignsPackagesDestroy removes one package.

Check What Still Points at the Campaign First

Live funnel pages use the campaign's api_key and package IDs. Take them down or repoint them before you delete either.

Domains Are Configured in the Dashboard

Set authorized domains in your store's Campaign Settings, not through this API. See Concepts → Domains.

Endpoints

Full request and response detail lives in the Admin API reference.

Campaigns

OperationEndpoint
Campaigns ListGET /api/admin/campaigns/
Campaigns CreatePOST /api/admin/campaigns/
Campaigns RetrieveGET /api/admin/campaigns/{id}/
Campaigns Partial UpdatePATCH /api/admin/campaigns/{id}/
Campaigns DestroyDELETE /api/admin/campaigns/{id}/
Campaigns ClonePOST /api/admin/campaigns/{id}/clone/

Offers

OperationEndpoint
Campaigns Offers ListGET /api/admin/campaigns/{id}/offers/
Campaigns Offers CreatePOST /api/admin/campaigns/{id}/offers/
Campaigns Offers RetrieveGET /api/admin/campaigns/{id}/offers/{offerId}/
Campaigns Offers Partial UpdatePATCH /api/admin/campaigns/{id}/offers/{offerId}/
Campaigns Offers DestroyDELETE /api/admin/campaigns/{id}/offers/{offerId}/

Packages

OperationEndpoint
Campaigns Packages ListGET /api/admin/campaigns/{id}/packages/
Campaigns Packages CreatePOST /api/admin/campaigns/{id}/packages/
Campaigns Packages RetrieveGET /api/admin/campaigns/{id}/packages/{packageId}/
Campaigns Packages Partial UpdatePATCH /api/admin/campaigns/{id}/packages/{packageId}/
Campaigns Packages DestroyDELETE /api/admin/campaigns/{id}/packages/{packageId}/
Campaigns Packages Image UpdatePUT /api/admin/campaigns/{id}/packages/{packageId}/image/
Campaigns Packages Image DestroyDELETE /api/admin/campaigns/{id}/packages/{packageId}/image/

Shipping Methods

OperationEndpoint
Campaigns Shipping Methods ListGET /api/admin/campaigns/{id}/shipping-methods/
Campaigns Shipping Methods CreatePOST /api/admin/campaigns/{id}/shipping-methods/
Campaigns Shipping Methods RetrieveGET /api/admin/campaigns/{id}/shipping-methods/{shippingMethodId}/
Campaigns Shipping Methods Partial UpdatePATCH /api/admin/campaigns/{id}/shipping-methods/{shippingMethodId}/
Campaigns Shipping Methods DestroyDELETE /api/admin/campaigns/{id}/shipping-methods/{shippingMethodId}/

On this page