Error Codes
All Tolinku API errors return a JSON object with an error field containing a human-readable message.
Error response format
Section titled “Error response format”{ "error": "Human-readable error message"}Plan enforcement errors include an additional code field:
{ "error": "This feature requires a paid plan", "code": "FEATURE_GATED"}Usage limit errors also include current usage data:
{ "error": "API call limit exceeded", "code": "USAGE_EXCEEDED", "usage": { "clicks": 55000, "clicksLimit": 50000, "apiCalls": 110000, "apiCallsLimit": 100000 }}HTTP status codes
Section titled “HTTP status codes”| Status | Meaning | Common causes |
|---|---|---|
400 | Bad Request | Missing required field, invalid format, validation failure |
401 | Unauthorized | Missing or invalid API key |
403 | Forbidden | Publishable key used on a secret-only endpoint, feature gated, usage exceeded, Appspace frozen |
404 | Not Found | Resource does not exist (route, referral, audience, message) |
429 | Too Many Requests | Rate limit exceeded (1,000 req/min for API, 60 req/min for clicks) |
500 | Internal Server Error | Unexpected server error |
Plan enforcement codes
Section titled “Plan enforcement codes”These codes appear in the code field of 403 responses:
| Code | Meaning | Resolution |
|---|---|---|
FEATURE_GATED | The feature is not available on the free tier | Upgrade to a paid plan (Standard or higher) |
USAGE_EXCEEDED | The Appspace has exceeded 110% of its plan’s click or API call limit | Upgrade to a higher tier, or wait for the next billing cycle |
APPSPACE_FROZEN | The Appspace is frozen due to a billing issue | Update your payment method in billing settings |
Common errors by endpoint
Section titled “Common errors by endpoint”Authentication
Section titled “Authentication”| Error | Status | Cause |
|---|---|---|
Invalid or missing API key | 401 | The X-API-Key header is missing, or the key does not exist or has been revoked |
This endpoint requires a secret API key | 403 | A publishable key (tolk_pub_) was used on an endpoint that requires a secret key (tolk_sec_) |
Analytics tracking
Section titled “Analytics tracking”| Error | Status | Cause |
|---|---|---|
event_type is required | 400 | The event_type field is missing from the request body |
event_type must start with "custom." | 400 | Custom events must use the custom. prefix |
event_type must match pattern: custom.[a-z0-9_]+ | 400 | The event name contains invalid characters (use only lowercase letters, numbers, underscores) |
event_type must be 100 characters or less | 400 | The event name is too long |
Custom events are not available on the free tier | 403 | Upgrade to a paid plan to use custom event tracking |
Referrals
Section titled “Referrals”| Error | Status | Cause |
|---|---|---|
user_id is required | 400 | Missing user_id when creating a referral code |
Maximum referrals per user reached | 400 | The user has hit the per-user referral limit set in your Appspace settings |
Referrals are not enabled for this Appspace | 403 | Referrals are not configured in your Appspace settings |
Referral not found | 404 | The referral code does not exist |
Referral not found or already completed | 404 | The referral has already been completed and cannot be completed again |
Deep links
Section titled “Deep links”| Error | Status | Cause |
|---|---|---|
Missing prefix | 400 | The prefix field is missing from the route resolution request |
Missing token parameter | 400 | The token query parameter is missing from the deferred claim request |
No app configured for this domain | 404 | The hostname does not match any Appspace |
Route not found | 404 | No route exists with the given prefix |
No matching deferred link found | 404 | No deferred link matches the token or device signals |
Messages
Section titled “Messages”| Error | Status | Cause |
|---|---|---|
API key or render token required | 401 | The render endpoint requires either an API key or a valid render token |
Invalid or expired render token | 401 | The render token has expired; generate a new one |
Message not found | 404 | The message ID does not exist |
Message has no content | 404 | The message exists but has no visual content to render |
Audiences
Section titled “Audiences”| Error | Status | Cause |
|---|---|---|
user_id query parameter is required | 400 | The user_id parameter is missing from the membership check |
Audience not found | 404 | The audience/segment ID does not exist |
Handling errors
Section titled “Handling errors”const res = await fetch(url, { headers: { 'X-API-Key': key } });
if (!res.ok) { const body = await res.json(); console.error(`API error ${res.status}: ${body.error}`);
if (body.code === 'USAGE_EXCEEDED') { // Handle usage limit }}