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