Developers

Integrate your ticketing or events platform with Tabanca

Tabanca Partner API (v1)

Integration contract for external platforms. Two flows plus a read-only catalogue:

  1. Hand-off in — send a holder of one of your tickets/items to Tabanca to resell it ("List on Tabanca").
  2. Sold callback out — when it sells, Tabanca calls your webhook so you can void the original and reissue to the buyer.
  3. Catalogue — read Tabanca's public listings and events.

No money moves between platforms in v1: Tabanca charges the buyer and pays the seller through its own payouts. The API communicates item lifecycle only.

Credentials

Tabanca issues you, per credential:

Value Use
key_id (pk_…) Public identifier, first half of your bearer token
Bearer secret (sk_…) Second half of your bearer token. Stored hashed by Tabanca — shown once
Hand-off signing secret (hs_…) HMAC key. Signs the hand-off links you mint, and signs the webhooks Tabanca sends you

Catalogue requests authenticate with:

Authorization: Bearer <key_id>.<bearer secret>

Scopes: catalogue:read, resale:handoff. Rate limit ~120 requests/minute per key. Rotation: ask for a second credential, migrate, then have the old one revoked — during the window both are valid.

Flow 1 — hand-off ("List on Tabanca")

Build a claims object, sign it, and link the holder to Tabanca.

{
  "partner": "your-slug",
  "external_ref": "YOUR-TICKET-REF-123",
  "kind": "ticket",
  "title": "Soca Brainwash — GA",
  "event_name": "Soca Brainwash",
  "event_date": "2026-02-14",
  "holder_email": "holder@example.com",
  "location": "Grenada",
  "image_url": "https://your-cdn/event-flyer.jpg",
  "suggested_price": 250,
  "currency": "XCD",
  "nonce": "unique-per-click"
}
  • kind: ticket | costume | other.
  • location (optional): where the item/event is — prefills the listing's location.
  • image_url (optional, https): event flyer or costume photo — prefills the listing's first image. The seller can replace it.
  • nonce: unique per click — each redeemed link burns its nonce, so generate a fresh token every time the button is pressed.
  • exp (optional, unix seconds): defaults to now + 15 minutes and may not exceed it.
  • Required: partner, external_ref, kind, title, holder_email, nonce.

Token: base64url(JSON claims) + . + hex HMAC-SHA256 of that base64url string, keyed with your hand-off signing secret. Sign the encoded string, not the raw JSON.

Link: https://tabanca.store/sell?handoff=<token>

A holder without a session is sent to Tabanca auth (sign in or create an account) and returned to the same link afterwards — your token survives the round trip, subject to its expiry. Their session email must equal holder_email; the token alone does not prove ownership. The listing form then arrives prefilled (type, title, event date, location, image, price suggestion; sale method fixed to online) and they publish.

Sellers do not need Tabanca seller verification to list a hand-off item — your signature stands in for it — but they are told at listing time that receiving their payout requires submitting banking details and getting verified. Re-generating a link for the same external_ref refreshes the draft; once the item is listed or sold, further redeems return already_listed / already_sold.

Partner-origin listings sell online only. This is enforced server-side and is not seller-configurable: the online purchase is what captures a verified buyer identity (the name and email in resale.sold) for you to reissue against, and it is the trigger for the callback. There is no offline/cash path for these listings.

Redeem errors your UI may want to handle if you probe POST /api/v1/handoff/redeem yourself: bad_signature, expired, exp_too_far, invalid_claims, unknown_partner, partner_disabled, holder_mismatch, already_redeemed, already_listed, already_sold.

Flow 2 — webhooks

Deliveries are POSTed to your configured webhook URL:

Content-Type: application/json
X-Tabanca-Event: resale.sold
X-Tabanca-Delivery: resale.sold:4:YOUR-TICKET-REF-123
X-Tabanca-Signature: t=1786466061,v1=<hex hmac>

Body:

{
  "event": "resale.sold",
  "delivery_id": "resale.sold:4:YOUR-TICKET-REF-123",
  "data": {
    "external_ref": "YOUR-TICKET-REF-123",
    "item_kind": "ticket",
    "buyer_email": "buyer@example.com",
    "buyer_name": "Buyer Name",
    "sold_at": "2026-08-11T19:00:00.000Z",
    "amount": 250,
    "currency": "XCD",
    "tabanca_listing_id": 321,
    "tabanca_order_id": 77
  }
}

On resale.sold, void the original item and reissue it to buyer_email. The sale is always an online purchase through Tabanca's checkout, so buyer_email and buyer_name are the identity the buyer paid under, and tabanca_order_id is always present.

Verify the signature: compute HMAC-SHA256 over <t>.<raw body> with your hand-off signing secret and compare to v1. Reject stale t values to prevent replays.

Respond 2xx quickly. Anything else retries with backoff (1m, 5m, 30m, 2h, 8h, 24h) and then dead-letters for manual review. Deliveries can arrive more than once — dedupe on X-Tabanca-Delivery.

Flow 3 — catalogue

All endpoints require Authorization: Bearer <key_id>.<secret> with catalogue:read.

Endpoint Notes
GET /api/v1/listings ?limit= (max 100), ?country=, ?category=, ?cursor=. Returns { data, next_cursor }
GET /api/v1/listings/{id-or-slug} Single listing
GET /api/v1/events Upcoming public events with ticket types. ?limit=, ?region=
GET /api/v1/events/{id-or-slug} Single event

Listing DTO: id, source (listing | vendor_product), slug, title, description, category, price, currency, images, seller_name, location, event_date, created_at, url. Event DTO adds ticket_types (name, price, sold_out).

Pagination is a keyset cursor: pass next_cursor back until it returns null.

Errors

Errors are { "error": "<code>" } with a conventional status: 401 bad or missing credentials, 403 disabled partner or missing scope, 404 not found, 409 conflict, 429 rate limited.

Testing

scripts/partner-simulator.mjs in the Tabanca repo plays your side of the integration: it mints signed hand-off links and runs a listener that verifies webhook signatures. See the header of that file for usage.

Your partner portal

Every partner has a portal at https://tabanca.store/partner. Sign in with a Tabanca account that your Tabanca contact has added to your partner's access list (your registered contact email works by default). The portal shows:

  • API keys — key IDs, scopes, and when each was last used. Secrets are displayed once at issue time and cannot be recovered; if one is lost, a replacement credential is issued.
  • Webhook endpoint — the URL Tabanca delivers events to. Editable here; must be https.
  • Recent deliveries — each webhook attempt with status, HTTP response and error detail. A delivery that has exhausted its retries shows a Redeliver button, which requeues it for the next delivery run.
  • API usage — your call volume for the last 30 days, per endpoint and status class, from the same rollups the Tabanca team monitors.