API ReferenceEndpointsCoupons

Coupons

Coupons are discount codes redeemed at checkout — percent off, fixed amount, free shipping, or BOGO. They carry usage limits (total + per-customer), date windows, eligibility rules (products, customer segments), and platform sync state. Use these endpoints to create, list, validate, and redeem coupons.

Two auth surfaces on this page.

  • Public API (Authorization: Bearer brainerce_*) — the 8 /v1/coupons/* operations are the stable, versioned surface for external integrators (list, create, get, update, delete, sync, publish, platform capabilities).
  • Dashboard API (Clerk JWT) — the 14 operations under /coupons/* power the merchant dashboard (conflicts, bulk ops, validate-for-order, …). They are internal and not part of the public contract — paths, fields, and behaviour can change without notice.

The newsletter welcome offer (/v1/newsletter-benefit/*) is on this page for the same reason it carries the coupons:* scopes: it mints a Coupon, and the coupon machinery enforces it. It issues nothing on its own. A coupon appears when a shopper confirms their own newsletter signup, one per mailbox per store, and resend re-sends that same code rather than minting a second. To hand a code to a named customer, create a coupon.

List available coupons

GET
/coupons/available
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/coupons/available?storeId=string"
[
  {
    "id": "clx1a2b3c4d5e6f7g8h9",
    "code": "SUMMER20",
    "title": "Summer sale",
    "description": "string",
    "type": "PERCENTAGE",
    "value": "20",
    "startsAt": "2019-08-24T14:15:22Z",
    "endsAt": "2019-08-24T14:15:22Z",
    "status": "ACTIVE",
    "usageLimit": 100,
    "usageLimitPerCustomer": 1,
    "usageCount": 12,
    "minimumOrderAmount": "50.00",
    "maximumDiscount": "25.00",
    "conditions": {},
    "applicableProducts": [
      {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "Summer Collection"
      }
    ],
    "excludedProducts": [
      {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "Summer Collection"
      }
    ],
    "applicableCategories": [
      {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "Summer Collection"
      }
    ],
    "excludedCategories": [
      {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "Summer Collection"
      }
    ],
    "regionIds": [],
    "combinesWithOther": true,
    "needsSync": false,
    "lastSyncedAt": "2019-08-24T14:15:22Z",
    "channels": {},
    "channelPublishes": [
      {
        "salesChannel": {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "My storefront",
          "connectionId": "vc_9f3a2b1c8d7e6f5a"
        },
        "connection": {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "My storefront",
          "connectionId": "vc_9f3a2b1c8d7e6f5a"
        }
      }
    ],
    "vibeCodedPublishes": [
      {
        "salesChannel": {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "My storefront",
          "connectionId": "vc_9f3a2b1c8d7e6f5a"
        },
        "connection": {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "My storefront",
          "connectionId": "vc_9f3a2b1c8d7e6f5a"
        }
      }
    ],
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  }
]

Find all

GET
/coupons
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/coupons?storeId=string"
{
  "data": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "code": "SUMMER20",
      "title": "Summer sale",
      "description": "string",
      "type": "PERCENTAGE",
      "value": "20",
      "startsAt": "2019-08-24T14:15:22Z",
      "endsAt": "2019-08-24T14:15:22Z",
      "status": "ACTIVE",
      "usageLimit": 100,
      "usageLimitPerCustomer": 1,
      "usageCount": 12,
      "minimumOrderAmount": "50.00",
      "maximumDiscount": "25.00",
      "conditions": {},
      "applicableProducts": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "excludedProducts": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "applicableCategories": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "excludedCategories": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "regionIds": [],
      "combinesWithOther": true,
      "needsSync": false,
      "lastSyncedAt": "2019-08-24T14:15:22Z",
      "channels": {},
      "channelPublishes": [
        {
          "salesChannel": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          },
          "connection": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          }
        }
      ],
      "vibeCodedPublishes": [
        {
          "salesChannel": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          },
          "connection": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          }
        }
      ],
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 137,
    "totalPages": 7
  }
}

Create

POST
/coupons
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeIdstring
codestring

Redemption code. Case-insensitive, and unique per store.

title?string

Human-readable title shown in the dashboard list.

description?string

Internal description (not shown to shoppers).

typestring

Discount type. PERCENTAGE = value is a percent (0-100); FIXED_AMOUNT = value is in store currency.

Value in"PERCENTAGE" | "FIXED_AMOUNT"
valuenumber

Discount amount. Interpretation depends on type: 25 for PERCENTAGE means 25% off; 25 for FIXED_AMOUNT means $25 off.

Range0 <= value
startsAt?string

ISO 8601 start date. Coupon is inactive before this timestamp.

endsAt?string

ISO 8601 end date. Coupon is inactive after this timestamp.

status?string

Initial status. Defaults to ACTIVE. Use SCHEDULED when startsAt is in the future.

Value in"ACTIVE" | "SCHEDULED" | "EXPIRED" | "DISABLED"
usageLimit?number

Total redemption cap across all customers. Omit for unlimited.

Range0 <= value
usageLimitPerCustomer?number

Per-customer redemption cap (requires customerId on the checkout).

Range0 <= value
minimumOrderAmount?number

Minimum cart subtotal to redeem.

Range0 <= value
maximumDiscount?number

Cap on the discount value for PERCENTAGE coupons (e.g. "25% off, up to $50"). Ignored for FIXED_AMOUNT.

Range0 <= value
conditions?object

Advanced conditions (customer segment, sales channel, …). Free-form JSON.

Empty Object

applicableProducts?array<string>

Restrict redemption to specific product IDs.

regionIds?array<string>

Restrict the coupon to specific regions (PRD §24). Empty/omitted = applies in all regions. Holds Region IDs of this store.

excludedProducts?array<string>

Exclude specific product IDs from the coupon.

applicableCategories?array<string>

Restrict redemption to specific category IDs.

excludedCategories?array<string>

Exclude specific category IDs from the coupon.

combinesWithOther?boolean

When false (default), this coupon cannot stack with other discount sources (other coupons, automatic discount rules). When true, it stacks.

platforms?array<string>

Sales channels to publish the coupon to.

channels?object

Per-platform field overrides (keyed by platform code). Useful when the platform uses a different code or wants a different title.

Empty Object

curl -X POST "https://api.brainerce.com/api/coupons?storeId=string" \  -H "Content-Type: application/json" \  -d '{    "code": "SUMMER25",    "type": "PERCENTAGE",    "value": 25  }'
{
  "id": "string",
  "code": "SUMMER20",
  "title": "string",
  "description": "string",
  "type": "string",
  "value": "string",
  "startsAt": "2019-08-24T14:15:22Z",
  "endsAt": "2019-08-24T14:15:22Z",
  "status": "string",
  "usageLimit": 0,
  "usageLimitPerCustomer": 0,
  "usageCount": 0,
  "minimumOrderAmount": "string",
  "maximumDiscount": "string",
  "conditions": {},
  "applicableProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "applicableCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "regionIds": [
    "string"
  ],
  "combinesWithOther": true,
  "needsSync": true,
  "lastSyncedAt": "2019-08-24T14:15:22Z",
  "channels": {},
  "channelPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "vibeCodedPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "validationWarnings": [
    {
      "platform": "SHOPIFY",
      "warnings": [
        "SHOPIFY does not support product exclusions - will be ignored on sync"
      ]
    }
  ]
}

List conflicts

GET
/coupons/conflicts
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/coupons/conflicts?storeId=string"
[
  {
    "id": "clx1a2b3c4d5e6f7g8h9",
    "matchType": "code",
    "sourcePlatform": "SHOPIFY",
    "sourceExternalId": "string",
    "sourceData": {},
    "existingCouponId": "string",
    "existingCoupon": {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "code": "SUMMER20",
      "title": "Summer sale",
      "description": "string",
      "type": "PERCENTAGE",
      "value": "20",
      "startsAt": "2019-08-24T14:15:22Z",
      "endsAt": "2019-08-24T14:15:22Z",
      "status": "ACTIVE",
      "usageLimit": 100,
      "usageLimitPerCustomer": 1,
      "usageCount": 12,
      "minimumOrderAmount": "50.00",
      "maximumDiscount": "25.00",
      "conditions": {},
      "applicableProducts": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "excludedProducts": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "applicableCategories": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "excludedCategories": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "regionIds": [],
      "combinesWithOther": true,
      "needsSync": false,
      "lastSyncedAt": "2019-08-24T14:15:22Z",
      "channels": {},
      "channelPublishes": [
        {
          "salesChannel": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          },
          "connection": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          }
        }
      ],
      "vibeCodedPublishes": [
        {
          "salesChannel": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          },
          "connection": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          }
        }
      ],
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    },
    "status": "PENDING",
    "resolution": "MERGE",
    "resolvedAt": "2019-08-24T14:15:22Z",
    "createdAt": "2019-08-24T14:15:22Z"
  }
]

List platform capabilities

Empty object. Platform coupon capabilities moved into the standalone connector apps and are not re-exposed here yet, so this answers {} for every store. A missing platform key means unknown, not unsupported.

GET
/coupons/platform-capabilities
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/coupons/platform-capabilities?storeId=string"
{}

Validate for order

POST
/coupons/validate-for-order
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeIdstring

Empty Object

curl -X POST "https://api.brainerce.com/api/coupons/validate-for-order?storeId=string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "valid": true,
  "coupon": {
    "id": "clx1a2b3c4d5e6f7g8h9",
    "code": "SUMMER20",
    "title": "Summer sale",
    "description": "string",
    "type": "PERCENTAGE",
    "value": "20",
    "startsAt": "2019-08-24T14:15:22Z",
    "endsAt": "2019-08-24T14:15:22Z",
    "status": "ACTIVE",
    "usageLimit": 100,
    "usageLimitPerCustomer": 1,
    "usageCount": 12,
    "minimumOrderAmount": "50.00",
    "maximumDiscount": "25.00",
    "conditions": {},
    "applicableProducts": [
      {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "Summer Collection"
      }
    ],
    "excludedProducts": [
      {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "Summer Collection"
      }
    ],
    "applicableCategories": [
      {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "Summer Collection"
      }
    ],
    "excludedCategories": [
      {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "Summer Collection"
      }
    ],
    "regionIds": [],
    "combinesWithOther": true,
    "needsSync": false,
    "lastSyncedAt": "2019-08-24T14:15:22Z",
    "channels": {},
    "channelPublishes": [
      {
        "salesChannel": {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "My storefront",
          "connectionId": "vc_9f3a2b1c8d7e6f5a"
        },
        "connection": {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "My storefront",
          "connectionId": "vc_9f3a2b1c8d7e6f5a"
        }
      }
    ],
    "vibeCodedPublishes": [
      {
        "salesChannel": {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "My storefront",
          "connectionId": "vc_9f3a2b1c8d7e6f5a"
        },
        "connection": {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "My storefront",
          "connectionId": "vc_9f3a2b1c8d7e6f5a"
        }
      }
    ],
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z"
  },
  "discountAmount": 12.5,
  "message": "Coupon applied",
  "errors": [
    "Coupon not found"
  ]
}

Bulk update

POST
/coupons/bulk/update
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeIdstring

Empty Object

curl -X POST "https://api.brainerce.com/api/coupons/bulk/update?storeId=string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "success": true,
  "updatedCount": 3,
  "details": "Updated 3 coupons: status"
}

Bulk delete

POST
/coupons/bulk/delete
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeIdstring

Empty Object

curl -X POST "https://api.brainerce.com/api/coupons/bulk/delete?storeId=string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "success": true,
  "deletedCount": 3,
  "details": "Deleted 3 coupons"
}

Find one

GET
/coupons/{id}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Query Parameters

storeIdstring
curl -X GET "https://api.brainerce.com/api/coupons/string?storeId=string"
{
  "id": "clx1a2b3c4d5e6f7g8h9",
  "code": "SUMMER20",
  "title": "Summer sale",
  "description": "string",
  "type": "PERCENTAGE",
  "value": "20",
  "startsAt": "2019-08-24T14:15:22Z",
  "endsAt": "2019-08-24T14:15:22Z",
  "status": "ACTIVE",
  "usageLimit": 100,
  "usageLimitPerCustomer": 1,
  "usageCount": 12,
  "minimumOrderAmount": "50.00",
  "maximumDiscount": "25.00",
  "conditions": {},
  "applicableProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "applicableCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "regionIds": [],
  "combinesWithOther": true,
  "needsSync": false,
  "lastSyncedAt": "2019-08-24T14:15:22Z",
  "channels": {},
  "channelPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "vibeCodedPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

Update

PATCH
/coupons/{id}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Query Parameters

storeIdstring

Empty Object

curl -X PATCH "https://api.brainerce.com/api/coupons/string?storeId=string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "clx1a2b3c4d5e6f7g8h9",
  "code": "SUMMER20",
  "title": "Summer sale",
  "description": "string",
  "type": "PERCENTAGE",
  "value": "20",
  "startsAt": "2019-08-24T14:15:22Z",
  "endsAt": "2019-08-24T14:15:22Z",
  "status": "ACTIVE",
  "usageLimit": 100,
  "usageLimitPerCustomer": 1,
  "usageCount": 12,
  "minimumOrderAmount": "50.00",
  "maximumDiscount": "25.00",
  "conditions": {},
  "applicableProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "applicableCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "regionIds": [],
  "combinesWithOther": true,
  "needsSync": false,
  "lastSyncedAt": "2019-08-24T14:15:22Z",
  "channels": {},
  "channelPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "vibeCodedPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

Delete

DELETE
/coupons/{id}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Query Parameters

storeIdstring
curl -X DELETE "https://api.brainerce.com/api/coupons/string?storeId=string"
{
  "success": true,
  "jobIds": [
    "string"
  ],
  "warnings": [
    "string"
  ]
}

Sync coupon

POST
/coupons/{id}/sync
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Query Parameters

storeIdstring
curl -X POST "https://api.brainerce.com/api/coupons/string/sync?storeId=string"
{
  "success": true,
  "message": "string",
  "jobIds": [
    "string"
  ]
}

Publish to platforms

POST
/coupons/{id}/publish
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Query Parameters

storeIdstring
curl -X POST "https://api.brainerce.com/api/coupons/string/publish?storeId=string"
{
  "message": "string",
  "jobIds": [
    "string"
  ]
}

Resolve conflict

POST
/coupons/conflicts/{conflictId}/resolve
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

conflictIdstring

Query Parameters

storeIdstring
curl -X POST "https://api.brainerce.com/api/coupons/conflicts/string/resolve?storeId=string"
{
  "success": true,
  "message": "Conflict resolved"
}

List coupons with pagination

GET
/v1/coupons
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

sortOrder?string
sortBy?string
platform?string
type?string
status?string
search?string
limit?number
page?number
curl -X GET "https://api.brainerce.com/api/v1/coupons?sortOrder=string&sortBy=string&platform=string&type=string&status=string&search=string&limit=0&page=0"
{
  "data": [
    {
      "id": "string",
      "code": "SUMMER20",
      "title": "string",
      "description": "string",
      "type": "string",
      "value": "string",
      "startsAt": "2019-08-24T14:15:22Z",
      "endsAt": "2019-08-24T14:15:22Z",
      "status": "string",
      "usageLimit": 0,
      "usageLimitPerCustomer": 0,
      "usageCount": 0,
      "minimumOrderAmount": "string",
      "maximumDiscount": "string",
      "conditions": {},
      "applicableProducts": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "excludedProducts": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "applicableCategories": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "excludedCategories": [
        {
          "id": "clx1a2b3c4d5e6f7g8h9",
          "name": "Summer Collection"
        }
      ],
      "regionIds": [
        "string"
      ],
      "combinesWithOther": true,
      "needsSync": true,
      "lastSyncedAt": "2019-08-24T14:15:22Z",
      "channels": {},
      "channelPublishes": [
        {
          "salesChannel": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          },
          "connection": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          }
        }
      ],
      "vibeCodedPublishes": [
        {
          "salesChannel": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          },
          "connection": {
            "id": "clx1a2b3c4d5e6f7g8h9",
            "name": "My storefront",
            "connectionId": "vc_9f3a2b1c8d7e6f5a"
          }
        }
      ],
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "meta": {
    "page": 1,
    "limit": 20,
    "total": 137,
    "totalPages": 7
  }
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons"
}

Create a new coupon

Honors Idempotency-Key header. See /docs/api/idempotency.

POST
/v1/coupons
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
codestring

Redemption code. Case-insensitive, and unique per store.

title?string

Human-readable title shown in the dashboard list.

description?string

Internal description (not shown to shoppers).

typestring

Discount type. PERCENTAGE = value is a percent (0-100); FIXED_AMOUNT = value is in store currency.

Value in"PERCENTAGE" | "FIXED_AMOUNT"
valuenumber

Discount amount. Interpretation depends on type: 25 for PERCENTAGE means 25% off; 25 for FIXED_AMOUNT means $25 off.

Range0 <= value
startsAt?string

ISO 8601 start date. Coupon is inactive before this timestamp.

endsAt?string

ISO 8601 end date. Coupon is inactive after this timestamp.

status?string

Initial status. Defaults to ACTIVE. Use SCHEDULED when startsAt is in the future.

Value in"ACTIVE" | "SCHEDULED" | "EXPIRED" | "DISABLED"
usageLimit?number

Total redemption cap across all customers. Omit for unlimited.

Range0 <= value
usageLimitPerCustomer?number

Per-customer redemption cap (requires customerId on the checkout).

Range0 <= value
minimumOrderAmount?number

Minimum cart subtotal to redeem.

Range0 <= value
maximumDiscount?number

Cap on the discount value for PERCENTAGE coupons (e.g. "25% off, up to $50"). Ignored for FIXED_AMOUNT.

Range0 <= value
conditions?object

Advanced conditions (customer segment, sales channel, …). Free-form JSON.

Empty Object

applicableProducts?array<string>

Restrict redemption to specific product IDs.

regionIds?array<string>

Restrict the coupon to specific regions (PRD §24). Empty/omitted = applies in all regions. Holds Region IDs of this store.

excludedProducts?array<string>

Exclude specific product IDs from the coupon.

applicableCategories?array<string>

Restrict redemption to specific category IDs.

excludedCategories?array<string>

Exclude specific category IDs from the coupon.

combinesWithOther?boolean

When false (default), this coupon cannot stack with other discount sources (other coupons, automatic discount rules). When true, it stacks.

platforms?array<string>

Sales channels to publish the coupon to.

channels?object

Per-platform field overrides (keyed by platform code). Useful when the platform uses a different code or wants a different title.

Empty Object

curl -X POST "https://api.brainerce.com/api/v1/coupons" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{    "code": "SUMMER25",    "type": "PERCENTAGE",    "value": 25  }'
{
  "id": "string",
  "code": "SUMMER20",
  "title": "string",
  "description": "string",
  "type": "string",
  "value": "string",
  "startsAt": "2019-08-24T14:15:22Z",
  "endsAt": "2019-08-24T14:15:22Z",
  "status": "string",
  "usageLimit": 0,
  "usageLimitPerCustomer": 0,
  "usageCount": 0,
  "minimumOrderAmount": "string",
  "maximumDiscount": "string",
  "conditions": {},
  "applicableProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "applicableCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "regionIds": [
    "string"
  ],
  "combinesWithOther": true,
  "needsSync": true,
  "lastSyncedAt": "2019-08-24T14:15:22Z",
  "channels": {},
  "channelPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "vibeCodedPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z",
  "validationWarnings": [
    {
      "platform": "SHOPIFY",
      "warnings": [
        "SHOPIFY does not support product exclusions - will be ignored on sync"
      ]
    }
  ]
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons"
}

Get platform capabilities for coupon features

GET
/v1/coupons/platform-capabilities
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

curl -X GET "https://api.brainerce.com/api/v1/coupons/platform-capabilities"
Empty

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/platform-capabilities"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/platform-capabilities"
}

Get a single coupon by ID

GET
/v1/coupons/{id}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Coupon ID

curl -X GET "https://api.brainerce.com/api/v1/coupons/string"
{
  "id": "string",
  "code": "SUMMER20",
  "title": "string",
  "description": "string",
  "type": "string",
  "value": "string",
  "startsAt": "2019-08-24T14:15:22Z",
  "endsAt": "2019-08-24T14:15:22Z",
  "status": "string",
  "usageLimit": 0,
  "usageLimitPerCustomer": 0,
  "usageCount": 0,
  "minimumOrderAmount": "string",
  "maximumDiscount": "string",
  "conditions": {},
  "applicableProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "applicableCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "regionIds": [
    "string"
  ],
  "combinesWithOther": true,
  "needsSync": true,
  "lastSyncedAt": "2019-08-24T14:15:22Z",
  "channels": {},
  "channelPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "vibeCodedPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

Update a coupon

Supports Idempotency-Key header for safe retries.

PATCH
/v1/coupons/{id}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Coupon ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255

Empty Object

curl -X PATCH "https://api.brainerce.com/api/v1/coupons/string" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "id": "string",
  "code": "SUMMER20",
  "title": "string",
  "description": "string",
  "type": "string",
  "value": "string",
  "startsAt": "2019-08-24T14:15:22Z",
  "endsAt": "2019-08-24T14:15:22Z",
  "status": "string",
  "usageLimit": 0,
  "usageLimitPerCustomer": 0,
  "usageCount": 0,
  "minimumOrderAmount": "string",
  "maximumDiscount": "string",
  "conditions": {},
  "applicableProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedProducts": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "applicableCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "excludedCategories": [
    {
      "id": "clx1a2b3c4d5e6f7g8h9",
      "name": "Summer Collection"
    }
  ],
  "regionIds": [
    "string"
  ],
  "combinesWithOther": true,
  "needsSync": true,
  "lastSyncedAt": "2019-08-24T14:15:22Z",
  "channels": {},
  "channelPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "vibeCodedPublishes": [
    {
      "salesChannel": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      },
      "connection": {
        "id": "clx1a2b3c4d5e6f7g8h9",
        "name": "My storefront",
        "connectionId": "vc_9f3a2b1c8d7e6f5a"
      }
    }
  ],
  "createdAt": "2019-08-24T14:15:22Z",
  "updatedAt": "2019-08-24T14:15:22Z"
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

Delete a coupon

Supports Idempotency-Key header for safe retries.

DELETE
/v1/coupons/{id}
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Coupon ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
platforms?array<string>

Optional platforms to remove the coupon from

curl -X DELETE "https://api.brainerce.com/api/v1/coupons/string" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{}'
{
  "success": true,
  "jobIds": [
    "string"
  ],
  "warnings": [
    "string"
  ]
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}"
}

Sync a coupon to all connected platforms

Supports Idempotency-Key header for safe retries.

POST
/v1/coupons/{id}/sync
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Coupon ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
curl -X POST "https://api.brainerce.com/api/v1/coupons/string/sync" \  -H "Idempotency-Key: string"
{
  "success": true,
  "message": "string",
  "jobIds": [
    "string"
  ]
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}/sync"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}/sync"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}/sync"
}

Publish a coupon to specific platforms

Supports Idempotency-Key header for safe retries.

POST
/v1/coupons/{id}/publish
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

idstring

Coupon ID

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
platformsarray<string>

Platforms to publish the coupon to

curl -X POST "https://api.brainerce.com/api/v1/coupons/string/publish" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{    "platforms": [      "string"    ]  }'
{
  "message": "string",
  "jobIds": [
    "string"
  ]
}

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}/publish"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}/publish"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}/publish"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/coupons/{id}/publish"
}

Get the newsletter signup benefit settings

Returns null when the store has never configured a benefit. enabled: false means configured but switched off — two different states, and a storefront should treat both as "offer nothing".

GET
/v1/newsletter-benefit/settings
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

curl -X GET "https://api.brainerce.com/api/v1/newsletter-benefit/settings"
Empty

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/settings"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/settings"
}

Create or replace the newsletter signup benefit settings

A FULL REPLACEMENT, not a patch: every field is written, so omitting one clears it. Bumps the stored settings version.

Changing these settings never rewrites a promise already made. Signups still waiting for a confirmation click keep the terms they were shown at signup, and coupons already issued are untouched.

Supports Idempotency-Key header for safe retries.

PUT
/v1/newsletter-benefit/settings
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Header Parameters

Idempotency-Key?string

Client-supplied key (a UUID v4 is the recommended form, max 255 characters) that makes this mutation safe to retry.

  • Replay window: 24 hours. The first response for a key is cached; a retry inside the window with the same request body returns the original status and body without re-running the handler.
  • Reusing a key with a different body returns 409 Conflict with code: "IDEMPOTENCY_KEY_REUSED". The request fingerprint (method + path + body hash) is compared against the stored one; a mismatch is refused rather than served the old response.
  • Keys are scoped to the calling credential and store — two API keys may safely use the same key value.
  • Error responses are cached too, so a retry of a request that failed validation returns the same 400 immediately.
  • Sending this header on a GET returns 400 with code: "IDEMPOTENCY_KEY_NOT_SUPPORTED" — GETs are already idempotent.
  • Support is per-route and this parameter is the authoritative signal: a key sent to a route that does not declare it is accepted and silently ignored.

See /docs/api/idempotency.

Lengthlength <= 255
enabledboolean

Turn the benefit on or off. Off stops new offers immediately; coupons already issued keep working, and signups still waiting for a confirmation click keep the terms they were shown.

discountTypeCouponType
Value in"PERCENTAGE" | "FIXED_AMOUNT"
discountValuenumber

Percent (1-100) for PERCENTAGE, or an amount in the store currency for FIXED_AMOUNT.

minimumOrderAmount?number

Minimum order subtotal required to use the coupon.

maximumDiscount?number

Cap on the discount a percentage benefit may produce. Ignored — and stored as null — for a fixed-amount benefit.

combinesWithOtherboolean

Whether the coupon may stack with other discounts.

validityDaysnumber

Days the coupon stays usable, counted from issuance.

eligibilityTtlHoursnumber

Hours a signup stays eligible, counted from the moment the form was submitted. A confirmation click after this still subscribes the address but earns no coupon — the confirmation LINK itself never expires, so this is the only deadline in the flow.

firstOrderOnlyboolean

Restrict the coupon to buyers with no previous order in this store. Checked against the address the coupon is bound to, including guest orders.

applicableProducts?array<string>

Product IDs the coupon applies to.

excludedProducts?array<string>
applicableCategories?array<string>
excludedCategories?array<string>
salesChannelIds?array<string>

Sales channels the issued coupon may be redeemed on. Leave empty for every enabled channel — an empty list is expanded at issuance, because a coupon with no channel rows is refused on every vibe-coded storefront.

content?object

Localized copy: { "en": { "headline": "...", "terms": "..." }, "he": { ... } }. Shown on the signup form and repeated in the email.

Empty Object

curl -X PUT "https://api.brainerce.com/api/v1/newsletter-benefit/settings" \  -H "Idempotency-Key: string" \  -H "Content-Type: application/json" \  -d '{    "enabled": true,    "discountType": "PERCENTAGE",    "discountValue": 0,    "combinesWithOther": true,    "validityDays": 0,    "eligibilityTtlHours": 0,    "firstOrderOnly": true  }'
Empty

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/settings"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/settings"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/settings"
}

List issued newsletter benefits

Paginated { data, meta }, newest first. redeemed is derived from the coupon having been used, so it is accurate the moment an order completes.

There is deliberately NO email filter: a lookup-by-address would turn this into a "does this person shop here" probe for any leaked key with coupons:read. Filter the page you get back.

GET
/v1/newsletter-benefit/grants
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Query Parameters

storeId?string

Store the grants belong to. Required.

page?number
Default1
limit?number
Default20
Rangevalue <= 100
status?string
Value in"PENDING" | "ISSUING" | "ISSUED" | "EXPIRED" | "FAILED"
from?string

Signups created on or after this ISO-8601 date.

to?string

Signups created on or before this ISO-8601 date.

curl -X GET "https://api.brainerce.com/api/v1/newsletter-benefit/grants?storeId=string&page=1&limit=20&status=PENDING&from=string&to=string"
Empty

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/grants"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/grants"
}

Re-send an issued newsletter benefit

Re-queues the SAME coupon code. It never mints a second one, so a support ticket cannot turn into two discounts. For a benefit whose issuance failed before any coupon existed, this retries the issuance and mails whatever comes out.

Rejects a signup that has not been confirmed yet, and one that lapsed before any coupon was minted: in both cases there is nothing to re-send and nothing that may be created.

POST
/v1/newsletter-benefit/grants/{grantId}/resend
AuthorizationBearer <token>

Admin API key (server-to-server). Issue via the dashboard at Settings → Authentication → API Keys. Plain-text key is shown once — store in a secret manager. Format: Authorization: Bearer brainerce_xxxxxxxxx.

In: header

Path Parameters

grantIdstring

Grant ID from the grants list

curl -X POST "https://api.brainerce.com/api/v1/newsletter-benefit/grants/string/resend"
Empty

{
  "statusCode": 400,
  "code": "VALIDATION_FAILED",
  "message": "name should not be empty, price must be a positive number",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/grants/{grantId}/resend"
}

{
  "statusCode": 401,
  "code": "UNAUTHORIZED",
  "message": "Invalid or expired credential",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/grants/{grantId}/resend"
}

{
  "statusCode": 403,
  "code": "INSUFFICIENT_SCOPE",
  "message": "API key does not have the required scope: products:write",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/grants/{grantId}/resend"
}

{
  "statusCode": 404,
  "code": "RESOURCE_NOT_FOUND",
  "message": "Resource not found",
  "timestamp": "2026-08-23T10:15:00.000Z",
  "path": "/api/v1/newsletter-benefit/grants/{grantId}/resend"
}

On this page

No Headings