Skip to content

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:

json
{
  "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:

bash
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/sites

Create Site

Register a new domain for API access.

Endpoint: POST /sites

Authentication: Required

Request body:

json
{ "domain": "example.com" }

Response: 201 Created

json
{
  "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:

bash
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:

json
{
  "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:

bash
curl -H "Authorization: Bearer {token}" https://api.tablrr.app/v1/sites/example.com

Update Site

Endpoint: PATCH /sites/{domain}

Authentication: Required

Request body:

json
{ "webhook_url": "https://example.com/webhook" }

Response: Returns the full updated site object.

Example:

bash
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 Content on success
  • 404 Not Found — site doesn't exist or belongs to another user

Example:

bash
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:

json
{
  "data": [
    {
      "public_id": "abc123def456",
      "name": "Example Casino",
      "slug": "example-casino",
      "type": "casino"
    }
  ]
}

Caching: Cache-Control: private, max-age=3600, ETag, Vary: Authorization

Example:

bash
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 time
  • page (query, optional): Page number (default: 1)

Response:

json
{
  "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:

bash
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:00Z

Create 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:

json
{
  "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:

bash
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:

bash
curl -H "Authorization: Bearer {token}" \
  https://api.tablrr.app/v1/operators/abc123def456

Update 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:

json
{
  "name": "Updated Casino",
  "rating": 4.8,
  "supported_currencies": [1, 2, 3]
}

Response: Returns the full updated operator object.

Example:

bash
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 Content on success
  • 404 Not Found — operator doesn't exist or belongs to another user

Example:

bash
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:

json
{
  "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:

bash
curl -H "Authorization: Bearer {token}" \
  https://api.tablrr.app/v1/operators/abc123def456/translations

Create Operator Translation

Create or update a translation for an operator in a specific locale.

Endpoint: POST /operators/{publicId}/translations

Authentication: Required

Request body:

json
{
  "locale": "pt",
  "data": {
    "name": "Cassino Exemplo",
    "description": "Um ótimo cassino",
    "bonus": "100% até $500"
  }
}

Response: 201 Created — returns the translation object.

Example:

bash
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:

json
{
  "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:

bash
curl -H "Authorization: Bearer {token}" \
  https://api.tablrr.app/v1/operators/abc123def456/translations/1

Update Operator Translation

Endpoint: PATCH /operators/{publicId}/translations/{id}

Authentication: Required

All fields are optional.

Request body:

json
{
  "locale": "pt",
  "data": { "name": "Cassino Atualizado" }
}

Response: Returns the full updated translation object.

Example:

bash
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 Content on success
  • 404 Not Found — translation doesn't exist or belongs to a different operator

Example:

bash
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:

json
{
  "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:

bash
curl -H "Authorization: Bearer {token}" \
  https://api.tablrr.app/v1/listings/summary

List 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 type
  • updated_since (query, optional): ISO 8601 timestamp — returns only listings updated after this time
  • page (query, optional): Page number (default: 1)

Response:

json
{
    "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:

bash
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:00Z

Create Listing

Endpoint: POST /listings

Authentication: Required

Request body:

json
{
  "name": "My Listing",
  "type": "table",
  "style": "0",
  "config": {},
  "operator_ids": [1, 2, 3],
  "tags": [1, 2]
}

Response: 201 Created

json
{ "id": 1, "public_id": "abc123def456" }

Example:

bash
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:

json
{
    "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:

bash
curl -H "Authorization: Bearer {token}" \
  https://api.tablrr.app/v1/listings/abc123def456

Update Listing

Endpoint: PATCH /listings/{publicId}

Authentication: Required

All fields are optional. Provide only the fields you want to update.

Request body:

json
{
  "name": "Updated Listing",
  "style": "0",
  "operator_ids": [1, 2],
  "tags": [1]
}

Response:

json
{ "id": 1, "public_id": "abc123def456" }

Example:

bash
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 Content on success
  • 404 Not Found — listing doesn't exist or belongs to another user

Example:

bash
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:

bash
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:

bash
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, or 30d (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:

json
{
  "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:

bash
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, or 30d (default: 7d)
  • listing_public_ids (query, optional): Filter by listing
  • site_domains (query, optional): Filter by site
  • operator_public_ids (query, optional): Filter by operator
  • click_type (query, optional): Filter by "affiliate" or "terms"
  • page (query, optional): Page number (default: 1)

Response:

json
{
  "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:

bash
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, or 30d (default: 7d)
  • listing_public_ids (query, optional): Filter by listing
  • site_domains (query, optional): Filter by site
  • operator_public_ids (query, optional): Filter by operator
  • click_type (query, optional): Filter by "affiliate" or "terms"

Response:

json
{
  "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:

bash
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"