How to integrate with the iot.cards REST API
The iot.cards REST API lets you manage every SIM's full lifecycle (activate, suspend, terminate, change plan, alarms, CDRs) from your own system, without touching the portal. This guide walks through the minimum viable integration that 90% of customers implement, with Python and Node examples and notes on the mistakes we see most often in production.
- 1
Request credentials in the portal
Go to Portal → Settings → API and generate a service token. Attach minimum-required permissions (read, manage, billing). The token is shown once — store it in your secret manager before closing the modal.
Tip: Generate one token per environment (dev / staging / prod). Revoking one leaves the others working.
- 2
Set up authentication
The API expects the token in the Authorization: Bearer <token> header. Unauthenticated calls return 401 without leaking details. The default rate limit is 60 req/min and can be raised on Enterprise plans.
Tip: Use an HTTP library with exponential retries: 429 (rate limit) and 503 (brief maintenance) are the only codes worth retrying automatically.
- 3
List your SIMs and filter by state
GET /v1/sims returns a paginated list (cursor in the X-Next-Cursor header). It supports filters by status (active, suspended, terminated), country, last_seen_lt, and tag. For large fleets (>10k), always paginate — don't fetch the full list.
- 4
Activate, suspend, or change plan
POST /v1/sims/<iccid>/activate, POST /v1/sims/<iccid>/suspend, and POST /v1/sims/<iccid>/plan handle lifecycle. Operations are idempotent by iccid — safe to retry without double-billing.
Tip: For 1000+ operations use the batch endpoints (/v1/batch/sims/activate, etc.) — faster and easier on rate limits.
- 5
Subscribe to events via webhook
POST /v1/webhooks defines an HTTPS URL on your side and the events to receive: sim.connected, sim.disconnected, sim.threshold_exceeded, billing.invoice_ready. iot.cards signs every payload with HMAC-SHA256 (header X-Iotcards-Signature) — verify the signature before processing.
Tip: Respond 2xx in under 5 seconds. If your logic is heavy, queue the event and process async — slow webhooks back-pressure the whole system.
- 6
Query CDRs and traffic detail
GET /v1/sims/<iccid>/cdrs returns detailed records (timestamp, country, operator, MB used). Handy for internal chargeback or anomaly detection. CSV export available via Accept: text/csv for reporting.
- 7
Handle errors and retries
The API uses standard HTTP codes: 4xx are client errors (don't retry), 5xx are server errors (retry with back-off). Every error has a JSON body with error.code, error.message, and error.request_id — include the request_id in any support ticket.
- 8
Move to production with observability
Before turning off the legacy system: instrument latency and error rate per call, define alert thresholds, and document the fallback plan (what if the API is down for 30 minutes?). The portal is always available as the manual fallback.
Common pitfalls
- ·Hardcoding the token in source. Use environment variables or a secret manager.
- ·Not verifying HMAC on webhooks — an attacker can inject fake events.
- ·Polling /v1/sims every 30 seconds instead of subscribing to webhooks.
- ·Skipping pagination on large lists. The API caps responses at 1,000 items per page.
- ·Retrying 4xx errors (validation, not-found, conflict). Only retry 429 and 5xx.
- ·Assuming a batch endpoint is atomic. It isn't: each SIM can fail individually.
Checklist
- ☐Token generated per environment (dev/staging/prod)
- ☐Token stored in secret manager, never in repo
- ☐Bearer auth tested with a GET /v1/sims
- ☐Webhook receiver verifying HMAC-SHA256 signature
- ☐Exponential retry implemented for 429 and 5xx
- ☐Cursor pagination implemented for lists
- ☐request_id logged on errors
- ☐Latency and error-rate metrics live in production
FAQ
Are there official Python or Node SDKs?+
Curated examples cover the main endpoints on GitHub. For production integrations most customers prefer a thin in-house HTTP client: the API is deliberately small.
What happens if I hit the rate limit?+
The API returns 429 with a Retry-After header indicating the recommended backoff. Your client should honor that header and retry afterwards.
Do webhooks retry?+
Yes. If your endpoint returns non-2xx or takes longer than 5 seconds, iot.cards retries with backoff (1, 5, 30, 300, 3600 seconds) for 24 hours before dropping the event. Keep a dedicated, fast endpoint.
Can I scope a token to an IP range?+
Yes, in Portal → Settings → API → Allowed IPs. Useful when the token only lives on your servers and shouldn't be valid from outside.
More guides