Tickets Wholesale API
A modern API for real-time inventory, pricing, and order fulfillment at scale. Access requires an approved partner account. Contact our team to get started.
Edge caching and batched responses keep your flows snappy.
All traffic is TLS 1.3 with HSTS and audit logging.
Retry-friendly semantics and idempotent order creation.
Getting started
Below is a quickstart for integrating with the v1 REST API, with webhooks and SDKs for common stacks.
# 1) Authenticate curl -X POST https://api.wholesaletickets.ca/v1/oauth/token -H "Content-Type: application/json" -d '{ "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "grant_type": "client_credentials" }' # 2) Search inventory curl -X GET 'https://api.wholesaletickets.ca/v1/inventory/search?eventId=12345§ion=Floor' -H 'Authorization: Bearer YOUR_ACCESS_TOKEN'
- • OAuth 2.0 client credentials and fine-grained API keys
- • IP allowlists and optional mTLS on enterprise plans
- • Idempotency keys for safe retries
- • PII minimization and encrypted storage for sensitive fields
Authentication
Use OAuth 2.0 Client Credentials to obtain short-lived access tokens. Assign the minimum scopes required for the integration. Rotate client secrets regularly.
POST https://api.wholesaletickets.ca/v1/oauth/token Content-Type: application/json { "client_id": "YOUR_CLIENT_ID", "client_secret": "YOUR_CLIENT_SECRET", "grant_type": "client_credentials", "scope": "inventory.read orders.write" }
GET https://api.wholesaletickets.ca/v1/health Authorization: Bearer YOUR_ACCESS_TOKEN
Environments
Environment | Base URL | Notes |
---|---|---|
Sandbox | https://api.sandbox.wholesaletickets.ca | For testing and certification |
Production | https://api.wholesaletickets.ca | Requires approval and whitelisting |
Header | Example |
---|---|
Authorization | Bearer <access_token> |
Content-Type | application/json |
Idempotency-Key | Optional for writes (recommended) |
Use a versioned prefix like /v1
. Breaking changes will increment the major version. Minor changes are backwards compatible.
GET /v1/inventory/search?eventId=123&limit=50 200 OK { "items": [ ... ], "nextCursor": "eyJpZCI6ICJhYmMxMjMifQ==" } # Next page GET /v1/inventory/search?eventId=123&cursor=eyJpZCI6ICJhYmMxMjMifQ==
Endpoint overview
Representative endpoints for the partner API.
Provide a unique Idempotency-Key
header on POST/PUT requests. The server caches results for a short period and returns the same response to duplicate keys.
Header | Description |
---|---|
X-RateLimit-Limit | Max requests in current window |
X-RateLimit-Remaining | Requests left in window |
X-RateLimit-Reset | UTC epoch seconds when window resets |
{ "error": { "code": "rate_limited", "message": "Too many requests", "requestId": "req_abc123" } }
Use exponential backoff for 429/5xx. Do not retry 4xx except 409.
Webhooks security
Verify webhook signatures using the shared secret and timestamped HMAC. Reject events older than 5 minutes.
Header | Example |
---|---|
TW-Signature | t=1734650000,v1=ab12cd... |
Content-Type | application/json |
import crypto from 'crypto' function verifyWebhook(rawBody: string, header: string, secret: string): boolean { const parts = Object.fromEntries(header.split(',').map(kv => kv.split('='))) const ts = parts['t'] const sig = parts['v1'] const payload = ts + '.' + rawBody const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex') const recent = Math.abs(Date.now() / 1000 - Number(ts)) < 300 const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig)) return ok && recent }
- v1.0 • Inventory, Orders, OAuth 2.0
- v1.1 • Webhooks for orders and price updates
- v1.2 • SDKs and self-serve keys
Roadmap
- Inventory Search v1
- Orders v1 (idempotent)
- OAuth client credentials
- Docs site and examples
- TypeScript/Python SDKs
- Orders webhooks
- mTLS and IP allowlists
- Fine-grained API keys
- Service-level credits