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

# Authentication

> How to authenticate with the Tickable API

The Tickable API supports two authentication methods. Both use the same `Authorization: Bearer` header.

## API Keys

API keys are the simplest way to authenticate. Create one from the [Tickable dashboard](https://app.tickable.nl/settings/developers).

API keys are scoped to an organization and have specific permissions. They look like:

```
tk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345
```

<Warning>
  API keys grant access to your organization's data. Store them securely and never expose them in client-side code.
</Warning>

### Using an API Key

```bash theme={null}
curl https://api.tickable.io/events \
  -H "Authorization: Bearer tk_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ012345"
```

### Scopes

Each API key has specific scopes that control what it can access:

| Scope            | Description                              |
| ---------------- | ---------------------------------------- |
| `events.read`    | Read events, ticket types, and timeslots |
| `events.write`   | Create and update events                 |
| `orders.read`    | Read orders                              |
| `tickets.read`   | Read tickets                             |
| `tickets.write`  | Scan tickets                             |
| `webhooks.read`  | List webhook subscriptions               |
| `webhooks.write` | Create and delete webhooks               |

## OAuth2

Use OAuth2 when building a third-party application that acts on behalf of a Tickable user. The API supports:

* **Authorization Code** — for apps with a backend
* **Client Credentials** — for machine-to-machine access
* **Refresh Token** — to renew expired access tokens

### Authorization Code Flow

<Steps>
  <Step title="Redirect to authorize">
    Send the user to the authorization endpoint:

    ```
    GET https://api.tickable.io/oauth2/authorize
      ?response_type=code
      &client_id=your-client-id
      &redirect_uri=https://yourapp.com/callback
      &scope=events.read webhooks.read
      &state=random-csrf-token
      &organization_id=org-uuid
      &token=supabase-jwt
    ```
  </Step>

  <Step title="Receive the callback">
    After the user approves, they are redirected to your `redirect_uri` with a `code` parameter:

    ```
    https://yourapp.com/callback?code=AUTH_CODE&state=random-csrf-token
    ```

    Always verify that `state` matches what you sent.
  </Step>

  <Step title="Exchange for tokens">
    ```bash theme={null}
    curl -X POST https://api.tickable.io/oauth2/token \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "grant_type=authorization_code" \
      -d "client_id=your-client-id" \
      -d "client_secret=your-client-secret" \
      -d "code=AUTH_CODE" \
      -d "redirect_uri=https://yourapp.com/callback"
    ```
  </Step>
</Steps>

### Client Credentials Flow

For server-to-server integrations where no user interaction is needed:

```bash theme={null}
curl -X POST https://api.tickable.io/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=your-client-id" \
  -d "client_secret=your-client-secret"
```

### Refreshing Tokens

Access tokens expire after 1 hour. Use the refresh token to get a new one:

```bash theme={null}
curl -X POST https://api.tickable.io/oauth2/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=refresh_token" \
  -d "client_id=your-client-id" \
  -d "client_secret=your-client-secret" \
  -d "refresh_token=your-refresh-token"
```

## Error Responses

| Status | Meaning                                     |
| ------ | ------------------------------------------- |
| `401`  | Missing, invalid, or expired token          |
| `403`  | Token is valid but lacks the required scope |
