API documentation

The Bullmark API, for your backend .

Two surfaces, one key. The ledger API reads and moves credit and cash on wallets you are allowed to touch. The voucher API verifies and redeems vouchers of your own brands at your own checkout. Every write is idempotent and every movement is sealed. Guides, SDKs and the full voucher reference live at developer.bullmark.net .

Before the first call

Base URL is https://api.bullmark.net . Every request carries your key in the X-Api-Key header; keys start with bm_live_ and are issued by Bullmark, bound to your Axowl organization. Money is what you would expect from the three kinds of money : an amount on a credit row is Brand Credit in dollars of face value, on a cash row it is USD.

Scopes

A key carries a comma-separated scope list. ledger.read reads balances and history. ledger.debit spends, refunds, withdraws. ledger.grant grants credit and books cash top-ups. voucher.read looks at vouchers, voucher.redeem reserves, redeems, claims and releases them. A call outside the key's scopes is a 401 .

Moving money

Every write that moves value — debit, refund, withdraw, auto-topup, grant, topup and the cash-refund calls — is a money call : the key must be bound to an Axowl org, and the request must also carry an Axowl-signed partner assertion as Authorization: Bearer … whose issuer matches that binding. Each key has a per-transaction ceiling; over it is a 403 . Reading and redeeming need neither.

Idempotency

Every write takes a refId — your own reference. Send the same refId twice and you get the same row back with idempotentReplay: true , never a second movement. Retry freely.

Owner keys

A wallet is named by its owner key: enduser:{guid} for a person, org:{guid} for a company, brand:{slug} for a brand. Credit is per brand, so most calls take owner and brand together. The platform's own credit lives under the brand __bullmark .

Rate limit

120 requests per minute per key, fixed window, no queue. Over it you get a 429 with nothing done. Reads and writes share the window.

Errors

Errors are JSON with an error string and, where useful, the numbers behind it. 400 bad input · 401 no key, wrong key or scope · 402 insufficient balance (with balance and required ) · 403 not yours, or over the ceiling · 404 nothing there · 409 state says no.

Ledger — /partner/ledger

One passbook, two tables underneath: credit rows and cash rows. History merges them newest first; each row says which it is in bucket ( cash , non-refundable , …) and what kind of movement in kind .

Route

Scope

What it does

GET /partner/ledger/balance ?owner=&brand=

ledger.read

Credit and cash balance of one wallet at one brand. balance is what can be spent there.

GET /partner/ledger/earnings ?owner=

ledger.read

Cash a business earned, across its brands — per-brand lines and the total.

GET /partner/ledger/history ?owner=&brand=&limit=

ledger.read

Movements, newest first, with the balances. Leave brand out for the person's whole passbook across every brand, platform credit included.

GET /partner/ledger/by-ref ?refId=

ledger.read

What actually left for one refId , credit and cash summed. For proration and reconciliation.

GET /partner/ledger/cash-topups ?owner=&brand=

ledger.read

Cash top-ups still holding value — what a cash refund can draw on.

POST /partner/ledger/debit

ledger.debit

Spend. {owner, brand, amount, refId, memo} , amount positive. Credit first, cash for the rest on an org wallet. 402 when short.

POST /partner/ledger/refund

ledger.debit

Give credit back for a debit. Same body as debit; the row is a Refund.

POST /partner/ledger/withdraw

ledger.debit

Pay an org's cash back to the cards it came from. Org wallets only.

POST /partner/ledger/auto-topup

ledger.debit

Charge the saved card off-session when a balance falls below the low line. 402 if the card declines, 502 if the payment provider is unreachable.

POST /partner/ledger/grant

ledger.grant

Grant non-refundable credit. {owner, brand, amount, refId, memo} .

POST /partner/ledger/topup

ledger.grant

Book a cash top-up an org paid through your gateway. Needs providerRef — a cash row without its receipt is a claim, not money.

POST /partner/ledger/cash-refund

ledger.debit

Refund part of a cash top-up. {owner, brand, topUpRefId, amount, refId} .

POST /partner/ledger/cash-refund/receipt

ledger.debit

Attach the gateway's receipt ( providerRef ) to a cash refund once it went through.

POST /partner/ledger/cash-refund/reverse

ledger.debit

Undo a cash refund that did not go through. Append-only — the book keeps both lines.

Vouchers — /partner/vouchers

A voucher is a claim about a price. Verify it, reserve it while your checkout runs, redeem it the instant the value is given, release it if the payment fails. All of it against vouchers of your own brands — the key's org binding says which.

Route

Scope

What it does

GET /partner/vouchers ?holder=&holder=

voucher.read

Vouchers of your brands held by up to eight end-users.

GET /partner/vouchers/{codeOrTicket}

voucher.read

Verify: the live state, the price owed at redemption ( priceUsd ), the term. Safe to call as often as you like.

GET /partner/vouchers/{codeOrTicket}/events

voucher.read

The voucher's sealed event chain — claimed, reserved, redeemed — with seal verification.

POST /partner/vouchers/reserve

voucher.redeem

Lock it for your checkout. {code} → a ticket token with an expiry. Asking twice returns the same ticket.

POST /partner/vouchers/redeem

voucher.redeem

The burn. {ticket | code, externalRef, note} — externalRef is your order id and what makes a retry safe.

POST /partner/vouchers/release

voucher.redeem

Give a reserved voucher back — the payment failed or the buyer left.

POST /partner/vouchers/claim

voucher.redeem

Claim a voucher for an end-user through a referral deal. {code, productId, holder, holderEmail} .

Verification, without a key

Anyone can read an entity's sealed chain at GET /integrity/events/{entityType}/{entityId} — each event's hash, its link to the previous one, and whether the chain is intact. No key, no login: this is how a customer, a brand or an auditor checks that the record was not rewritten.

Read first

Cash, Brand Credit and Bullmark Credit →

What an amount means on each kind of row, and which way money moves.

Related

Fees and where the money goes →

Who pays what — so a settlement line reconciles to the cent.

Need a key?

Keys are issued to registered companies. List your startup, and ask for a partner key with the scopes your integration needs.

List your startup → See all eight steps

Loading…
an unhandled error has occurred. reload