Management API
These endpoints let you manage your tablrr data programmatically. Everything here can also be done through the tablrr UI — this API is for automation, bulk operations, and integrations.
Sites
List Sites
Get a paginated list of all verified sites.
Endpoint: GET /sites
Authentication: Required
Parameters:
page(query, optional): Page number (default: 1)
Response:
{
"data": [
{
"id": 1,
"domain": "example.com",
"status": "verified",
"verified_at": "2025-01-02T10:00:00Z",
"webhook_url": null,
"created_at": "2025-01-01T10:00:00Z",
"updated_at": "2025-01-02T10:00:00Z"
}
],
"meta": { "current_page": 1, "per_page": 50, "total": 5, "last_page": 1 },
"links": { "first": "...", "last": "...", "prev": null, "next": null }
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/sitesCreate Site
Register a new domain for API access.
Endpoint: POST /sites
Authentication: Required
Request body:
{ "domain": "example.com" }Response: 201 Created
{
"id": 1,
"domain": "example.com",
"status": "pending",
"verified_at": null,
"webhook_url": null,
"webhook_secret": "your-secret-key-here",
"created_at": "2025-01-01T10:00:00Z",
"updated_at": "2025-01-01T10:00:00Z"
}The webhook_secret is only included in the create response — store it securely.
Example:
curl -X POST https://api.tablrr.app/v1/sites \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"domain": "example.com"}'Get Site
Endpoint: GET /sites/{domain}
Authentication: Required
Response:
{
"id": 1,
"domain": "example.com",
"status": "verified",
"verified_at": "2025-01-02T10:00:00Z",
"webhook_url": null,
"created_at": "2025-01-01T10:00:00Z",
"updated_at": "2025-01-02T10:00:00Z"
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/sites/example.comUpdate Site
Endpoint: PATCH /sites/{domain}
Authentication: Required
Request body:
{ "webhook_url": "https://example.com/webhook" }Response: Returns the full updated site object.
Example:
curl -X PATCH https://api.tablrr.app/v1/sites/example.com \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"webhook_url": "https://example.com/webhook"}'Delete Site
Deletes the site and its associated API token.
Endpoint: DELETE /sites/{domain}
Authentication: Required
Response:
204 No Contenton success404 Not Found— site doesn't exist or belongs to another user
Example:
curl -X DELETE https://api.tablrr.app/v1/sites/example.com \
-H "Authorization: Bearer {token}"Operators
Get Operators Summary
Get a lightweight list of operators without relationships. Not paginated. Useful for building selection UIs and mapping operator IDs.
Endpoint: GET /operators/summary
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"
}
]
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/operators/summary
# Filter by type
curl -H "Authorization: Bearer {token}" \
"https://api.tablrr.app/v1/operators/summary?type=casino"List Operators
Get a paginated list of operators with all fields and relationships. Supports filtering by type and updated_since.
Endpoint: GET /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 timepage(query, optional): Page number (default: 1)
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: private, max-age=3600, ETag based on latest updated_at, Vary: Authorization
Example:
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
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators?updated_since=2025-01-10T10:00:00ZCreate Operator
Endpoint: POST /operators
Authentication: Required
Required fields: name, slug, type. All others are optional. Relationship fields (restricted_countries, supported_currencies, payment_methods, games, sports, software_providers) accept arrays of internal integer IDs.
Request body:
{
"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",
"affiliate_link": "https://example.com/affiliate",
"terms_and_conditions": "18+ T&Cs apply",
"terms_link": "https://example.com/terms",
"features": ["Live Dealer", "Mobile App"],
"tags": [1, 2],
"restricted_countries": [1, 2],
"supported_currencies": [1, 2],
"payment_methods": [1, 2],
"games": [1, 2]
}Response: 201 Created — returns the full operator object.
Example:
curl -X POST https://api.tablrr.app/v1/operators \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"name": "Example Casino", "slug": "example-casino", "type": "casino"}'Get Single Operator
Endpoint: GET /operators/{publicId}
Authentication: Required
Response: Full operator object including all fields and relationships (same shape as List Operators items).
Caching: Cache-Control: private, max-age=3600, ETag based on public_id and updated_at, Vary: Authorization
Error: 404 Not Found — operator doesn't exist or belongs to another user
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators/abc123def456Update Operator
Endpoint: PATCH /operators/{publicId}
Authentication: Required
All fields are optional. Relationship fields accept arrays of internal integer IDs and fully replace existing values when provided.
Request body:
{
"name": "Updated Casino",
"rating": 4.8,
"supported_currencies": [1, 2, 3]
}Response: Returns the full updated operator object.
Example:
curl -X PATCH https://api.tablrr.app/v1/operators/abc123def456 \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"rating": 4.8}'Delete Operator
Endpoint: DELETE /operators/{publicId}
Authentication: Required
Response:
204 No Contenton success404 Not Found— operator doesn't exist or belongs to another user
Example:
curl -X DELETE https://api.tablrr.app/v1/operators/abc123def456 \
-H "Authorization: Bearer {token}"List Operator Translations
Endpoint: GET /operators/{publicId}/translations
Authentication: Required
Parameters:
publicId(path, required)page(query, optional): Page number (default: 1)
Response:
{
"data": [
{
"id": 1,
"operator_id": 1,
"locale": "pt",
"data": { "name": "Cassino Exemplo", "description": "Um ótimo cassino" },
"updated_at": "2025-01-10T10:00:00Z",
"created_at": "2025-01-01T10:00:00Z"
}
],
"meta": { "current_page": 1, "per_page": 50, "total": 10, "last_page": 1 },
"links": { "first": "...", "last": "...", "prev": null, "next": null }
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators/abc123def456/translationsCreate Operator Translation
Create or update a translation for an operator in a specific locale.
Endpoint: POST /operators/{publicId}/translations
Authentication: Required
Request body:
{
"locale": "pt",
"data": {
"name": "Cassino Exemplo",
"description": "Um ótimo cassino",
"bonus": "100% até $500"
}
}Response: 201 Created — returns the translation object.
Example:
curl -X POST https://api.tablrr.app/v1/operators/abc123def456/translations \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"locale": "pt", "data": {"name": "Cassino Exemplo"}}'Get Operator Translation
Endpoint: GET /operators/{publicId}/translations/{id}
Authentication: Required
Response:
{
"id": 1,
"operator_id": 1,
"locale": "pt",
"data": { "name": "Cassino Exemplo", "description": "Um ótimo cassino" },
"updated_at": "2025-01-10T10:00:00Z",
"created_at": "2025-01-01T10:00:00Z"
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/operators/abc123def456/translations/1Update Operator Translation
Endpoint: PATCH /operators/{publicId}/translations/{id}
Authentication: Required
All fields are optional.
Request body:
{
"locale": "pt",
"data": { "name": "Cassino Atualizado" }
}Response: Returns the full updated translation object.
Example:
curl -X PATCH https://api.tablrr.app/v1/operators/abc123def456/translations/1 \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"data": {"name": "Cassino Atualizado"}}'Delete Operator Translation
Endpoint: DELETE /operators/{publicId}/translations/{id}
Authentication: Required
Response:
204 No Contenton success404 Not Found— translation doesn't exist or belongs to a different operator
Example:
curl -X DELETE https://api.tablrr.app/v1/operators/abc123def456/translations/1 \
-H "Authorization: Bearer {token}"Listings
Get Listings Summary
Get a lightweight list of all listings. Returns essential fields without full config. Not paginated.
Endpoint: GET /listings/summary
Authentication: Required
Response:
{
"data": [
{
"public_id": "abc123def456",
"name": "Example Listing",
"type": "table",
"style": "0",
"tags": [{ "id": 1, "name": "Featured" }],
"geo_enabled": false,
"geo_counts": null
}
]
}geo_counts is null when geo targeting is disabled. When enabled, it is an object keyed by uppercase country code with the count of operators visible to visitors from that country, plus a "default" key for operators with no geo restriction.
Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/summaryList Listings
Get a paginated list of all listings. Supports filtering by type and updated_since for incremental sync.
Endpoint: GET /listings
Authentication: Required
Parameters:
type(query, optional): Filter by listing typeupdated_since(query, optional): ISO 8601 timestamp — returns only listings updated after this timepage(query, optional): Page number (default: 1)
Response:
{
"data": [
{
"id": 1,
"public_id": "abc123def456",
"name": "Example Listing",
"type": "table",
"style": "0",
"config": {
"fields": [...],
"labels": [...],
"options": [...],
"css": [...]
},
"operators": [
{ "id": 42, "public_id": "op123", "name": "Example Casino", "position": 1 }
],
"tags": [{ "id": 1, "name": "Featured" }],
"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/listings?page=1",
"last": "https://api.tablrr.app/v1/listings?page=2",
"prev": null,
"next": "https://api.tablrr.app/v1/listings?page=2"
}
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/listings
# Incremental sync
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings?updated_since=2025-01-10T10:00:00ZCreate Listing
Endpoint: POST /listings
Authentication: Required
Request body:
{
"name": "My Listing",
"type": "table",
"style": "0",
"config": {},
"operator_ids": [1, 2, 3],
"tags": [1, 2]
}Response: 201 Created
{ "id": 1, "public_id": "abc123def456" }Example:
curl -X POST https://api.tablrr.app/v1/listings \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"name": "My Listing", "type": "table", "style": "0", "operator_ids": [1, 2, 3]}'Get Single Listing
Endpoint: GET /listings/{publicId}
Authentication: Required
Response:
{
"id": 1,
"public_id": "abc123def456",
"name": "Example Listing",
"type": "table",
"style": "0",
"config": { "fields": [...], "labels": [...], "options": [...], "css": [...] },
"operators": [
{ "id": 42, "public_id": "op123", "name": "Example Casino", "position": 1 }
],
"tags": [{ "id": 1, "name": "Featured" }],
"updated_at": "2025-01-10T10:00:00Z",
"created_at": "2025-01-01T10:00:00Z"
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" \
https://api.tablrr.app/v1/listings/abc123def456Update Listing
Endpoint: PATCH /listings/{publicId}
Authentication: Required
All fields are optional. Provide only the fields you want to update.
Request body:
{
"name": "Updated Listing",
"style": "0",
"operator_ids": [1, 2],
"tags": [1]
}Response:
{ "id": 1, "public_id": "abc123def456" }Example:
curl -X PATCH https://api.tablrr.app/v1/listings/abc123def456 \
-H "Authorization: Bearer {token}" \
-H "Content-Type: application/json" \
-d '{"name": "Updated Listing"}'Delete Listing
Endpoint: DELETE /listings/{publicId}
Authentication: Required
Response:
204 No Contenton success404 Not Found— listing doesn't exist or belongs to another user
Example:
curl -X DELETE https://api.tablrr.app/v1/listings/abc123def456 \
-H "Authorization: Bearer {token}"Enable Listing Page
Enable the standalone listing page. The listing will be accessible at a dedicated URL on tablrr's domain.
Endpoint: POST /listings/{publicId}/page/enable
Authentication: Required
Response: 204 No Content
Example:
curl -X POST https://api.tablrr.app/v1/listings/abc123def456/page/enable \
-H "Authorization: Bearer {token}"Disable Listing Page
Endpoint: POST /listings/{publicId}/page/disable
Authentication: Required
Response: 204 No Content
Example:
curl -X POST https://api.tablrr.app/v1/listings/abc123def456/page/disable \
-H "Authorization: Bearer {token}"Analytics
These endpoints read aggregated analytics data. For tracking events, see the Core API.
Get Analytics Views
Get view counts grouped by date, listing, and site.
Endpoint: GET /analytics/views
Authentication: Required
Rate limit: 60 requests per minute
Parameters:
range(query, optional):7d,14d, or30d(default:7d). Data covers through yesterday.listing_public_ids(query, optional): Filter by listing (e.g.listing_public_ids[]=abc123)site_domains(query, optional): Filter by site (e.g.site_domains[]=example.com)page(query, optional): Page number (default: 1)
Response:
{
"data": [
{ "date": "2025-01-10", "listing_id": 1, "site_id": 1, "count": 150 }
],
"meta": { "current_page": 1, "per_page": 50, "total": 100, "last_page": 2 },
"links": { "first": "...", "last": "...", "prev": null, "next": "..." }
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/analytics/views
# Last 30 days
curl -H "Authorization: Bearer {token}" \
"https://api.tablrr.app/v1/analytics/views?range=30d"Get Analytics Clicks
Get click counts grouped by date, listing, site, operator, and click type.
Endpoint: GET /analytics/clicks
Authentication: Required
Rate limit: 60 requests per minute
Parameters:
range(query, optional):7d,14d, or30d(default:7d)listing_public_ids(query, optional): Filter by listingsite_domains(query, optional): Filter by siteoperator_public_ids(query, optional): Filter by operatorclick_type(query, optional): Filter by"affiliate"or"terms"page(query, optional): Page number (default: 1)
Response:
{
"data": [
{
"date": "2025-01-10",
"listing_id": 1,
"site_id": 1,
"operator_id": 42,
"click_type": "affiliate",
"count": 25
}
],
"meta": { "current_page": 1, "per_page": 50, "total": 100, "last_page": 2 },
"links": { "first": "...", "last": "...", "prev": null, "next": "..." }
}Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization
Example:
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/analytics/clicks
# Filter by click type
curl -H "Authorization: Bearer {token}" \
"https://api.tablrr.app/v1/analytics/clicks?click_type=affiliate"Get Analytics Report
Get an aggregated summary with trends, time series, and top performers by operator, listing, and site.
Endpoint: GET /analytics/report
Authentication: Required
Rate limit: 60 requests per minute
Parameters:
range(query, optional):7d,14d, or30d(default:7d)listing_public_ids(query, optional): Filter by listingsite_domains(query, optional): Filter by siteoperator_public_ids(query, optional): Filter by operatorclick_type(query, optional): Filter by"affiliate"or"terms"
Response:
{
"summary": {
"totalViews": 1000,
"totalClicks": 50,
"ctr": 5.0,
"activeListings": 3,
"trends": { "views": 10.5, "clicks": -2.3, "ctr": 1.2 }
},
"timeSeries": {
"labels": ["2025-01-04", "2025-01-05", "..."],
"views": [100, 120, 95, 150, 110, 130, 295],
"clicks": [5, 8, 4, 9, 6, 7, 11]
},
"topOperators": [
{
"id": 42,
"name": "Example Casino",
"views": 500,
"clicks": 25,
"ctr": 5.0,
"trend": 10.5
}
],
"topListings": [
{
"id": 1,
"name": "Example Listing",
"public_id": "abc123",
"siteId": 1,
"siteName": "example.com",
"views": 300,
"clicks": 15,
"ctr": 5.0,
"trend": 8.2
}
],
"topSites": [
{
"id": 1,
"name": "example.com",
"views": 500,
"clicks": 30,
"ctr": 6.0,
"activeListings": 3
}
]
}Example:
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/analytics/report
# Last 30 days filtered by site
curl -H "Authorization: Bearer {token}" \
"https://api.tablrr.app/v1/analytics/report?range=30d&site_domains[]=example.com"