Sign inSign up

Documentation

Authenticate with an API key and send promotion text to CouponBrain. One successful extract uses one credit.

Authentication

Create a key on Generate API key, then send it as a Bearer token. The secret is shown once.

Authorization: Bearer aff_…

Extract

POST /api/extract reads promotion text and returns grounded coupons, tiers, scope flags, campaign events, campaign themes, and an end date.

text

string, required

Promotion source. Max 20,000 characters.

as_of

YYYY-MM-DD, optional

Temporal context for countdowns. Not used as coupon evidence. Defaults to today if omitted.

model

string, optional

latest or couponbrain-mini-1.10. Empty or omitted is latest. Both currently resolve to Mini 1.10.

format

string, optional

json or toon. Empty or omitted is json.
curl https://affensus.com/api/extract \
  -H "Authorization: Bearer aff_…" \
  -H "Content-Type: application/json" \
  -d '{
    "text": "Use code SAVE20 for 20% off your order. New customers only. Ends in 3 days.",
    "as_of": "2026-09-27",
    "model": "latest",
    "format": "json"
  }'

Response

success

boolean

True when extraction finished.

result

object | string

Canonical payload when format is json. TOON string when format is toon. Same fields either way.

processing_ms

number | null

Upstream processing time.

credits_used

number

Credits deducted for this request. 1 on a billed extract, 0 on the homepage demo.

credits_remaining

number | null

Credits left after this request.

usage

object | null

Token and generation timing from the model.
{
  "success": true,
  "result": {
    "coupons": [
      {
        "code": "SAVE20",
        "type": "percentage",
        "currency": null,
        "scope": {
          "sitewide": true,
          "new_customers_only": true
        },
        "tiers": [
          {
            "minimum_spend": null,
            "discount_percent": 20
          },
          {
            "minimum_spend": 50,
            "discount_percent": 25,
            "capped_discount": 15
          }
        ]
      },
      {
        "code": "SHIPFREE",
        "type": "free_shipping",
        "currency": "USD",
        "scope": {
          "app_only": true
        },
        "tiers": [
          {
            "minimum_spend": 25
          }
        ]
      },
      {
        "code": "TAKE10",
        "type": "fixed",
        "currency": "EUR",
        "scope": {},
        "tiers": [
          {
            "minimum_spend": null,
            "discount_amount": 10
          }
        ]
      }
    ],
    "end_date": "2026-09-30",
    "campaign_events": ["black_friday"],
    "campaign_themes": ["new_customer_offer"]
  },
  "processing_ms": 150,
  "credits_used": 1,
  "credits_remaining": 9999
}

Result

coupons

array

Grounded coupons only. A code must appear as its own token in the source. Multiple thresholds for the same code stay in tiers, not as duplicate coupons.

coupons[].code

string | null

Code as it appears in the source.

coupons[].type

string

One of percentage, fixed, free_shipping, gift, other, unknown.

coupons[].currency

string | null

ISO currency when the discount is a fixed amount. Null for percentage and most other types.

end_date

YYYY-MM-DD | null

Explicit calendar date in the source, then a countdown resolved against as_of, otherwise null.

Scope

coupons[].scope is an object of boolean flags. A key is present only when it is true. An empty object means no extra limits.

sitewide

boolean

The code applies store-wide, not to one product or category.

new_customers_only

boolean

The code is limited to first-time or new customers.

app_only

boolean

The code is limited to the merchant app.

Tiers

coupons[].tiers holds spend thresholds for the same code. Sort is not guaranteed. minimum_spend is always present. Discount keys are omitted when they do not apply.

minimum_spend

number | null

Basket minimum for this tier. Null when there is no minimum.

discount_percent

number

Percent off. Used with type percentage.

discount_amount

number

Fixed amount off. Used with type fixed. Read with currency.

capped_discount

number

Maximum discount amount when a percent off is capped.

Campaign events

campaign_events is a string array of canonical event IDs named in the source. Empty when none are found. Output only IDs from this taxonomy. Do not invent an ID, and do not infer an event from the calendar date alone.

