Errors
All API errors follow a consistent format. The HTTP status code indicates the error category, and the response body contains a human-readable message.
Error Response Format
Every error response has the same structure:
Error Response
{
"error": "A human-readable error message"
}Some error responses include additional fields for programmatic handling:
Extended Error Response
{
"error": "You've used all 5 free links for today. Sign up for unlimited link creation!",
"code": "DAILY_LIMIT",
"signupUrl": "/login"
}HTTP Status Codes
| Code | Name | Description |
|---|---|---|
| 200 | OK | Request succeeded. Response body contains the requested data. |
| 201 | Created | Resource was successfully created (links, keys, webhooks). |
| 400 | Bad Request | Invalid request body, missing required fields, or validation error. Check the error message for details. |
| 401 | Unauthorized | Missing, invalid, expired, or revoked API key. Ensure your Authorization header uses the correct format. |
| 403 | Forbidden | Request blocked by bot detection (anonymous shorten endpoint only). |
| 404 | Not Found | The requested resource does not exist or does not belong to your account. |
| 409 | Conflict | Resource already exists (e.g. duplicate slug on the same domain, or domain already registered). |
| 429 | Too Many Requests | Rate limit exceeded. Check the Retry-After header and wait before retrying. |
| 500 | Internal Server Error | An unexpected error occurred on our end. If this persists, contact support. |
Common Error Messages
Authentication Errors
| Error | Cause | Fix |
|---|---|---|
| Missing or invalid API key | No Authorization header or key does not start with flyn_sk_live_ | Add header: Authorization: Bearer flyn_sk_live_... |
| Invalid or revoked API key | Key does not match any active key in the database | Check your key or create a new one in Settings |
| API key has expired | The key has passed its expiration date | Create a new key in Settings |
| Unauthorized | Session-based endpoint called without a valid login session | Log in to the dashboard first, or use an API key |
Link Errors
| Error | Cause | Fix |
|---|---|---|
| url is required | Missing or empty url field in request body | Provide a valid URL in the request body |
| Invalid URL | URL cannot be parsed or has no valid hostname | Ensure the URL has a valid format (e.g. https://example.com) |
| Unsupported URL protocol | Protocol is not http, https, ftp, mailto, tel, or sms | Use a supported protocol |
| Cannot shorten Flyn URLs | Attempted to shorten a flyn.to URL | You cannot create recursive short links |
| Private/internal URLs are not allowed | URL points to localhost, 10.x.x.x, 192.168.x.x, etc. | Use a publicly accessible URL |
| Slug can only contain letters, numbers, hyphens, and underscores | Invalid characters in custom slug | Use only a-z, A-Z, 0-9, -, _ |
| Slug must be 100 characters or fewer | Slug exceeds maximum length | Shorten your custom slug |
| This slug is reserved | Slug conflicts with a Flyn system route (api, login, docs, etc.) | Choose a different slug |
| This slug is already taken on this domain | Slug+domain combination already exists | Use a different slug or domain |
| No fields to update | PATCH request with empty body | Include at least one field to update |
| Invalid status. Use: active, expired, archived | Invalid status value in update | Use one of the three valid status values |
Domain Errors
| Error | Cause |
|---|---|
| Please enter a valid domain | Domain is empty, missing a TLD, or exceeds 253 characters |
| Invalid domain format | Domain contains invalid characters |
| You cannot add flyn.to as a custom domain | Attempted to register the default Flyn domain |
| This domain is already registered | Domain already exists in the system |
Webhook Errors
| Error | Cause |
|---|---|
| Webhook URL is required | Missing url in request body |
| Only HTTP/HTTPS URLs allowed | Webhook URL uses an unsupported protocol |
| Webhook URL must be a public address | URL points to a private/internal address |
| Select at least one event | Events array is empty or contains no valid events |
| Maximum 10 webhooks allowed | Account has reached the webhook limit |
| Events must be a non-empty array | Events field is not an array or is empty |
| Status must be active or inactive | Invalid status value in update |
| Maximum 5 active API keys allowed | Account has reached the API key limit |
Error Handling Best Practices
TypeScript Error Handling
async function createLink(url: string, slug?: string) {
const res = await fetch('https://www.flyn.to/api/links', {
method: 'POST',
headers: {
'Authorization': 'Bearer flyn_sk_live_...',
'Content-Type': 'application/json',
},
body: JSON.stringify({ url, slug }),
});
if (!res.ok) {
const { error } = await res.json();
switch (res.status) {
case 400: throw new Error(`Validation error: ${error}`);
case 401: throw new Error('Invalid API key');
case 409: throw new Error(`Slug "${slug}" is taken`);
case 429:
const retryAfter = res.headers.get('Retry-After');
throw new Error(`Rate limited. Retry in ${retryAfter}s`);
default: throw new Error(`API error (${res.status}): ${error}`);
}
}
return res.json();
}Was this page helpful? Spotted something wrong?