Skip to main content

Protecting your API key and secret

  • Server-side only. Your API key/secret and any bearer token derived from them must never reach a browser, mobile app, or other client an end user can inspect. Exchange for a token on a server you control and proxy authenticated calls through it.
  • Secrets manager, not source control. Store the key/secret in your platform’s secrets manager (AWS Secrets Manager, GCP Secret Manager, Vault, or equivalent) or, at minimum, an untracked .env file. Never commit them.
  • Transport security. Only ever call https://api.spenza.com over TLS — never construct a plain-HTTP variant of the base URL.

Secret rotation

There is no self-service key/secret rotation endpoint in this API. If a credential may have been exposed (checked into a public repo, logged accidentally, shared over an insecure channel), contact Support immediately to have it rotated — don’t wait to confirm the exposure was exploited.

Webhook credentials

Webhook registrations carry two separate secrets — don’t conflate them:
  • authentication (the credential you configure) protects your endpoint from unauthorized callers — Spenza presents it when calling you.
  • signingSecret (returned once, at registration) is what you use to verify a delivery actually came from Spenza, via the X-Spenza-Signature header. See Webhooks → Verifying delivery signatures.
Store both like any other credential — a secrets manager, never source control — and treat a lost signingSecret as a reason to re-register (there’s no way to retrieve it again).

Logging and sensitive-data handling

Several fields that pass through this API are sensitive and should be excluded from application logs, error-tracking tools, and analytics:
  • Credentials — your API secret, any bearer token, a webhook’s authentication credential and signingSecret.
  • Port-in carrier credentialscurrentAccountPassword (the losing carrier’s account PIN) is functionally a password; never log the request body of a port-in call unredacted.
  • Personal data — names, emails, phone numbers and billing addresses flow through the Users, SIMs, Devices, and Port-in surfaces. Handle this like any other customer PII in your systems: minimize retention, restrict access, and exclude it from third-party logging/analytics tools that don’t need it.
If you build request/response logging for debugging, redact these fields (or the whole body on auth/port-in endpoints) before writing them anywhere persistent.

Idempotency

Many write endpoints accept an Idempotency-Key request header — use it on anything that spends money or has a side effect you can’t cheaply reverse (purchases, assignments, group membership changes). It’s the difference between “safe to retry blindly” and “must check state first.” See Core Concepts → Idempotency and Errors → Retry recommendations for the full mechanics. Not every endpoint supports it — check each operation’s page in the API Reference.

Handling rate limits

429 RATE_LIMITED means back off, not retry immediately — see Rate Limits for the full strategy (exponential backoff with jitter, applied per endpoint) and the published per-endpoint thresholds.

Request retries

Retry 429 and 5xx responses with backoff; don’t retry 4xx responses unchanged — they mean the request itself needs to change. Prefer sending an Idempotency-Key on write calls over guessing whether a retry is safe. The full matrix is in Errors → Retry recommendations.

Timeout recommendations

  • Synchronous endpoints (most GET/POST/PUT/DELETE calls) typically resolve quickly; a client timeout in the 10–30 second range is a reasonable general default. This isn’t a number Spenza publishes — size it to your own latency tolerance and adjust if you observe slower calls in practice.
  • Async calls (POST /api/v1.1/esim, the /api/v3 purchase variants, top-up, port-in) return immediately with a transactionId — don’t hold a long-lived connection waiting for the transaction to finish. eSIM provisioning specifically can take up to ~45 minutes end to end; poll GET /api/v3/transactions/{transactionId} on the interval described in Guides → Handling async operations instead of waiting on the original request.

Next steps

  • Errors for the full error taxonomy and retry matrix.
  • Rate Limits for throttling behavior.
  • Webhooks for securing inbound webhook delivery specifically.