API Key
- Header:
x-api-key - Format:
lmn_prd_<28 url-safe base64 chars>(production) orlmn_stg_<28 url-safe base64 chars>(sandbox). - Transport: keys are shared via one-time secret link at onboarding. Never commit to source; never transmit in URLs.
- Rotation: coordinated out-of-band; both old and new keys are accepted during a brief overlap window for zero-downtime cutover.
- Errors:
401 missing_api_key—x-api-keyheader absent.401 invalid_api_key— key not recognized, revoked, or wrong environment (e.g.,lmn_stg_*againstapi.lmnauto.com).
IP Allowlist
Requests are accepted only from pre-registered partner egress IPs.- Up to 16 IPv4 addresses or CIDR ranges per environment.
- Sandbox and production have independent allowlists.
- Requests from unlisted IPs return
403 ip_not_allowed.
integrations@lmnauto.com with at least 72 hours notice. Emergency same-day changes via security@lmnauto.com.
TLS Requirements
- Minimum TLS 1.2 (TLS 1.3 preferred).
- Forward-secret cipher suites required (ECDHE-*).
- Public CA chain — no certificate pinning required.
Idempotency-Key (required on POST)
EveryPOST must include an Idempotency-Key header with a UUID v4 value.
- LMN enforces a permanent unique constraint on
(api_key, idempotency_key). Replays return the cached response (same status, same body). Safe to retry on timeouts. - Missing on
POSTreturns400 missing_idempotency_key. - Reusing an Idempotency-Key with a different
vehicle_idreturns422 idempotency_key_reused— generate a fresh key per logical request, never reuse across different orders.
Safe vs unsafe key reuse
| Scenario | Result | Example |
|---|---|---|
| Same key + same body (network retry) | ✅ Safe — returns the original response, no duplicate created | Same vehicle_id, same max_bid_amount_usd |
| Same key + different body | ❌ 422 idempotency_key_reused with details.original_vehicle_id | Different vehicle_id than the original POST |
| Different key + same body | ⚠️ Treated as a new request — 409 duplicate_order if active order already exists for that vehicle | Generated a fresh key for what should have been a retry |
Rate Limits
Per-API-key sliding-window buckets:| Bucket | Endpoints | Limit |
|---|---|---|
| Read-heavy | GET /v1/vehicles, GET /v1/vehicles/facets | 600 req/min |
| Read-light | GET /v1/orders/{id}, GET /v1/orders | 300 req/min |
| Write | All POST, DELETE | 60 req/min |
429 rate_limited with Retry-After header (seconds until window resets). Apply client-side exponential backoff.