@bullmark/sdk (TypeScript)
npm install @bullmark/sdkNode 18+. ESM. Server-side only — the key burns vouchers.
import { Bullmark } from '@bullmark/sdk';
const bm = new Bullmark({ apiKey: process.env.BULLMARK_API_KEY!, baseUrl: 'https://api.bullmark.net', // optional timeoutMs: 10_000, // optional fetch: myFetch, // optional — for tests or a proxy});The four calls
Section titled “The four calls”await bm.vouchers.inspect(codeOrTicket); // what do I owe them?await bm.vouchers.reserve({ code }); // hold it (optional)await bm.vouchers.redeem({ code, externalRef: order.id }); // burn itawait bm.vouchers.release({ ticket, reason: 'payment_failed' }); // give it backawait bm.integrity.verify(codeOrTicket); // check us, locallyredeem throws before making a request if externalRef is missing — the type says it is
required and the runtime agrees, because a missing reference is only discovered otherwise
by a customer losing a voucher to a network blip.
Reading a ticket off a URL
Section titled “Reading a ticket off a URL”import { readTicket } from '@bullmark/sdk';const ticket = readTicket(location.search); // ?bm_ticket=… → string | nullErrors
Section titled “Errors”import { BullmarkError } from '@bullmark/sdk';
try { await bm.vouchers.redeem({ code, externalRef: order.id });} catch (e) { if (e instanceof BullmarkError) { // e.status — HTTP status // e.message — our own words, written for a person. Show it. } throw e;}Verifying without the client
Section titled “Verifying without the client”If you already have a chain (from your own cache, or a webhook you stored):
import { verifyChain } from '@bullmark/sdk';const result = verifyChain(chain);computeRecordHash and stjString are exported too, for anyone porting the algorithm.