API Key Authentication
All requests require an API key passed as a bearer token in the Authorization header:
curl 'https://api.sbx.moduluslabs.io/ecom/v1/checkout' \
-H 'Authorization: Bearer sk_test_your_api_key_here'
API keys are provisioned during merchant onboarding. Contact your account manager to request keys.
| Environment | Key Prefix | Description |
|---|
| Production | sk_live_ | Live transactions, real money |
| Sandbox | sk_test_ | Test transactions, no real charges |
Keep your API keys secret. Do not expose them in client-side code, public repositories, or browser applications. Requests without a valid key receive a 401 invalid_api_key response.
Entity Scoping
Every API key is scoped to an entity in the organization hierarchy. Data access is automatically restricted based on your key’s level.
| Key Level | Access |
|---|
| Partner | All merchants and branches under the partner |
| Merchant | All branches under the merchant |
| Branch | Only that branch |
When you create a payment link, partner- and merchant-scoped keys must specify a merchant_branch_reference_number. Branch-scoped keys can omit it — the link is created against that branch automatically.
Idempotency
The Idempotency-Key header is a unique client-generated identifier using letters, digits, dot (.), hyphen (-), and underscore (_), 8–64 characters. Clients often reuse their own order_reference as the key.
POST /checkout (create a payment link) — required
POST /checkout/{id}/cancel (cancel a payment link) — optional; cancel is idempotent by nature, so a key is accepted but not required
If you send the same idempotency key with the same request body, you receive the original response without creating a duplicate. If you send the same key with a different body, you receive a 409 idempotency_mismatch error.
Idempotency keys expire after 24 hours. Generate a fresh key for each distinct operation.
| Header | Required | Description |
|---|
Authorization | Always | Bearer sk_live_... or Bearer sk_test_... |
Content-Type | POST, PATCH | application/json |
Idempotency-Key | Required on POST /checkout; optional on POST /checkout/{id}/cancel | Unique client-generated ID. Letters, digits, ., -, _; 8–64 characters |
Every response includes:
| Header | Description |
|---|
x-correlation-id | Unique request identifier (UUID v4). Include this in support requests. |
X-RateLimit-Limit | Maximum requests allowed per minute for this endpoint |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp when the rate limit window resets |
Rate limits
Requests are rate-limited per API key per endpoint.
| Endpoint | Limit |
|---|
POST /checkout | 60 requests/minute |
GET /checkout | 120 requests/minute |
GET /checkout/{id} | 120 requests/minute |
PATCH /checkout/{id} | 60 requests/minute |
POST /checkout/{id}/cancel | 60 requests/minute |
When rate limited, the API returns a 429 rate_limited response. Check the Retry-After header for the number of seconds to wait before retrying.