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

# Authentication: API Keys, Environments, and Errors

> Authenticate every AgriBackup request with an API key. Understand live vs sandbox prefixes, base URL resolution, and handling auth errors.

Every request to the AgriBackup API must include a valid API key. AgriBackup uses the `X-API-Key` header scheme — pass your key as a plain header value, or use the official SDKs which handle this automatically. There are no OAuth flows, no token expiry windows, and no refresh tokens to manage.

## API key format

AgriBackup API keys are prefixed to indicate their environment:

| Prefix     | Environment | Description                                                                               |
| ---------- | ----------- | ----------------------------------------------------------------------------------------- |
| `sk_live_` | Production  | Processes real compliance records, anchors on Hedera mainnet, and files to live TRACES NT |
| `sk_test_` | Sandbox     | Fully isolated; no real blockchain transactions or EU system submissions                  |

Generate and manage your keys from the [developer console](https://agribackup.com) or programmatically via `POST /api/v1/enterprise/api-keys`.

<Warning>
  A `sk_live_` key has the authority to file binding legal records with the EU TRACES NT system and incur real Hedera consensus fees. Treat it with the same care as a production database password — never commit it to source control or expose it in client-side code.
</Warning>

## Passing your API key

### Raw HTTP

Include the key in the `X-API-Key` header on every request:

```bash theme={null}
curl -X POST https://live.agribackup.com/api/v1/enterprise/eudr/polygons \
  -H "X-API-Key: sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: tx_unique_001" \
  -d '{"features": [...]}'
```

For sandbox requests, swap the base URL and key:

```bash theme={null}
curl -X POST https://sandbox.agribackup.com/api/v1/enterprise/eudr/polygons \
  -H "X-API-Key: sk_test_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: tx_unique_001" \
  -d '{"features": [...]}'
```

<Note>
  Both `X-API-Key` and `Authorization: Bearer` header formats are accepted. The `X-API-Key` header is the canonical form used by all official SDKs.
</Note>

### Python SDK

```python theme={null}
import agribackup

configuration = agribackup.Configuration()
configuration.api_key['ApiKeyAuth'] = 'sk_live_YOUR_API_KEY'
# No need to set configuration.host — the SDK resolves it from the key prefix

with agribackup.ApiClient(configuration) as api_client:
    polygons_api = agribackup.EnterprisePolygonsApi(api_client)
    # ... make requests
```

### Node.js SDK

```javascript theme={null}
import { AgriBackupClient } from '@agribackup/sdk';

const client = new AgriBackupClient({
  apiKey: 'sk_live_YOUR_API_KEY'
  // baseUrl is optional — omit it and the SDK resolves from key prefix
});
```

### Java SDK

```java theme={null}
import com.agribackup.client.*;

ApiClient defaultClient = Configuration.getDefaultApiClient();
defaultClient.setApiKey("sk_live_YOUR_API_KEY");
// Do NOT call setBasePath — let the SDK resolve from the key prefix
```

## Base URL auto-resolution

You do not need to configure a base URL when using an official SDK. The SDK inspects the `sk_live_` or `sk_test_` prefix and selects the correct host:

| Key prefix | Resolved base URL                |
| ---------- | -------------------------------- |
| `sk_live_` | `https://live.agribackup.com`    |
| `sk_test_` | `https://sandbox.agribackup.com` |

If you call the API directly over HTTP (without an SDK), use the appropriate host from the table above. All paths are prefixed with `/api/v1`.

<Tip>
  Switching your integration from sandbox to production requires changing only one string: the API key. Swap `sk_test_…` for `sk_live_…` and every endpoint URL resolves automatically.
</Tip>

## Rate limits

The production environment enforces a limit of **100 requests per second** per API key. Every response includes the following headers so you can monitor your usage in real time:

<ResponseField name="X-RateLimit-Limit" type="integer">
  The maximum number of requests permitted per rate-limit window.
</ResponseField>

<ResponseField name="X-RateLimit-Remaining" type="integer">
  The number of requests remaining in the current window.
</ResponseField>

<ResponseField name="X-RateLimit-Reset" type="integer">
  UTC epoch seconds at which the current window resets.
</ResponseField>

When you exceed the limit the API returns `429 Too Many Requests`. Back off using the `Retry-After` header value before retrying.

## Common authentication errors

### 401 Unauthorized

You receive `401` when no valid API key is present or the key is malformed.

```json theme={null}
{
  "code": "UNAUTHORIZED",
  "message": "Missing or invalid API key",
  "details": []
}
```

**Common causes:**

* The `X-API-Key` header is absent.
* The key value is truncated or contains whitespace.
* You are passing the key in the wrong header (e.g. `Authorization: Token` instead of `X-API-Key`).

### 403 Forbidden

You receive `403` when the key is valid but lacks the required scope for the requested operation.

```json theme={null}
{
  "code": "FORBIDDEN",
  "message": "API key does not have the required scope",
  "details": []
}
```

**Common causes:**

* The key was generated with restricted scopes (e.g. read-only) and you are attempting a write.
* You are sending a `sk_test_` key to the production host (`live.agribackup.com`) or vice versa.
* The key has been rotated and the old value is being used.

Rotate keys with `POST /api/v1/enterprise/api-keys/{keyId}/rotate`.

## Keeping keys secure

<Note>
  Follow these practices to keep your API keys secure:

  * **Environment variables only.** Load the key from an environment variable or a secrets manager (e.g. HashiCorp Vault, AWS Secrets Manager) — never hard-code it.
  * **No client-side exposure.** Never include a `sk_live_` key in browser JavaScript, mobile app binaries, or any code that runs outside your trusted server environment.
  * **Rotate regularly.** Use `POST /api/v1/enterprise/api-keys/{keyId}/rotate` to issue a new key on a schedule or immediately after any suspected compromise.
  * **Scope minimally.** When creating keys for automated pipelines, grant only the scopes that pipeline requires.
  * **Audit usage.** List active keys with `GET /api/v1/enterprise/api-keys` and revoke any you no longer recognise.
</Note>
