Rate limits & errors
HTTP status codes, retry strategy, and the error envelopes on both the SDK and server side.
HTTP status codes
| Status | Meaning | Retry? |
|---|---|---|
200 / 201 / 204 | Success. | — |
400 | Malformed request body. | No. Fix the request. |
401 | API key missing, expired, or revoked. | No. Refresh the key. |
403 | Key valid but not scoped for this operation. | No. Request new scope. |
404 | Resource doesn't exist, or the subscriber was revoked. | No. |
409 | Conflict (duplicate creation). | No. Read first, then write. |
429 | Rate limited. | Yes, with exponential backoff. |
5xx | Transient server error. | Yes, with exponential backoff. |
Rate limits
Limits are applied per API key at the gateway. Published ceilings will
be added here before GA; until then, development-environment limits are
loose. When you hit a ceiling the gateway responds 429 with a
Retry-After header in seconds. Honor it.
async function withRetry<T>(fn: () => Promise<T>, attempt = 0): Promise<T> {
try {
return await fn();
} catch (e) {
if (e.code === 'API_RATE_LIMITED' && attempt < 3) {
const wait = Math.min(2 ** attempt * 1_000, 8_000);
await new Promise((r) => setTimeout(r, wait));
return withRetry(fn, attempt + 1);
}
throw e;
}
}
SDK error envelope
The SDK normalizes every failure into a PasspointError with a typed
code:
import { PasspointError, PasspointErrorCode } from '@helium/passpoint-sdk';
try {
await install(subscriberId);
} catch (e) {
if (e instanceof PasspointError) {
if (e.code === PasspointErrorCode.API_RATE_LIMITED) {
// back off and retry
}
}
}
The full catalog lives in SDK errors. The codes operations people care about:
API_UNAUTHORIZED: the key is bad. Don't retry; re-issue the key.API_RATE_LIMITED: back off as above.NETWORK_ERROR: usually connectivity on your side rather than Helium's. Retry.API_ERROR: a non-2xx that doesn't fit the above. InspectnativeErrorand surface it to support.
Server-side error envelope
Backend callers get the same status codes plus a JSON body:
{
"error": "subscriber_not_found",
"message": "no active subscriber for this id under this partner",
"request_id": "req_01HX..."
}
Always log request_id. Helium support uses it to look up your request
in the gateway logs.
Errors during the SDK's
install()flow are best-effort logged on the device. The server-side request ID is not currently surfaced to the SDK caller. TODO: propagateX-Request-Idinto the SDK'snativeErrorfield.
Rate limits and status codes here cover the Wi-Fi offload service only. The heliumOS platform API has its own limits and error contract: see rate limiting and errors.