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

CodeNameDescription
200OKRequest succeeded. Response body contains the requested data.
201CreatedResource was successfully created (links, keys, webhooks).
400Bad RequestInvalid request body, missing required fields, or validation error. Check the error message for details.
401UnauthorizedMissing, invalid, expired, or revoked API key. Ensure your Authorization header uses the correct format.
403ForbiddenRequest blocked by bot detection (anonymous shorten endpoint only).
404Not FoundThe requested resource does not exist or does not belong to your account.
409ConflictResource already exists (e.g. duplicate slug on the same domain, or domain already registered).
429Too Many RequestsRate limit exceeded. Check the Retry-After header and wait before retrying.
500Internal Server ErrorAn unexpected error occurred on our end. If this persists, contact support.

Common Error Messages

Authentication Errors

ErrorCauseFix
Missing or invalid API keyNo Authorization header or key does not start with flyn_sk_live_Add header: Authorization: Bearer flyn_sk_live_...
Invalid or revoked API keyKey does not match any active key in the databaseCheck your key or create a new one in Settings
API key has expiredThe key has passed its expiration dateCreate a new key in Settings
UnauthorizedSession-based endpoint called without a valid login sessionLog in to the dashboard first, or use an API key

Link Errors

ErrorCauseFix
url is requiredMissing or empty url field in request bodyProvide a valid URL in the request body
Invalid URLURL cannot be parsed or has no valid hostnameEnsure the URL has a valid format (e.g. https://example.com)
Unsupported URL protocolProtocol is not http, https, ftp, mailto, tel, or smsUse a supported protocol
Cannot shorten Flyn URLsAttempted to shorten a flyn.to URLYou cannot create recursive short links
Private/internal URLs are not allowedURL 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 underscoresInvalid characters in custom slugUse only a-z, A-Z, 0-9, -, _
Slug must be 100 characters or fewerSlug exceeds maximum lengthShorten your custom slug
This slug is reservedSlug conflicts with a Flyn system route (api, login, docs, etc.)Choose a different slug
This slug is already taken on this domainSlug+domain combination already existsUse a different slug or domain
No fields to updatePATCH request with empty bodyInclude at least one field to update
Invalid status. Use: active, expired, archivedInvalid status value in updateUse one of the three valid status values

Domain Errors

ErrorCause
Please enter a valid domainDomain is empty, missing a TLD, or exceeds 253 characters
Invalid domain formatDomain contains invalid characters
You cannot add flyn.to as a custom domainAttempted to register the default Flyn domain
This domain is already registeredDomain already exists in the system

Webhook Errors

ErrorCause
Webhook URL is requiredMissing url in request body
Only HTTP/HTTPS URLs allowedWebhook URL uses an unsupported protocol
Webhook URL must be a public addressURL points to a private/internal address
Select at least one eventEvents array is empty or contains no valid events
Maximum 10 webhooks allowedAccount has reached the webhook limit
Events must be a non-empty arrayEvents field is not an array or is empty
Status must be active or inactiveInvalid status value in update
Maximum 5 active API keys allowedAccount 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?