Complete reference for the Scraper Portal API
Base URL:
/api/v1X-API-Key: your_api_key_here
/api/v1/events| Name | Type | Description |
|---|---|---|
| limit | integer | Number of events (1-100, default: 50) |
| offset | integer | Pagination offset (default: 0) |
| venue | string | Filter by venue name |
| sortBy | string | Sort field: date, name, venue, lastUpdated |
| sortOrder | string | Sort direction: asc, desc |
curl -H "X-API-Key: your_api_key_here" \
"/api/v1/events?limit=10"{
"data": [
{
"eventId": "EVENT123",
"name": "Concert Event",
"date": "2025-12-15",
"time": "7:00 PM",
"isoDate": "2025-12-15T19:00:00.000Z",
"location": "Main Arena",
"numberOfSeats": 150
}
],
"meta": {
"pagination": {
"total": 17,
"limit": 10,
"offset": 0,
"hasMore": true,
"nextOffset": 10
},
"filters": {
"venue": null,
"sortBy": "date",
"sortOrder": "asc"
}
}
}/api/v1/inventory| Name | Type | Required | Description |
|---|---|---|---|
| eventId | string | ✓ | Event mapping ID |
| listingId | string | - | Filter by specific listing ID |
| minPrice | number | - | Minimum price filter |
| maxPrice | number | - | Maximum price filter |
| quantity | integer | - | Required quantity (1-20) |
| sortBy | string | - | Sort field: price, section, row |
| sortOrder | string | asc | Sort direction: asc, desc |
curl -H "X-API-Key: your_api_key_here" \
"/api/v1/inventory?eventId=EVENT123&minPrice=50&maxPrice=200"/api/v1/orders{
"eventId": "EVENT123",
"listingId": "674e1234567890abcdef1234",
"quantity": 2,
"customer": {
"email": "buyer@example.com",
"phone": {
"number": "5551234567",
"countryCode": "+1"
}
}
}{
"eventId": "EVENT123",
"quantity": 2,
"section": "101",
"row": "A",
"customer": {
"email": "buyer@example.com",
"phone": {
"number": "5551234567",
"countryCode": "+1"
}
}
}curl -X POST -H "Content-Type: application/json" \
-H "X-API-Key: your_api_key_here" \
-d '{"eventId":"EVENT123","listingId":"674e1234567890abcdef1234","quantity":2,"customer":{"email":"buyer@example.com","phone":{"number":"5551234567","countryCode":"+1"}}}' \
/api/v1/orders/api/v1/ordersUpdate the status of an existing order. This endpoint requires API authentication and supports the same status flow as the admin dashboard.
{
"orderId": "order_1769082692221",
"status": "accepted"
}confirmedacceptedfulfilledcancelledTypical Order Flow: confirmed → accepted → fulfilled
Orders can be cancelled at any stage. Each status change triggers a webhook notification.
curl -X PATCH -H "Content-Type: application/json" \
-H "X-API-Key: your_api_key_here" \
-d '{"orderId":"order_1769082692221","status":"accepted"}' \
/api/v1/orders{
"success": true,
"message": "Order order_1769086588534 updated to accepted successfully",
"order": {
"orderId": "order_1769086588534",
"orderNumber": "TIC-KRLCH4H78",
"eventId": "4546456",
"eventName": "Boston Bruins Vs Vegas Golden Knights Boston",
"eventDate": "2026-01-22T10:00:00.000Z",
"eventVenue": "TD Garden",
"eventLocation": "Boston, MA",
"section": "Club Box 19",
"row": "A",
"listingId": "697200166edd0569d00c3d24",
"quantity": 2,
"status": "accepted",
"totalAmount": 150.66,
"customer": {
"email": "buyer@example.com",
"phone": {
"number": "5551234567",
"countryCode": "+1"
}
},
"createdAt": "2026-01-22T12:56:28.540Z",
"updatedAt": "2026-01-22T13:07:50.088Z",
"previousStatus": "confirmed"
},
"webhook": {
"event": "order.accepted",
"sent": true
},
"timestamp": "2026-01-22T13:07:50.475Z"
}Unified Status Updates: Our system notifies your endpoint instantly whenever an order status changes, whether triggered via API or manually by an Admin in the Dashboard.
Signed HTTP POST with JSON payload to your configured URL. HTTPS required in production.
X-Webhook-Signature: sha256=...Up to 5 retries with exponential backoff on non-200 responses. Respond within 30 seconds.
{
"event": "order.accepted",
"orderId": "order_1769086190205",
"order": {
"eventId": "4546456",
"eventName": "Boston Bruins Vs Vegas Golden Knights Boston",
"eventDate": "2026-01-22T10:00:00.000Z",
"eventVenue": "TD Garden",
"eventLocation": "Boston, MA",
"section": "Club Box 19",
"row": "A",
"listingId": "697200166edd0569d00c3973",
"quantity": 2,
"status": "accepted",
"totalAmount": 148.24,
"customer": {
"email": "buyer@example.com",
"phone": {
"number": "5551234567",
"countryCode": "+1"
}
},
"createdAt": "2026-01-22T12:49:50.220Z",
"updatedAt": "2026-01-22T12:52:52.509Z",
"previousStatus": "confirmed"
},
"timestamp": "2026-01-22T12:52:52.509Z"
}When an order is fulfilled, the webhook includes transfer method details showing how the ticket was delivered.
{
"event": "order.fulfilled",
"orderId": "order_1769086190205",
"order": {
"eventId": "4546456",
"eventName": "Boston Bruins Vs Vegas Golden Knights Boston",
"eventDate": "2026-01-22T10:00:00.000Z",
"eventVenue": "TD Garden",
"eventLocation": "Boston, MA",
"section": "Club Box 19",
"row": "A",
"listingId": "697200166edd0569d00c3973",
"quantity": 2,
"status": "fulfilled",
"totalAmount": 148.24,
"customer": {
"email": "buyer@example.com",
"phone": {
"number": "5551234567",
"countryCode": "+1"
}
},
"transferMethod": "mobile_transfer",
"transferNote": "Transferred via mobile transfer",
"previousStatus": "accepted",
"createdAt": "2026-01-22T12:49:50.220Z",
"updatedAt": "2026-01-22T14:30:00.000Z"
},
"timestamp": "2026-01-22T14:30:00.000Z"
}| Field | Type | Description |
|---|---|---|
| event | string | Event type (order.confirmed, order.accepted, etc.) |
| orderId | string | Unique order identifier |
| order.eventId | string | Event identifier |
| order.eventName | string | Full event name |
| order.eventDate | string | Event date in ISO 8601 format |
| order.eventVenue | string | Venue name where event takes place |
| order.section | string | Seating section |
| order.row | string | Seating row |
| order.listingId | string | Listing identifier reference |
| order.quantity | number | Number of tickets |
| order.status | string | Current order status |
| order.totalAmount | number | Total order amount in USD |
| order.customer.email | string | Customer email address |
| order.customer.phone | object | Customer phone with number and countryCode |
| order.transferMethod | string | How ticket was transferred (fulfilled orders only): mobile_transfer, digital_download, email, pickup |
| order.transferNote | string | Transfer details/instructions (fulfilled orders only) |
| order.createdAt | string | Order creation timestamp |
| order.updatedAt | string | Last update timestamp |
| order.previousStatus | string | Previous status (for status change events only) |
| timestamp | string | Webhook notification timestamp |
Webhook endpoints are configured by your account manager. You will receive an API Key and a Webhook Signing Secret for signature verification.
const express = require('express');
const crypto = require('crypto');
const app = express();
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;
// IMPORTANT: Use express.raw() to get the raw body for signature verification
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const timestamp = req.headers['x-webhook-timestamp'];
const rawBody = req.body.toString();
// 1. Verify signature
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(timestamp + '.' + rawBody)
.digest('hex');
const isValid = crypto.timingSafeEqual(
Buffer.from('sha256=' + expected),
Buffer.from(signature)
);
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// 2. Process the event
const payload = JSON.parse(rawBody);
console.log('Received:', payload.event, payload.orderId);
// 3. Return 200 quickly
res.json({ received: true });
});
app.listen(3000, () => console.log('Webhook listener running on port 3000'));Every webhook delivery includes these security headers:
| Header | Description |
|---|---|
| X-Webhook-Signature | HMAC-SHA256 signature: sha256=<hex> |
| X-Webhook-Timestamp | Unix epoch (seconds) when the webhook was sent |
| X-Webhook-Event | Event type, e.g. order.fulfilled |
| X-Webhook-Delivery | Unique delivery UUID (use for idempotency) |
The signature is computed as: HMAC-SHA256(secret, timestamp + "." + rawBody). The timestamp is included in the HMAC to prevent replay attacks.
const crypto = require('crypto');
const TOLERANCE_SECONDS = 1800; // 30 minutes (generous for manual workflows)
function verifyWebhook(rawBody, headers, secret) {
const signature = headers['x-webhook-signature'];
const timestamp = Number(headers['x-webhook-timestamp']);
// 1. Reject old deliveries (replay protection)
const age = Math.floor(Date.now() / 1000) - timestamp;
if (isNaN(timestamp) || age > TOLERANCE_SECONDS) {
throw new Error('Webhook timestamp too old (>30 min) — possible replay');
}
// 2. Compute expected signature: HMAC(secret, timestamp.body)
const expected = crypto
.createHmac('sha256', secret)
.update(timestamp + '.' + rawBody)
.digest('hex');
// 3. Constant-time comparison
const a = Buffer.from(`sha256=${expected}`);
const b = Buffer.from(signature);
if (a.length !== b.length || !crypto.timingSafeEqual(a, b)) {
throw new Error('Invalid webhook signature');
}
return JSON.parse(rawBody);
}
// Express handler:
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
try {
const payload = verifyWebhook(
req.body.toString(), req.headers, WEBHOOK_SECRET
);
switch (payload.event) {
case 'order.confirmed': break;
case 'order.fulfilled': break; // check payload.order.transferMethod
case 'order.cancelled': break;
}
res.json({ received: true });
} catch (err) {
res.status(401).json({ error: err.message });
}
});order.confirmedOrder received and confirmed by system
order.acceptedOrder accepted and processing begins
order.purchase_issuesIssues encountered during processing
order.fulfilledOrder successfully completed and delivered
order.cancelledOrder cancelled by admin or system
order.refundedOrder refunded to customer
order.confirmedorder.acceptedorder.fulfilledorder.cancelled