Skip to main content

Quote to Order Walkthrough

This guide walks through the complete purchase flow from authentication to a confirmed order with ticket transfer. Every step includes working code examples you can use directly in your integration.


Prerequisites

Before starting, make sure you have:

RequirementDetails
TBB Partner AccountProvisioned by Ticket Buyback
client_idIssued during onboarding
client_secretIssued during onboarding
Routable configuredRequired for quotes and orders — see Routable Setup

Full Flow Overview

Step 1 — Authenticate          POST /v1/auth/token
Step 2 — Find an Event GET /v1/events
Step 3 — Browse Sections GET /v1/events/{id}/sections
Step 4 — Browse Rows GET /v1/events/{id}/sections/{name}/rows
Step 5 — Create a Quote POST /v1/quotes
Step 6 — Create an Order POST /v1/orders
Step 7 — Deliver to Customer Share transfer_email with your customer

Step 1 — Authenticate

Exchange your credentials for a Bearer token.

JavaScript
async function getToken() {
const response = await fetch(
"https://api.ticketbuyback.com/partner/v1/auth/token",
{
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
client_id: process.env.TBB_CLIENT_ID,
client_secret: process.env.TBB_CLIENT_SECRET,
grant_type: "client_credentials",
}),
}
);

const { data } = await response.json();
return data.access_token;
}

const token = await getToken();
cURL
curl -X POST https://api.ticketbuyback.com/partner/v1/auth/token \
-H "Content-Type: application/json" \
-d '{
"client_id": "tbb_partner_clientid_abc123",
"client_secret": "tbb_partner_secret_xxxxxxxxxxxxxxxx",
"grant_type": "client_credentials"
}'
Store Credentials Securely

Always load client_id and client_secret from environment variables — never hardcode them in your source code.

What you get: access_token — valid for 1 hour.


Step 2 — Find an Event

Search for the event your customer wants to attend.

JavaScript
async function findEvent(token, query) {
const params = new URLSearchParams({
q: query,
date_from: new Date().toISOString().split("T")[0],
limit: 10,
});

const response = await fetch(
`https://api.ticketbuyback.com/partner/v1/events?${params}`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: "application/json",
},
}
);

const { data } = await response.json();
return data; // array of matching events
}

const events = await findEvent(token, "Patriots");
const event = events[0];
console.log(event.event_id); // "5496123"
console.log(event.event_name); // "New England Patriots vs. Buffalo Bills"
cURL
curl "https://api.ticketbuyback.com/partner/v1/events?q=Patriots&date_from=2026-09-01" \
-H "Authorization: Bearer <token>"

What you get: event_id — used in all downstream requests.


Step 3 — Browse Sections

Get all available sections for the selected event.

JavaScript
async function getSections(token, eventId) {
const response = await fetch(
`https://api.ticketbuyback.com/partner/v1/events/${eventId}/sections`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: "application/json",
},
}
);

const { data } = await response.json();
return data; // array of available sections
}

const sections = await getSections(token, event.event_id);
const section = sections[0];
console.log(section.section_name); // "101"
console.log(section.section_name_display); // "Section 101"
cURL
curl "https://api.ticketbuyback.com/partner/v1/events/5496123/sections" \
-H "Authorization: Bearer <token>"

What you get: section_name — used in the rows request and quote.


Step 4 — Browse Rows

Get all available rows within the selected section.

JavaScript
async function getRows(token, eventId, sectionName) {
const response = await fetch(
`https://api.ticketbuyback.com/partner/v1/events/${eventId}/sections/${sectionName}/rows`,
{
headers: {
Authorization: `Bearer ${token}`,
Accept: "application/json",
},
}
);

const { data } = await response.json();
return data; // array of available rows
}

const rows = await getRows(token, event.event_id, section.section_name);
const row = rows[0];
console.log(row.row_name); // "A"
console.log(row.row_name_display); // "Row A"
cURL
curl "https://api.ticketbuyback.com/partner/v1/events/5496123/sections/101/rows" \
-H "Authorization: Bearer <token>"
Skip Row Selection

You can omit row_name in the quote request without the row.

What you get: row_name — used in the quote request.


Step 5 — Create a Quote

Lock in a price for the selected section, row, and quantity.

JavaScript
async function createQuote(token, { eventId, sectionName, rowName, quantity }) {
const response = await fetch(
"https://api.ticketbuyback.com/partner/v1/quotes",
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
event_id: eventId,
section_name: sectionName,
row_name: rowName,
quantity,
}),
}
);

if (!response.ok) {
const { error } = await response.json();
throw new Error(`Quote failed: ${error.code}${error.message}`);
}

