Tab Pass Spend Limits
Restrict how much a specific pass holder can spend on a tab — for event budgets, corporate allowances, gift cards, or parental controls.
Tab Pass Spend Limits allow you to restrict how much a specific pass holder can spend on a tab. This feature enables controlled spending for use cases such as event budgets, corporate allowances, gift cards, or parental controls.
This guide is intended for third-party integrators using the GoTab API to manage tabs and tab passes programmatically.
Prerequisites
Section titled “Prerequisites”- Feature Flag: The
tab_pass_spend_limitsfeature flag must be enabled for your location(s). Contact your GoTab account representative to enable this feature. - API Credentials: You must have valid API credentials with appropriate permissions (
location:tabs,location:orders, ormanage:ordering). - Base URL: All endpoints use the base path
/api/v2/loc/{location}where{location}is your location’s unique identifier (URL name or locationUuid).
How spend limits work
Section titled “How spend limits work”Data structure
Section titled “Data structure”A spend limit consists of two properties:
amount(integer, required): The spending limit in cents (e.g.5000= $50.00)enforce(string, required): The enforcement mode — either"pre"or"post"
Enforcement modes
Section titled “Enforcement modes”| Mode | Behavior | Use case |
|---|---|---|
pre | Block before exceeding — An order that would cause the total spent to exceed the limit is blocked before it’s placed. | Strict budget enforcement (e.g. corporate expense limits) |
post | Allow last order — The order that reaches or crosses the limit is allowed, but the next order is blocked. | Flexible spending (e.g. event passes where you want to allow the final purchase) |
off | No limit enforced | Removes the spend limit from a pass |
Spent calculation
Section titled “Spent calculation”The spent amount is calculated as the sum of all non-pending and non-voided orders associated with the tab pass. This means:
- Orders with status
SENT,COMPLETE, orCLOSEDcount toward the spent amount - Orders with status
PENDINGorVOIDEDdo not count
API endpoints
Section titled “API endpoints”1. Get tab by tab pass
Section titled “1. Get tab by tab pass”Retrieve tab information including the current spend limit and spent amount for a specific tab pass.
Endpoint
Section titled “Endpoint”GET /api/v2/loc/{location}/tabs/passes/{x_pass_id}Parameters
Section titled “Parameters”| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
location | string | path | Yes | The unique identifier of the location |
x_pass_id | string | path | Yes | The external pass ID recognized by your system |
Response
Section titled “Response”The response includes a tab_pass object with spend limit information:
{ "tab_id": "12345", "tab_uuid": "tab_abc123xyz", "location_id": "67890", "status": "OPEN", "balance_due": 2500, "tab_pass": { "tab_pass_id": "98765", "tab_pass_uuid": "tp_def456uvw", "x_pass_id": "CARD-12345", "customer_name": "John Doe", "customer_phone": "+15551234567", "privileges": ["VIP"], "spend_limit": { "amount": 5000, "enforce": "post" }, "spent": 3250 }, "orders": [], "items": []}Key fields
Section titled “Key fields”tab_pass.spend_limit: The configured spend limit (nullif no limit is set)amount: Limit in centsenforce: Enforcement mode ("pre"or"post")
tab_pass.spent: Total amount spent on this pass in cents (sum of non-pending, non-voided orders)
Example: check remaining budget
Section titled “Example: check remaining budget”const response = await fetch('/api/v2/loc/my-location/tabs/passes/CARD-12345', { headers: { 'Authorization': 'Bearer YOUR_API_TOKEN' }});
const data = await response.json();const {spend_limit, spent} = data.tab_pass;
if (spend_limit) { const remaining = spend_limit.amount - spent; console.log(`Remaining budget: $${(remaining / 100).toFixed(2)}`);
if (spend_limit.enforce === 'pre' && spent >= spend_limit.amount) { console.log('This pass has reached its spending limit.'); }}2. Add items to tab by pass
Section titled “2. Add items to tab by pass”Add items to a tab using the tab pass identifier. This is the required endpoint for spend tracking.
Endpoint
Section titled “Endpoint”POST /api/v2/loc/{location}/tabs/passes/{x_pass_id}/itemsParameters
Section titled “Parameters”| Parameter | Type | Location | Required | Description |
|---|---|---|---|---|
location | string | path | Yes | The unique identifier of the location |
x_pass_id | string | path | Yes | The external pass ID recognized by your system |
Request body
Section titled “Request body”{ "items": [ { "productUuid": "prod_abc123", "quantity": 2, "modifiers": [ { "productUuid": "mod_xyz789", "quantity": 1 } ] } ], "spotUuid": "spot_def456", "orderDetails": { "phoneNumber": "+15551234567", "callNumber": "42" }, "customerId": "customer_123", "employeeId": "employee_456", "name": "John Doe"}Request body fields
Section titled “Request body fields”| Field | Type | Required | Description |
|---|---|---|---|
items | array | Yes | Array of items to add to the tab |
items[].productUuid | string | Yes | UUID of the product |
items[].quantity | integer | Yes | Quantity of the item |
items[].modifiers | array | No | Array of modifier objects |
spotUuid | string | Yes | UUID of the spot/location where the order is placed |
orderDetails | object | No | Additional order information |
orderDetails.phoneNumber | string | No | Customer phone number |
orderDetails.callNumber | string | No | Call number for order pickup |
customerId | string | No | GoTab customer ID (if known) |
employeeId | string | No | Employee/server ID processing the order |
name | string | No | Customer name (defaults to Customer) |
Response
Section titled “Response”{ "items": [], "orders": [], "tabUuid": "tab_abc123xyz"}Spend limit enforcement
Section titled “Spend limit enforcement”If the order would violate the spend limit, the API returns a 400 error:
{ "alerts": [ { "type": "danger", "message": "This pass has reached its spend limit.", "timeout": 4000 } ]}Enforcement behavior:
premode: Order is blocked ifspent + order_total > limitpostmode: Order is blocked ifspent >= limit(the previous order already reached the limit)
Example: add items with error handling
Section titled “Example: add items with error handling”async function addItemsToPass(xPassId, items) { try { const response = await fetch(`/api/v2/loc/my-location/tabs/passes/${xPassId}/items`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' }, body: JSON.stringify({ items: items, spotUuid: 'spot_abc123', orderDetails: { phoneNumber: '+15551234567' } }) });
if (!response.ok) { const error = await response.json(); if (error.alerts?.[0]?.message?.includes('spend limit')) { console.error('Spend limit reached for this pass'); // Handle spend limit error } throw new Error(error.alerts?.[0]?.message || 'Failed to add items'); }
return await response.json(); } catch (error) { console.error('Error adding items:', error); throw error; }}