Ticket Company Sales API
Related documentation: Promoters Integration · Finance API
TICKET COMPANY SALES API
Section titled “TICKET COMPANY SALES API”Version: 1.0.0 (2026-07-13) Audience: external ticket companies, partners, internal developers Status: live
This is the doc you hand to a ticket company so they can push daily ticket sales into Kisum automatically. Sales land in Promoters (real-time event view) and flow daily to Finance, the source of truth for real income.
1. Authentication — one key per ticket company
Section titled “1. Authentication — one key per ticket company”Every request carries an API key in the x-api-key header:
x-api-key: tkv_<64 hex characters>- Keys are per ticket vendor, per promoter company. A key only sees the tickets assigned to that vendor inside that promoter’s company — never another tenant’s data.
- Keys are generated by the promoter in Promoters: Event → Tickets → vendor card → Sales API access → Generate key. The key is shown once; only its sha256 hash is stored (
ticket_vendor_api_keyscollection). - Rotating generates a new key and revokes the old one immediately. Revoking cuts access without affecting other ticket companies.
- This is NOT the platform
INTERNAL_API_KEY— the internal key is never shared with external partners.
Backend: middleware/ticket-vendor-key.middleware.js (authenticateTicketVendorKey) in Backend-Kisum-Promoters.
2. Endpoints
Section titled “2. Endpoints”Base URL: the Promoters backend base URL + /api.
GET /api/ticket-api/tickets
Section titled “GET /api/ticket-api/tickets”Lists the events and tickets assigned to the authenticated vendor, so the ticket company can map their internal products to Kisum ticketIds.
{ "data": { "vendorId": "…", "events": [ { "eventId": "…", "eventTitle": "…", "eventDate": "…", "eventStatus": "confirmed", "tickets": [ { "ticketId": "…", "title": "GA", "price": 50, "currency": "usd", "allocation": 1000, "comps": 50 } ] } ] }}POST /api/ticket-api/sales
Section titled “POST /api/ticket-api/sales”Push daily sales totals. Body:
{ "sales": [ { "ticketId": "…", "date": "2026-07-12", "quantity": 120, "comps": 4, "discount": 0 } ]}Rules:
dateisYYYY-MM-DD(UTC day).quantity= paid tickets sold that day (integer ≥ 0).compsoptional.discountoptional, decimal 0–1 applied to that day’s paid quantity.- Day-set semantics (idempotent): a push REPLACES that ticket+date’s previous API rows. Re-sending the same day (e.g. corrected totals) never double-counts. Manual rows entered in the Promoters UI are never touched.
- Max 200 rows per request. Per-row results — one bad row doesn’t reject the rest:
{ "data": { "processed": 2, "accepted": 1, "rejected": 1, "results": [ { "index": 0, "status": "ACCEPTED" }, { "index": 1, "status": "REJECTED", "error": "Ticket not found for this vendor" } ] } }- Standard capacity validation applies (cannot sell beyond the ticket’s saleable allocation; comps beyond the comp allocation are rejected).
3. What happens downstream
Section titled “3. What happens downstream”- Rows are written to
event_ticket_sold_historywithsource: 'api'(manual rows aresource: 'manual'); vendor payment terms update exactly like manual entry (addTicketSalevalidation chain). - Promoters shows sales in real time on the event’s Tickets tab. If someone opens the manual add-sales form for a ticket that receives API sales, the form shows a duplicate-entry warning.
- Income reaches Finance via the daily cron push (
/cron/finance-income-daily-push) or the per-event “Sync to Finance” button. In Finance the ticket income is LIVE (accruing, counts everywhere) until the promoter settles it after the event — after settlement Finance ignores further sync for that income (SETTLED_SKIPPED).
4. Key management endpoints (internal users)
Section titled “4. Key management endpoints (internal users)”Tenant-scoped (session auth + x-org), permission promoter.event.sales.edit / commercial edit:
| Method | Path | Purpose |
|---|---|---|
POST | /api/vendors/tickets/{vendorId}/api-key | Generate / rotate — returns the raw key ONCE |
GET | /api/vendors/tickets/{vendorId}/api-key | Status: key prefix, created, last used (never the key) |
DELETE | /api/vendors/tickets/{vendorId}/api-key | Revoke |
Backend: integrations/commands/ticket-api.command.js, routes in integrations/integrations.route.js.