Always inspect the HTTP status and content type before using a response. Client API success is JSON; Business API generation success is plain text.
JSON responses
Client API response fields sit at the top level beside success and message. There is no universal data wrapper.
{
"success": true,
"message": "Configuration message updated",
"configuration_id": 12,
"configuration_name": "My configuration",
"config_unique_key": "0123456789abcdef0123456789abcdef",
"config_message": "Welcome!"
}
Every Client and Business API error returns success: false, a stable string error code, a human-readable message, and an errors object. errors is empty when there are no field errors. Rate/quota errors can also include their details and headers. This applies to validation, authentication, middleware failures, and unsupported methods.
{
"success": false,
"error": "validation_failed",
"message": "The given data was invalid.",
"errors": {
"name": ["The name field is required."]
}
}
Troubleshoot by status
| Status | Meaning | What to do |
|---|---|---|
200 |
Read, update, delete, sync, or generation succeeded | Parse JSON for Client; preserve plain text for Business generation |
201 |
An individual server or tweak was created | Read server or tweak and save its key; Location identifies the resource |
400 |
Invalid operation or malformed app request | Check the endpoint's required input |
401 |
Missing or invalid authentication | Use the correct API key in a supported header; check rotation |
403 |
Access unavailable or ownership denied | Check account status and configuration owner; internal server detail reads are forbidden |
404 |
Configuration, access record, or target resource not found | Copy the key/ID from a current list response |
405 |
This HTTP method is not supported | Check PATCH versus PUT and the endpoint path; inspect the Allow header |
409 |
A one-time share has already been consumed (app import) | Generate or distribute a new share if another import is needed |
410 |
Cloud share expired (app import) | Obtain a new share; this does not alter previously imported copies |
413 |
Cloud export exceeds the size limit | Reduce generated content or use direct delivery |
422 |
Validation failed | Read each field in errors; batch paths include array indexes |
429 |
Burst limit or daily quota reached | Wait for Retry-After; inspect error and quota headers |
500 |
Generation, delivery, or resource processing failed | Preserve diagnostic information and check the outcome before retrying a mutation |
503 |
API or quota service unavailable | Respect Retry-After when present and retry later |
Messages can be localized. Do not build control flow around a specific English sentence.
Burst limits
The Client API's configured burst limit is 60,1 (attempts, minutes). It also passes through the general API IP limiter. Business requests use their account-specific limiter; consult your Business account for the effective allowance.
| Header | Meaning |
|---|---|
X-RateLimit-Limit |
Maximum attempts in the current rate window |
X-RateLimit-Remaining |
Remaining attempts |
X-RateLimit-Reset |
Reset Unix timestamp when supplied |
Retry-After |
Seconds to wait before retrying |
Repeated invalid Business authentication attempts have a separate IP-based limiter. An authentication_rate_limited error requires waiting even if you subsequently correct the key.
Daily quota
Quotas reset at 00:00 UTC and are separate from burst limits.
| API | When a unit is consumed |
|---|---|
| Client | Every authenticated request that passes the rate limiter, including reads and requests that later return validation/ownership errors |
| Business | After request validation succeeds, before generation; later generation or delivery failures still count |
The configured Client default is 1000 requests per UTC day. Account overrides can change the effective limit. The Business account page displays its effective rate and quota; installation settings and account overrides can change them. Rotation does not reset usage.
| Header | Meaning |
|---|---|
X-DailyQuota-Limit |
Daily allowance |
X-DailyQuota-Used |
Units consumed today |
X-DailyQuota-Remaining |
Units remaining today |
X-DailyQuota-Reset |
Next reset as a Unix timestamp |
Daily exhaustion returns HTTP 429 with error: "daily_quota_exceeded", quota details, and Retry-After. Read headers from the actual response rather than assuming the default quota applies to your account.
Retry without creating duplicates
An individual POST creation assigns a new key every time. Batch sync also creates a new resource when its entry omits unique_key. Before retrying after a lost response, list the configuration's resources and check whether the operation completed. Business generation creates fresh keys on each call and has no idempotency key.
For repeatable Client updates, retain the returned resource keys and update those resources. A failed transactional batch rolls back resource changes, but its quota unit is not refunded.
The API succeeds, but the app cannot connect
| Symptom | Check |
|---|---|
| App asks to add a tweak | Add a matching tweak even for direct connections; use methods: {} |
| Server disappears after selecting a tweak | Tunnel variant, carrier, exact accepted method set, and both categories; empty categories do not match named categories |
| Panel shows changes, but the app still shows old resources | Update source was included in the imported configuration; run an update or export/import again |
| Update reports a different configuration key | Serve the original configuration; a new Business generation is a new identity |
| One-time password works once, then fails | It is consumed on authentication; use reusable access for future authentications |
| Disabling an access record does not disconnect a user | An already issued authorization token can remain valid until expiry |
| A restriction works on Android but not iOS | Check the platform restriction table |
| A sample imports but cannot reach a host | Replace placeholder profiles/credentials and configure the actual tunnel service; validation does not contact the remote server |
Stable error codes
| Code | Typical status |
|---|---|
invalid_request |
400 |
unauthenticated |
401 |
forbidden |
403 |
not_found |
404 |
method_not_allowed |
405 |
conflict |
409 |
payload_too_large |
413 |
validation_failed |
422 |
rate_limited, authentication_rate_limited, daily_quota_exceeded |
429 |
internal_error |
500 |
service_unavailable |
503 |
More specific quota/service codes may accompany the same status. Handle unknown codes by HTTP status. Individual resource validation paths start at the request body, such as settings.credentials.password; batch paths include the index, such as servers.0.settings.credentials.password.