docs

Rate limits & errors

HTTP status codes, retry strategy, and the error envelopes on both the SDK and server side.

HTTP status codes

StatusMeaningRetry?
200 / 201 / 204Success.
400Malformed request body.No. Fix the request.
401API key missing, expired, or revoked.No. Refresh the key.
403Key valid but not scoped for this operation.No. Request new scope.
404Resource doesn't exist, or the subscriber was revoked.No.
409Conflict (duplicate creation).No. Read first, then write.
429Rate limited.Yes, with exponential backoff.
5xxTransient 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. Inspect nativeError and 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: propagate X-Request-Id into the SDK's nativeError field.

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.