Brizz

Model B

You upload your codes

You already have a batch of codes. Give them to Brizz once — by CSV in the dashboard, or one API call — and checkout matches them locally with no live dependency on your systems.

You build a CSV, or one API call

Flow

PARTNERBRIZZEND USERAHEAD OF TIMEAT CHECKOUT — THE CUSTOMER IS WAITINGYou generate codesStores your codesGets code from youEnters at checkoutMatched locallyDiscount appliedPays lessupload once — CSV or APIno partner involvement at checkout
One upload ahead of time, then the partner lane goes quiet. From checkout onward this is identical to Model A — only the origin of the codes differs.

What you need from your side

  • RequiredYour list of codesThe only hard requirement. Upload it as a CSV from the dashboard and you are done — no engineering involvement at all.
  • OptionalAn API key with codes:writeOnly if you would rather import programmatically than upload a file. It is one HTTP call.
  • OptionalA webhook endpointOnly if you would rather not poll. Receives code.redeemed, signed with a secret we issue.

Authentication

Keys are issued per partner in the Brizz admin. The secret is shown once at creation and never again — Brizz stores only HMAC-SHA256(pepper, secret), so a database leak never yields a usable key. Keys are independently rotatable and revocable.

Base URL and credential
# Base URL
https://api.brizz.me/api/partner/v1

# Every request — bearer only, no alternative header accepted
Authorization: Bearer brz_partner_<credential_id>.<secret>

Scopes

Each key carries an explicit least-privilege scope set. A key with only codes:read can never mint.

ScopeGrants
campaigns:readList your campaigns and their state
codes:readCheck the status of a single code
codes:writeMint or import codes into a campaign
redemptions:readPull redemptions for reconciliation

Error responses are deliberately uninformative

A missing key, a wrong key, a revoked key and an insufficient scope all return the same response. Nothing distinguishes them, so a caller probing for valid keys or scopes learns nothing.

Endpoints

EndpointScopeRate limitPurpose
GET /campaignscampaigns:read300/minYour campaigns
POST /codes/statuscodes:read300/minOne code's state
POST /campaigns/{uuid}/codescodes:write10/minMint or import
GET /campaigns/{uuid}/redemptionsredemptions:read30/minPaginated redemptions

A shared ceiling of 600/min per partner applies across all endpoints, plus 60/min per IP before authentication. Exceeding a limit returns 429.

Importing your codes

Same endpoint as Model A's mint — the request body decides which happens.

POST /api/partner/v1/campaigns/{uuid}/codes
# scope: codes:write
Authorization: Bearer brz_partner_<credential_id>.<secret>
Idempotency-Key: 9a1b…

{
  "codes": [
    "PARTNER-AB12",
    "PARTNER-CD34"
  ]
}

The response reports imported and skipped counts, so duplicates in your batch are visible rather than silently dropped. Idempotency-Key is required and a replay returns the original result.

Checking a code

POST /api/partner/v1/codes/status
# →
{ "code": "PARTNER-AB12" }

# ← 200
{
  "code": {
    "status": "REDEEMED",
    "redeemed_at": "2026-07-22T18:04:11+00:00",
    "campaign_uuid": "…"
  }
}

A code moves AVAILABLE RESERVED REDEEMED, and REFUNDED if the booking is refunded. No buyer identity is ever returned — status, timestamp and owning campaign only.

Webhooks

Rather than poll, subscribe. Brizz pushes code.redeemed to your URL, signed so you can verify authenticity. Delivery is at-least-once with retry and backoff — dedupe on the event id.

Webhook headers
X-Brizz-Timestamp: 1784654651        # unix seconds
X-Brizz-Event-Id:  <uuid>            # dedupe key
X-Brizz-Signature: v1=<hex>[,v1=<hex>]

# HMAC-SHA256 over the exact transmitted bytes:
#   "{timestamp}.{event_id}.{raw_body}"

The dual v1=,v1= form appears only during a signing-secret rotation: the previous secret stays valid for a 24-hour grace window, so you can switch over with no dropped deliveries.

Reconciliation reports

Every campaign produces a report of what was redeemed and what is owed — downloadable from the dashboard at any time, and optionally emailed to you monthly plus a final one when the campaign closes.

GET /api/partner/v1/campaigns/{uuid}/redemptions
# ?from=&to=&cursor=&limit=
# from + to are REQUIRED (UTC; a date-only value expands to the whole day)
# keyset-paginated by (redeemed_at, id) · limit default 100, max 500

Every row carries code, status, redeemed_at and event, alongside invoice_total_eur, redeemed_count and refunded_count.

Brizz uses cookies to improve your experience and measure site usage. You can manage your preferences at any time.