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
There are two ways to get an API token, depending on how you plan to use the API:
1. Direct API Access (Growth Plan or Higher)
If you want to access the API directly from your own applications or scripts:
- Go to Settings > API Tokens in your tablrr account
- Click "Create Token"
- Give your token a name (e.g., "My WordPress Site")
- Copy the token immediately - it won't be shown again
Requirements:
- Growth plan or higher subscription
- Token is scoped to your account
2. WordPress Plugin (All Plans)
If you're using the official tablrr WordPress plugin:
- Install and activate the plugin on your WordPress site
- Enter your verification code from Settings > Sites in tablrr
- The plugin automatically verifies your site and creates a token
Requirements:
- Works with any plan (Free, Hobby, Growth, or Business)
- Token is automatically scoped to your verified domain
- Only works from the verified domain
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.
Domain Verification
Site-scoped tokens (created via WordPress plugin) can only be used from the domain they were verified for. This ensures your listings can only be embedded on your verified websites.
For browser-based requests, make sure:
- Your domain is verified in Settings > Sites
- Requests include the
Originheader matching your verified domain - Server-to-server requests (without Origin header) are allowed from any location
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 |
Validation Errors
When a request fails validation, the details object contains specific field errors:
{
"error": {
"code": "VALIDATION_FAILED",
"message": "The request validation failed.",
"details": {
"code": [
"The code field is required.",
"The code must be 32 characters."
]
}
}
}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
Plan Requirements:
- Direct API access: Growth plan or higher
- WordPress plugin: Any plan (but premium templates require Hobby+)
Parameters:
publicId(path, required): The public ID of your listing (found in the listing URL or settings)
Response:
{
"html": "<div>...</div>",
"css": "/* CSS styles */",
"js": "/* JavaScript code */",
"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",
"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/embedGet 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
Plan Requirements:
- Direct API access: Growth plan or higher
- WordPress plugin: Any plan (but premium templates require Hobby+)
Parameters:
publicId(path, required): The public ID of your listing
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/htmlGet 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
Plan Requirements:
- Direct API access: Growth plan or higher
- WordPress plugin: Any plan (but premium templates require Hobby+)
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
Plan Requirements:
- Direct API access: Growth plan or higher
- WordPress plugin: Any plan (but premium templates require Hobby+)
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/jsVerify Site (WordPress Plugin)
Verify your site during WordPress plugin setup. This endpoint is used automatically by the plugin - you typically don't need to call it directly.
Endpoint: POST /api/v1/sites/verify
Authentication: Not required (public endpoint)
Rate Limit: 10 requests per minute
Request Body:
{
"code": "32-character-verification-code",
"domain": "example.com"
}Parameters:
code(required, string, exactly 32 characters): The verification code from Settings > Sites in tablrrdomain(required, string): The domain you're verifying (e.g., "example.com" without protocol)
Response:
{
"message": "Site verified successfully",
"site": {
"id": 1,
"domain": "example.com",
"status": "verified"
},
"token": "site-scoped-api-token"
}Important: Store the returned token securely. This token is scoped to your verified domain and can only be used from that domain.
Errors:
422 Validation Failed: Invalid verification code or domain doesn't match
Example:
curl -X POST https://api.tablrr.app/v1/sites/verify \
-H "Content-Type: application/json" \
-H "Origin: https://example.com" \
-d '{
"code": "abc123def456ghi789jkl012mno345pq",
"domain": "example.com"
}'Usage 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);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>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);
}WordPress Plugin Integration
The official tablrr WordPress plugin handles site verification automatically. If you're building a custom integration, here's how it works:
$response = wp_remote_post('https://api.tablrr.app/v1/sites/verify', [
'headers' => [
'Content-Type' => 'application/json',
'Origin' => home_url()
],
'body' => json_encode([
'code' => $verification_code,
'domain' => parse_url(home_url(), PHP_URL_HOST)
])
]);
$body = json_decode(wp_remote_retrieve_body($response), true);
if (isset($body['token'])) {
// Store token securely in WordPress options
update_option('tablrr_api_token', $body['token']);
}Then use the token to fetch listing data:
$token = get_option('tablrr_api_token');
$response = wp_remote_get(
'https://api.tablrr.app/v1/listings/abc123/embed',
[
'headers' => [
'Authorization' => 'Bearer ' . $token,
],
]
);
$data = json_decode(wp_remote_retrieve_body($response), true);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
Support
For API support, please contact support@tablrr.app.