Error Codes

March 18, 2026 ยท View on GitHub

Response Format

All API responses are JSON with a status field. Successful responses use "status": "success". Error responses use "status": "error" with a human-readable message.

Standard Error Response

{
  "status": "error",
  "message": "Description of what went wrong"
}

Error Response with Context

Most endpoints include a context field that provides structured information for programmatic consumers. The context string contains the endpoint name, description, accepted parameters, and a suggested fix.

{
  "status": "error",
  "message": "tunnel_token and profile_name required",
  "context": "save_profile: Snapshots tunnel settings into a saved profile | Params: tunnel_token, profile_name, profile_icon, profile_notes, profile_type | Error: tunnel_token and profile_name required | Fix: Provide the required parameters"
}

HTTP Status Codes

CodeMeaningWhen It Happens
200SuccessRequest succeeded. Always check the status field in the JSON body, as some 200 responses contain "status": "error".
400Bad RequestMissing or invalid parameters. The message field describes which parameter is wrong.
401UnauthorizedInvalid, expired, or missing authentication token. Verify your auth token is correct.
402Payment RequiredFeature requires a paid subscription. The profile or feature needs a Pro plan.
403ForbiddenAccess denied. You do not own the requested resource, or the action requires proof-of-work verification.
404Not FoundThe requested resource (tunnel, domain, profile, device, address) does not exist or does not belong to your account.
409ConflictResource conflict. Examples: domain already registered, profile already in use on another device, seat limit reached, profile limit reached, IP slot limit reached, site mismatch.
422Unprocessable EntityThe request was well-formed but the data cannot be processed. Example: invalid DNS record content for the specified record type.
423LockedThe resource is locked and cannot be modified. Occurs when a profile has ip_locked=1 and you attempt an address operation.
500Internal Server ErrorAn unexpected error occurred. Retry the request. If it persists, try a regional failover endpoint or contact support.
503Service UnavailableThe service is in a degraded state. Try a different regional endpoint.

Extended Error Fields

Some error responses include additional structured fields beyond status and message:

feature_required

Returned when an endpoint requires a subscription feature the account does not have.

{
  "status": "error",
  "message": "Pro subscription required for dedicated public IPv4",
  "feature_required": "dedicated_ip"
}

seat_limit

Returned when the account has reached its maximum number of device seats.

{
  "status": "error",
  "message": "Seat limit reached",
  "device_count": 6,
  "max_devices": 6
}

site_mismatch

Returned by address assignment when the address's geographic site does not match the profile's preferred server location. The response includes both locations so the client can display the conflict.

{
  "status": "error",
  "error": "site_mismatch",
  "message": "This address is at Miami, FL but \"Privacy Mode\" uses Zurich, CH. Addresses can only be assigned to profiles at their home location.",
  "ip_location": "Miami, FL",
  "ip_site_id": 1,
  "profile_location": "Zurich, CH",
  "profile_site_id": 5,
  "profile_name": "Privacy Mode"
}

Pass update_location=1 to automatically resolve the mismatch by updating the profile's location to match the address.

Profile Locked

Returned when attempting to modify addresses on a profile that has ip_locked=1.

{
  "status": "error",
  "message": "IPs are locked on this profile"
}

HTTP 423

Profile In Use

Returned when attempting an operation (load, lock, re-snapshot, lease) on a profile that is currently loaded on another connected device.

{
  "status": "error",
  "message": "This profile is already in use on \"iPhone 15 Pro\". Disconnect or switch profiles on that device first.",
  "in_use_by": "iPhone 15 Pro",
  "profile_id": 3
}

HTTP 409

Important Notes

  • HTTP 200 can contain errors. Always check the status field in the response body. Some legacy endpoints return HTTP 200 with "status": "error" in the JSON.
  • The context field is informational. It is designed for AI agents and programmatic consumers to understand endpoint behavior without external documentation.
  • Regional failover. When you receive 500 or 503 errors, retry against a different regional endpoint (config-us-east, config-us-west, config-eu-central).