IDName
new_yearNew year
lunar_new_yearLunar new year
valentines_dayValentines day
international_womens_dayInternational womens day
easterEaster
mothers_dayMothers day
fathers_dayFathers day
labor_dayLabor day
members_dayMembers day
halloweenHalloween
black_fridayBlack friday
cyber_mondayCyber monday
christmasChristmas
boxing_dayBoxing day
singles_day_11_11Singles day 11 11
1_11 1
2_22 2
3_33 3
4_44 4
5_55 5
6_66 6
7_77 7
8_88 8
9_99 9
10_1010 10
12_1212 12
ramadanRamadan
eid_al_fitrEid al fitr
eid_al_adhaEid al adha
deepavaliDeepavali
mid_autumn_festivalMid autumn festival
vesak_dayVesak day
merdekaMerdeka
malaysia_dayMalaysia day
singapore_national_daySingapore national day
singapore_retail_saleSingapore retail sale
songkranSongkran
loy_krathongLoy krathong
indonesia_independence_dayIndonesia independence day
kartini_dayKartini day
tetTet
vietnam_national_dayVietnam national day
philippines_independence_dayPhilippines independence day
philippines_ber_monthsPhilippines ber months
australia_dayAustralia day
click_frenzyClick frenzy
french_daysFrench days
afterpay_dayAfterpay day
eofyEofy
back_to_schoolBack to school
back_to_workBack to work
graduationGraduation
wedding_seasonWedding season
travel_fairTravel fair

Campaign themes

campaign_themes is a string array of canonical theme IDs named in the source. Empty when none are found. Output only IDs from this taxonomy.

IDName
payday_salePayday sale
mid_month_saleMid month sale
month_end_saleMonth end sale
flash_saleFlash sale
weekend_saleWeekend sale
one_day_saleOne day sale
limited_time_saleLimited time sale
early_bird_saleEarly bird sale
clearance_saleClearance sale
warehouse_saleWarehouse sale
closing_down_saleClosing down sale
spring_saleSpring sale
summer_saleSummer sale
autumn_saleAutumn sale
winter_saleWinter sale
mid_season_saleMid season sale
end_of_season_saleEnd of season sale
mid_year_saleMid year sale
year_end_saleYear end sale
anniversary_saleAnniversary sale
member_saleMember sale
vip_saleVip sale
loyalty_saleLoyalty sale
new_customer_offerNew customer offer
app_exclusive_saleApp exclusive sale
online_exclusive_saleOnline exclusive sale
new_collectionNew collection
launch_saleLaunch sale
preorder_salePreorder sale
early_access_saleEarly access sale
last_chance_saleLast chance sale
mega_saleMega sale
super_brand_daySuper brand day
voucher_dayVoucher day
free_shipping_eventFree shipping event
bundle_saleBundle sale
buy_more_save_moreBuy more save more
friends_family_saleFriends family sale
student_saleStudent sale
travel_early_bookingTravel early booking
travel_last_minuteTravel last minute
tax_free_saleTax free sale
trade_in_eventTrade in event
gift_eventGift event
mystery_saleMystery sale
live_saleLive sale
bank_card_saleBank card sale
wallet_payment_saleWallet payment sale
newsletter_exclusiveNewsletter exclusive
private_salePrivate sale

Credits

A successful extract deducts one credit from the earliest-expiring pack. Failed extracts do not deduct. Unused credits expire 12 months after purchase.

Errors

400

Invalid request

Missing text, text too long, as_of is not a date, or model / format is unknown.

401

Unauthorized

Missing or invalid API key.

402

No credits

No remaining credits on an unexpired pack.

502

Extraction failed

Upstream extract did not complete. Credit is refunded.

JavaScript

const response = await fetch("https://affensus.com/api/extract", {
  method: "POST",
  headers: {
    Authorization: "Bearer aff_…",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    text: "Use code SAVE20 for 20% off your order",
    as_of: "2026-09-27",
    model: "latest",
    format: "json",
  }),
});

const data = await response.json();

Playground

Use Playground to try extract with your key. The API accepts json and toon. Playground can also preview TEXT. Empty model or format is latest and json.