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

# Authentication

> Learn how to authenticate with the amberSearch API using OAuth 2.0

## Overview

The amberSearch Public API uses **OAuth 2.0 Authorization Code Grant and a PKCE safety measure** to authenticate third-party applications. This flow allows users to authorize external applications to access amberSearch on their behalf without sharing their credentials. The provider abides by the specifications defined in the RFC 6749 and RFC 7636 protocols, implementing a seamless and secure interface for authorizing users.

<Note>
  This is a beta version of our OAuth 2.0 implementation. Features may evolve as we continue to improve the API.
</Note>

## Base URL

All OAuth endpoints are available under:

```
https://customerDomain.ambersearch.de/api/oauth
```

## OAuth 2.0 Flow

The OAuth 2.0 Authorization Code Grant flow consists of the following steps:

<Steps>
  <Step title="Client Redirects User to Authorization Endpoint">
    Your application redirects the user to `/api/oauth/authorize` with your client credentials and desired scopes.
  </Step>

  <Step title="User Authentication">
    The user authenticates with amberSearch (if not already logged in) and authorizes your application.
  </Step>

  <Step title="Authorization Code Issued">
    amberSearch redirects back to your application's redirect URI with an authorization code.
  </Step>

  <Step title="Exchange Code for Access Token">
    Your application exchanges the authorization code for an access token by calling `/api/oauth/token`.
  </Step>

  <Step title="Access API with Token">
    Use the access token to make authenticated requests to amberSearch API endpoints.
  </Step>
</Steps>

***

## Getting Started

To use OAuth 2.0 with the amberSearch API, you need OAuth client credentials `client_id`, `client_secret` or simply `client_id` if PKCE is required.

<Warning>
  **OAuth client credentials can only be obtained from the amberSearch team.** Contact your dedicated customer success manager to request your credentials. You cannot generate these credentials yourself.
</Warning>

***

## Discovery Endpoints

To make integration easier, amberSearch exposes OAuth discovery endpoints so clients can automatically learn:
•	the authorization endpoint (/authorize)
•	the token endpoint (/token)
•	supported PKCE methods
•	supported scopes

```http theme={null}
GET /.well-known/oauth-authorization-server
```

## Authorization Endpoint

### Step 1: Redirect User to Authorization

Direct users to the authorization endpoint to begin the OAuth flow:

```http theme={null}
GET /api/oauth/authorize
```

**Query Parameters:**

| Parameter               | Type   | Required    | Description                                                                                                            |
| ----------------------- | ------ | ----------- | ---------------------------------------------------------------------------------------------------------------------- |
| `response_type`         | string | Yes         | Must be `code`                                                                                                         |
| `client_id`             | string | Yes         | Your OAuth client ID                                                                                                   |
| `redirect_uri`          | string | Yes         | Must match one of the registered redirect URIs                                                                         |
| `scope`                 | string | No          | Space-separated list of requested scopes                                                                               |
| `state`                 | string | Recommended | Opaque value for CSRF protection                                                                                       |
| `code_challenge`        | string | Yes         | Encoded version of the code verifier                                                                                   |
| `code_challenge_method` | string | Yes         | Encoding algorithm that transforms code\_verifier into a code\_challenge, only 2 methods are supported, S256 and plain |

**Example Authorization URL:**

```
https://customerDomain.ambersearch.de/api/oauth/authorize?
  response_type=code&
  client_id=550e8400-e29b-41d4-a716-446655440000&
  redirect_uri=https://myapp.example.com/callback&
  scope=offline_access&
  state=xyz123
  code_challenge=a-code-challenge
  code_challenge_method=S256
```

### Step 2: User Authentication

If the user is not logged into amberSearch, they will be redirected to the login page. After successful authentication, they are redirected back to continue the OAuth flow.

### Step 3: Authorization Response

Upon successful authorization, the user is redirected to your `redirect_uri` with:

```
https://myapp.example.com/callback?code=BASE64_ENCODED_AUTH_CODE&state=xyz123
```

| Parameter | Description                                             |
| --------- | ------------------------------------------------------- |
| `code`    | The authorization code (valid for 10 minutes)           |
| `state`   | The state parameter you provided (verify this matches!) |

**Error Response:**

```
https://myapp.example.com/callback?error=access_denied&error_description=User+denied+access
```

