> ## Documentation Index
> Fetch the complete documentation index at: https://docs.spenza.com/llms.txt
> Use this file to discover all available pages before exploring further.

# FAQ & Troubleshooting

> Answers to common setup, authentication, and integration questions.

## Setup

### How do I get API credentials?

There's no self-serve signup — your API key and secret are issued when Spenza provisions your partner account. Contact [support@spenza.com](mailto:support@spenza.com) or your account representative. See **[Getting Started](/getting-started)**.

### Is there a sandbox I can test against?

Not yet — the only base URL today is `https://api.spenza.com`, which is production. A sandbox is planned; see **[Guides → Testing and validation guidance](/guides#testing-and-validation-guidance)** for how to validate safely without one.

### Where do I find the full list of endpoints and fields?

The API Reference (sidebar) — every operation, parameter, request/response schema and error code, generated directly from the OpenAPI spec. You can also download the spec itself at [`/openapi.yaml`](/openapi.yaml).

## Authentication

### My token request returns `UNAUTHORIZED`

Your `key`/`secret` pair is wrong at the `POST /api/v1.1/auth/token` step. Double-check you're using the credentials issued for this account (not credentials from a different system or a copy-paste with trailing whitespace).

### My subsequent requests return `UNAUTHORIZED`

Your bearer token is missing, malformed, or past its `expires_at`. Confirm you're sending `Authorization: Bearer <token>` (not just the raw token, and not `Bearer: <token>`), and re-authenticate if it's expired. See **[Authentication](/authentication)**.

### A request returns `FORBIDDEN` even though my token is valid

The token doesn't carry the role tier that endpoint requires, or your account's plan doesn't include that capability. This is an account permissions/plan issue, not a request bug — contact [Support](/support) to confirm what your token can and can't do.

## Invalid payloads

### I get `MISSING_FIELDS` but I think I sent everything

Check `error.details` when it's present — it often lists exactly which fields were missing or invalid. A common cause is sending the field with the wrong name or nesting (for example, sending `iccid` at the top level when the operation expects it nested under a `user` object, or vice versa) — compare your body against the **Body** table on that operation's reference page field by field.

### I get `VALIDATION_ERROR` on a field that looks correct

Check the field's `enum` values and type in the reference — a common mismatch is sending a string where a boolean/number is expected (`"true"` instead of `true`), or an enum value in the wrong case.

### Can I retry a failed write safely?

If the endpoint supports it, send an `Idempotency-Key` header — then yes, unconditionally; a retry with the same key and body replays the original result instead of repeating it. If it doesn't, only retry if you're sure the original request didn't already partially succeed. See **[Errors → Retry recommendations](/errors#retry-recommendations)**.

## Environment mismatches

### My request works in one script but fails in another with the same code

Check the base URL your HTTP client actually sent — a copy-pasted example with a placeholder host, a stale environment variable, or a leftover `http://` instead of `https://` are the usual culprits. There's only one documented environment (`https://api.spenza.com`), so "it worked from curl but not from my app" is almost always a client configuration difference, not an API difference.

### An endpoint I'm calling isn't in this documentation

It likely predates the Partner API standardization and isn't part of this contract — ask [Support](/support) for the current equivalent rather than continuing to build against it.

## Debugging an integration

1. **Isolate with cURL first.** Reproduce the failing call outside your application code using the exact cURL sample from the reference page — this rules out bugs in your HTTP client/serialization.
2. **Check `error.code`, not just the HTTP status.** The status tells you the category; the code tells you the specific cause — see **[Errors](/errors)**.
3. **Diff your request against the reference example field by field.** Most failures are a missing/misnamed/mistyped field, not an API bug.
4. **For async operations, check the transaction, not just the initial response.** A `202 Accepted` only means the operation started — poll `statusEndpoint` and inspect `status`/`result`/`errorCode` for the actual outcome. See **[Guides → Handling async operations](/guides#handling-async-operations)**.
5. **Still stuck?** See **[Support](/support)** for what to include when you reach out.
