API Reference
Base URL
All API requests should be made to:
https://api.tablrr.app/v1Authentication
Most API endpoints require authentication using an API token. Include your token in the Authorization header:
Authorization: Bearer {your-token-here}Getting an API Token
If you want to access the API directly from your own applications or scripts, you need to follow these steps:
- Go to Settings > Sites & API Tokens in your tablrr account
- Click "Add Site"
- Enter you domain name
- Verify your site and the token will be shown to you
- Copy the token immediately - it won't be shown again
Requirements:
- Growth plan or higher subscription
Premium Template Access
If your listing uses a premium template, you need:
- Hobby plan or higher to use premium templates
- Free plan users can only use free templates
If you try to access a premium template listing without the required plan, you'll receive a 403 Forbidden error.
Rate Limiting
To prevent abuse, API endpoints have rate limits:
- Listing endpoints: 60 requests per minute
- Site verification endpoint: 10 requests per minute
If you exceed the rate limit, you'll receive a 429 Too Many Requests response. Wait a minute before trying again.
Error Responses
All API errors follow a consistent format:
{
"error": {
"code": "ERROR_CODE",
"message": "Human-readable error message",
"details": {}
}
}Common Error Codes
| Code | HTTP Status | Description |
|---|---|---|
RESOURCE_NOT_FOUND | 404 | The requested listing or resource was not found |
VALIDATION_FAILED | 422 | Request data is invalid or missing |
FORBIDDEN | 403 | Access denied (plan restriction or unauthorized) |
INTERNAL_ERROR | 500 | An internal server error occurred |
Endpoints
Health Check
Check if the API is available and responding.
Endpoint: GET /api/v1/health
Authentication: Not required
Response:
{
"status": "ok"
}Example:
curl https://api.tablrr.app/v1/healthGet Listing Embed Data
Get everything you need to embed a listing: HTML, CSS, JavaScript, and direct URLs to each asset.
Endpoint: GET /api/v1/listings/{publicId}/embed
Authentication: Required
Parameters:
publicId(path, required): The public ID of your listing (found in the listing URL or settings)country(query, optional): ISO 3166-1 alpha-2 country code (e.g.gb,de). When the listing has geo targeting enabled, only operators visible to visitors from this country are included in the HTML and structured data. CSS and JS are not affected. Omit to receive all operators regardless of geo rules. Ignored if geo targeting is not enabled on the listing.
Response:
{
"html": "<div>...</div>",
"css": "/* CSS styles */",
"js": "/* JavaScript code */",
"structured_data": "/* JSON data */",
"html_url": "https://api.tablrr.app/v1/listings/{publicId}/html",
"css_url": "https://api.tablrr.app/v1/listings/{publicId}/css",
"js_url": "https://api.tablrr.app/v1/listings/{publicId}/js",
"structured_data_url": "https://api.tablrr.app/v1/listings/{publicId}/structured_data",
"updated_at": "2025-01-10T10:00:00Z"
}Caching:
Responses include cache headers to help reduce bandwidth:
Cache-Control: public, max-age=3600(1 hour)ETagheader for conditional requests
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123/embed
# With geo targeting
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123/embed?country=gbGet Listing HTML
Get just the HTML content for a listing. Useful when you only need the markup.
Endpoint: GET /api/v1/listings/{publicId}/html
Authentication: Required
Parameters:
publicId(path, required): The public ID of your listingcountry(query, optional): ISO 3166-1 alpha-2 country code. Filters operators by country when geo targeting is enabled. Omit for all operators.
Response:
Returns HTML content with Content-Type: text/html; charset=UTF-8
Caching:
Cache-Control: public, max-age=3600(1 hour)ETagheader for conditional requests
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123/html
# With geo targeting
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123/html?country=deGet Listing CSS
Get just the CSS styles for a listing. Useful for loading styles separately or customizing them.
Endpoint: GET /api/v1/listings/{publicId}/css
Authentication: Required
Parameters:
publicId(path, required): The public ID of your listing
Response:
Returns CSS content with Content-Type: text/css; charset=UTF-8
Caching:
Cache-Control: public, max-age=3600(1 hour)ETagheader for conditional requests
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123/cssGet Listing JavaScript
Get just the JavaScript code for a listing.
Endpoint: GET /api/v1/listings/{publicId}/js
Authentication: Required
Parameters:
publicId(path, required): The public ID of your listing
Response:
Returns JavaScript content with Content-Type: application/javascript; charset=UTF-8
Caching:
Cache-Control: public, max-age=3600(1 hour)ETagheader for conditional requests
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123/jsGet Listing Structured Data
Get just the Schema.org ItemList JSON-LD structured data for a listing. Useful for injecting into the <head> section of your page for SEO.
Endpoint: GET /api/v1/listings/{publicId}/structured_data
Authentication: Required
Parameters:
publicId(path, required): The public ID of your listingcountry(query, optional): ISO 3166-1 alpha-2 country code. Filters operators by country when geo targeting is enabled. Omit for all operators.
Response:
Returns JSON-LD structured data with Content-Type: application/json; charset=UTF-8
Caching:
Cache-Control: public, max-age=3600(1 hour)ETagheader for conditional requests
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123/structured_data
# With geo targeting
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123/structured_data?country=gbGet Operators List
Get a lightweight list of operators for setup and mapping purposes. Returns only essential fields without relationships.
Endpoint: GET /api/v1/operators/list
Authentication: Required
Parameters:
type(query, optional): Filter by operator type (casino,sportsbook,forex,other)
Response:
{
"data": [
{
"public_id": "abc123def456",
"name": "Example Casino",
"slug": "example-casino",
"type": "casino"
},
{
"public_id": "xyz789ghi012",
"name": "Another Casino",
"slug": "another-casino",
"type": "casino"
}
]
}Caching:
Cache-Control: public, max-age=3600(1 hour)
Example:
# Get all operators
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators/list
# Filter by type
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators/list?type=casinoGet Operators Index
Get a paginated list of operators with all fields and relationships. Supports filtering and incremental sync.
Endpoint: GET /api/v1/operators
Authentication: Required
Parameters:
type(query, optional): Filter by operator type (casino,sportsbook,forex,other)updated_since(query, optional): ISO 8601 timestamp - returns only operators updated after this time
Response:
{
"data": [
{
"id": 1,
"public_id": "abc123def456",
"name": "Example Casino",
"slug": "example-casino",
"type": "casino",
"logo_url": "https://example.com/logo.png",
"rating": 4.5,
"bonus": "100% up to $500",
"description": "A great casino",
"features": ["Live Dealer", "Mobile App"],
"affiliate_link": "https://example.com/affiliate",
"terms_and_conditions": "18+ T&Cs apply",
"terms_link": "https://example.com/terms",
"custom_fields": {
"license": "Malta Gaming Authority"
},
"relationships": {
"restricted_countries": [
{ "code": "US", "name": "United States" }
],
"supported_currencies": [
{ "code": "USD", "name": "US Dollar" }
],
"payment_methods": [{ "code": "visa", "name": "Visa" }],
"software_providers": [{ "code": "netent", "name": "NetEnt" }],
"games": [{ "code": "slots", "name": "Slots" }],
"sports": [{ "code": "football", "name": "Football" }],
"tags": [{ "id": 1, "name": "VIP" }],
"custom_relationships": {
"licenses": [
{ "code": "mga", "name": "Malta Gaming Authority" }
]
}
},
"updated_at": "2025-01-10T10:00:00Z",
"created_at": "2025-01-01T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"per_page": 50,
"total": 100,
"last_page": 2
},
"links": {
"first": "https://api.tablrr.app/v1/operators?page=1",
"last": "https://api.tablrr.app/v1/operators?page=2",
"prev": null,
"next": "https://api.tablrr.app/v1/operators?page=2"
}
}Caching:
Cache-Control: public, max-age=3600(1 hour)ETagheader based on latestupdated_attimestamp
Example:
# Get all operators
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators
# Filter by type
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators?type=casino
# Incremental sync - only get operators updated since a specific time
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators?updated_since=2025-01-10T10:00:00Z
# Pagination
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators?page=2Get Single Operator
Get detailed information for a specific operator by public ID, including all fields and relationships.
Endpoint: GET /api/v1/operators/{publicId}
Authentication: Required
Parameters:
publicId(path, required): The public ID of the operator
Response:
{
"id": 1,
"public_id": "abc123def456",
"name": "Example Casino",
"slug": "example-casino",
"type": "casino",
"logo_url": "https://example.com/logo.png",
"rating": 4.5,
"bonus": "100% up to $500",
"description": "A great casino",
"features": ["Live Dealer", "Mobile App"],
"affiliate_link": "https://example.com/affiliate",
"terms_and_conditions": "18+ T&Cs apply",
"terms_link": "https://example.com/terms",
"custom_fields": {
"license": "Malta Gaming Authority"
},
"relationships": {
"restricted_countries": [{ "code": "US", "name": "United States" }],
"supported_currencies": [{ "code": "USD", "name": "US Dollar" }],
"payment_methods": [{ "code": "visa", "name": "Visa" }],
"software_providers": [{ "code": "netent", "name": "NetEnt" }],
"games": [{ "code": "slots", "name": "Slots" }],
"sports": [{ "code": "football", "name": "Football" }],
"tags": [{ "id": 1, "name": "VIP" }],
"custom_relationships": {
"licenses": [{ "code": "mga", "name": "Malta Gaming Authority" }]
}
},
"updated_at": "2025-01-10T10:00:00Z",
"created_at": "2025-01-01T10:00:00Z"
}Caching:
Cache-Control: public, max-age=3600(1 hour)ETagheader based onpublic_idandupdated_at
Error Responses:
404 Not Found- Operator with this public_id doesn't exist or belongs to another user
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators/abc123def456Usage Examples
Embed a Listing in Your Website
Option 1: Load Everything at Once
const response = await fetch(
'https://api.tablrr.app/v1/listings/abc123/embed',
{
headers: {
Authorization: 'Bearer your-token-here',
},
},
);
const data = await response.json();
// Inject HTML, CSS, and JS into your page
document.getElementById('listing-container').innerHTML = data.html;
const style = document.createElement('style');
style.textContent = data.css;
document.head.appendChild(style);
const script = document.createElement('script');
script.textContent = data.js;
document.body.appendChild(script);
// Inject structured data into <head> for SEO
const structuredDataScript = document.createElement('script');
structuredDataScript.type = 'application/ld+json';
structuredDataScript.textContent = JSON.stringify(data.structured_data);
document.head.appendChild(structuredDataScript);Option 2: Load Assets Separately
<!-- In your HTML -->
<div id="listing-container"></div>
<link rel="stylesheet" href="https://api.tablrr.app/v1/listings/abc123/css" />
<script src="https://api.tablrr.app/v1/listings/abc123/js"></script>
<script>
fetch('https://api.tablrr.app/v1/listings/abc123/html', {
headers: {
Authorization: 'Bearer your-token-here',
},
})
.then((response) => response.text())
.then((html) => {
document.getElementById('listing-container').innerHTML = html;
});
</script>Sync Operators to Your Site
// Fetch all operators for initial sync
const response = await fetch('https://api.tablrr.app/v1/operators', {
headers: {
Authorization: 'Bearer your-token-here',
},
});
const data = await response.json();
// Store operators in your database
for (const operator of data.data) {
// Save operator to your local database
saveOperator(operator);
}
// Handle pagination if there are more pages
if (data.links.next) {
// Fetch next page...
}Incremental Operator Sync
// Get last sync timestamp from your database
const lastSync = getLastSyncTimestamp(); // e.g., "2025-01-10T10:00:00Z"
// Fetch only operators updated since last sync
const response = await fetch(
`https://api.tablrr.app/v1/operators?updated_since=${lastSync}`,
{
headers: {
Authorization: 'Bearer your-token-here',
},
},
);
const data = await response.json();
// Update only changed operators
for (const operator of data.data) {
updateOperator(operator);
}
// Save current timestamp for next sync
saveLastSyncTimestamp(new Date().toISOString());Handle Errors
try {
const response = await fetch(
'https://api.tablrr.app/v1/listings/abc123/embed',
{
headers: {
Authorization: 'Bearer your-token-here',
},
},
);
if (!response.ok) {
const error = await response.json();
switch (error.error.code) {
case 'RESOURCE_NOT_FOUND':
console.error('Listing not found. Check the public ID.');
break;
case 'FORBIDDEN':
if (error.error.message.includes('premium template')) {
console.error(
'This listing uses a premium template. Upgrade to Hobby plan or higher.',
);
} else {
console.error(
'Access denied. Upgrade to Growth plan or higher for direct API access.',
);
}
break;
case 'VALIDATION_FAILED':
console.error('Invalid request:', error.error.details);
break;
default:
console.error('An error occurred:', error.error.message);
}
return;
}
const data = await response.json();
// Use the listing data
} catch (error) {
console.error('Network error:', error);
}Best Practices
- Store tokens securely: Never commit API tokens to version control or expose them in client-side code that's publicly accessible
- Handle errors gracefully: Always check response status codes and provide helpful error messages to users
- Respect rate limits: Implement retry logic with exponential backoff if you hit rate limits
- Cache responses: Use the ETag header for conditional requests to reduce bandwidth and improve performance
- Verify domains: Ensure your domain is verified in Settings > Sites before making browser-based requests
- Check plan requirements: Make sure your account has the required plan before attempting to use premium features or direct API access
- Pass country for geo-targeted listings: If the listing has geo targeting enabled, detect the visitor's country server-side (e.g. from a Cloudflare
CF-IPCountryheader or a GeoIP lookup) and pass it as?country=xx. Omitting the parameter returns all operators with no geo filtering applied.
Support
For API support, please contact support@tablrr.app.