const { data } = await response.json();
return data;
}

const quote = await createQuote(token, {
eventId: event.event_id,
sectionName: section.section_name,
rowName: row.row_name,
quantity: 2,
});

console.log(quote.quote_id); // "qt_9f3a2b1c"
console.log(quote.pricing.unit_price); // 175.00
console.log(quote.pricing.subtotal); // 350.00
console.log(quote.expires_at); // "2026-02-26T11:00:00Z"
cURL
curl -X POST https://api.ticketbuyback.com/partner/v1/quotes \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"event_id": "5496123",
"section_name": "101",
"row_name": "A",
"quantity": 2
}'

What you get: quote_id + expires_at + confirmed pricing.

warning

Store expires_at and always check it before submitting an order. Expired quotes return 422 QUOTE_EXPIRED.


Step 6 — Create an Order

Convert the quote into a confirmed order.

JavaScript
async function createOrder(token, { quoteId, deliveryDeadline }) {
// Always check expiry before ordering
const response = await fetch(
"https://api.ticketbuyback.com/partner/v1/orders",
{
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
quote_id: quoteId,
delivery_type: "mobile_transfer",
delivery_deadline: deliveryDeadline,
}),
}
);

if (!response.ok) {
const { error } = await response.json();
throw new Error(`Order failed: ${error.code}${error.message}`);
}

const { data } = await response.json();
return data;
}

const order = await createOrder(token, {
quoteId: quote.quote_id,
deliveryDeadline: "2026-09-12T18:00:00Z",
});

console.log(order.order_id); // "TBB-20260226-X7K9"
console.log(order.status); // "awaiting_transfer"
console.log(order.delivery.transfer_email); // "transfer-inbox-abc123@ticketbuyback.com"
cURL
curl -X POST https://api.ticketbuyback.com/partner/v1/orders \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"quote_id": "qt_9f3a2b1c",
"delivery_type": "mobile_transfer",
"delivery_deadline": "2026-09-12T18:00:00Z"
}'

What you get: order_id + status + transfer_email.


Step 7 — Deliver Tickets to Your Customer

Share the transfer_email with your customer so they can accept the ticket transfer.

JavaScript — Example customer notification
function buildTransferMessage(order) {
const deadline = new Date(order.delivery.delivery_deadline)
.toLocaleString("en-US", { dateStyle: "long", timeStyle: "short" });

return `
Your tickets are confirmed!

Event: ${order.event.event_name}
Seats: ${order.seats.section_name_display}, ${order.seats.row_name_display}, Seats ${order.seats.seat_range}
Date: ${order.event.event_datetime_local}

Your tickets will be transferred from:
${order.delivery.transfer_email}

Please accept the transfer before ${deadline}.
Check your inbox and spam folder for the transfer email.

Order ID: ${order.order_id}
`;
}

const message = buildTransferMessage(order);
// Send via your own email/SMS system
Transfer Deadline

Your customer must accept the ticket transfer before delivery_deadline. If they miss it, the order status moves to transfer_expired. Contact support immediately with the order_id.


Complete End-to-End Example

Here is the full flow in a single function:

JavaScript — Full end-to-end flow
async function buyTickets({ query, quantity, deliveryDeadline }) {
// Step 1 — Authenticate
const token = await getToken();

// Step 2 — Find event
const events = await findEvent(token, query);
const event = events[0];

// Step 3 — Get sections
const sections = await getSections(token, event.event_id);
const section = sections[0];

// Step 4 — Get rows
const rows = await getRows(token, event.event_id, section.section_name);
const row = rows[0];

// Step 5 — Create quote
const quote = await createQuote(token, {
eventId: event.event_id,
sectionName: section.section_name,
rowName: row.row_name,
quantity,
});

// Check quote has not expired
if (new Date() >= new Date(quote.expires_at)) {
throw new Error("Quote expired before order could be placed.");
}

// Step 6 — Create order
const order = await createOrder(token, {
quoteId: quote.quote_id,
deliveryDeadline,
});

// Step 7 — Return transfer details for customer notification
return {
orderId: order.order_id,
transferEmail: order.delivery.transfer_email,
seats: order.seats,
pricing: order.pricing,
};
}

// Usage
const result = await buyTickets({
query: "Patriots",
quantity: 2,
deliveryDeadline: "2026-09-12T18:00:00Z",
});

console.log(result.transferEmail);
// → "transfer-inbox-abc123@ticketbuyback.com"

What Happens Next

Once the order is confirmed:

Order status: awaiting_transfer


Customer accepts transfer from transfer_email


Order status: transfer_complete


Customer attends the event 🎉

→ See Error Reference for handling any errors along the way.