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

# Authentication

> Authenticate every webhooks API request with your partner key and secret

Every request to `/api/v0/**` carries two headers.

| Header         | Value                                                  |
| -------------- | ------------------------------------------------------ |
| `X-API-KEY`    | Your partner API key, which identifies the credential. |
| `X-API-SECRET` | Your partner API secret, compared in constant time.    |

```bash theme={null}
curl https://qa-api.endl.xyz/api/v0/webhooks/subscriptions \
  -H "X-API-KEY: $ENDL_API_KEY" \
  -H "X-API-SECRET: $ENDL_API_SECRET"
```

<Warning>
  Keep your secret server-side. Never ship it in browser or mobile code, and never commit it to source control.
</Warning>

## Permissions

Each key carries permissions that gate which endpoints it can reach.

| Permission | Grants access to                                 |
| ---------- | ------------------------------------------------ |
| `webhooks` | Manage subscriptions and inspect deliveries.     |
| `events`   | Read the [PULL event feed](/webhooks/pull-feed). |

A valid key that lacks the required permission is rejected with `400 VALIDATION_ERROR` — not `403`.

## Failure modes

Authentication fails closed, and deliberately does not tell you which part was wrong.

<ResponseField name="401 UNAUTHORIZED" type="Your credentials were rejected">
  A header is missing or blank, the key is unknown, the secret is wrong, or the partner is inactive. All four are indistinguishable by design.
</ResponseField>

<ResponseField name="503 DIRECTORY_UNAVAILABLE" type="Endl could not verify right now">
  Endl could not reach the credential store. Your key may be perfectly valid, so retry with backoff. This is deliberately not a `401`.
</ResponseField>

<Tip>
  Treat `401` as a configuration problem to fix and `503` as a transient fault to retry. Retrying a `401` will never succeed.
</Tip>