***

## Token Endpoint

### Step 4: Exchange Authorization Code for Access Token

```http theme={null}
POST /api/oauth/token
Content-Type: application/x-www-form-urlencoded
```

**Request Body (form-encoded):**

| Parameter       | Type   | Required | Description                                                                 |
| --------------- | ------ | -------- | --------------------------------------------------------------------------- |
| `grant_type`    | string | Yes      | `authorization_code`                                                        |
| `code`          | string | Yes      | The authorization code received                                             |
| `redirect_uri`  | string | Yes      | Must match the authorization request                                        |
| `client_id`     | string | Yes      | Your OAuth client ID                                                        |
| `code_verifier` | string | Yes      | A randomly generated string used to verify the client request on the server |

**Example Request:**

```bash theme={null}
curl -X POST "https://customerDomain.ambersearch.de/api/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=BASE64_ENCODED_AUTH_CODE" \
  -d "redirect_uri=https://myapp.example.com/callback" \
  -d "client_id=550e8400-e29b-41d4-a716-446655440000" \
  -d "code_verifier=your-code-verifier"
```

**Success Response:**

```json theme={null}
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": ""
}
```

**Success Response (with offline\_access scope):**

```json theme={null}
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": null,
  "scope": "offline_access"
}
```

| Field           | Description                                                 |
| --------------- | ----------------------------------------------------------- |
| `access_token`  | JWT access token for API requests                           |
| `refresh_token` | JWT access token for generating access tokens               |
| `token_type`    | Always `Bearer`                                             |
| `expires_in`    | Token lifetime in seconds (3600 = 1 hour, null = permanent) |
| `scope`         | Granted scopes                                              |

***

## Using the Access Token

Once you have an access token, include it in the `Authorization` header for all API requests:

```bash theme={null}
curl -X GET "https://customerDomain.ambersearch.de/api/beta/search?query=example" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```

***

## Step 5: Exchanging the refresh token for an access token

In case of the access token expiring or for rotating the tokens you can pass the refresh token in order to retrieve a new access and refresh token

| Parameter       | Type   | Required | Description                                               |
| --------------- | ------ | -------- | --------------------------------------------------------- |
| `client_id`     | string | Yes      | Your OAuth client ID                                      |
| `client_secret` | string | Yes      | Your OAuth client secret                                  |
| `grant_type`    | string | Yes      | `refresh_token`                                           |
| `refresh_token` | string | Yes      | A jwt used for authentication and access token generation |

curl -X POST "[https://customerDomain.ambersearch.de/api/oauth/token](https://customerDomain.ambersearch.de/api/oauth/token)" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client\_id=client\_id" \
-d "client\_secret"="client\_secret" \
-d "grant\_type=refresh\_token" \
-d "refresh\_token=your-refresh-token"

**Success Response:**

```json theme={null}
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
}
```

**Success Response (with offline\_access scope):**

```json theme={null}
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": null,
}
```

***

## Scopes

| Scope            | Description                                      |
| ---------------- | ------------------------------------------------ |
| `offline_access` | Request a permanent access token (never expires) |

**Token Expiration:**

* **Standard tokens:** Expire after 1 hour (`expires_in: 3600`)
* **Offline access tokens:** Never expire (`expires_in: null`)

<Tip>
  For long-running applications or background processes, request the `offline_access` scope to avoid token expiration issues.
</Tip>

***

## Error Handling

Common OAuth errors:

| Error                 | Description                                                 |
| --------------------- | ----------------------------------------------------------- |
| `invalid_request`     | The request is missing a required parameter or is malformed |
| `unauthorized_client` | The client is not authorized to use this flow               |
| `access_denied`       | The user denied the authorization request                   |
| `invalid_grant`       | The authorization code is invalid or expired                |
| `invalid_client`      | Client authentication failed                                |

**Example Error Response:**

```json theme={null}
{
  "error": "invalid_grant",
  "error_description": "The authorization code has expired"
}
```

***

## Security Best Practices

<Warning>
  * Always use HTTPS for redirect URIs
  * Validate the `state` parameter to prevent CSRF attacks
  * Rotate access tokens regularly if not using offline\_access
  * Switch between the `code_verifier` strings constantly
  * Never expose tokens in URLs or logs
</Warning>
