> For the complete documentation index, see [llms.txt](https://developers.citrusad.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.citrusad.com/integration/reference/oauth-20-authentication.md).

# OAuth 2.0 Authentication

{% hint style="info" %}
Epsilon Retail Media's documentation is now centralized with our knowledgebase!

For up to date guides, please view [this page](https://help.citrusad.com/retail-media-interface/integration/data-api/api-overview/oauth-20-authentication) in the new Integration APIs space of our documentation.
{% endhint %}

{% hint style="info" %}
OAuth 2.0 is only available on the /ads endpoint

When integrating order reporting via API, you will need to integrate the /orders endpoint with Basic authentication and your secret API key.
{% endhint %}

## Client ID and Client Secret

The `client_id` and the `client_secret` will be provided by your Technical Account Manager. The Client Secret is private and should not be shared.

## Requesting Access Tokens

To obtain an Access Token, you must send a request containing the `client_id` and `client_secret`. To do that, the Retailer must make a POST request to the Epsilon Retail Media Authorization Server endpoint:

```http
https://$BASE_URL/v1/oauth2/token
```

{% hint style="info" %}
`/oauth2/token` only provides the relevant token. You will use these tokens to interact with the various integration endpoints.
{% endhint %}

Your request will require a Basic Authorization sent via the Authorization request header containing the Retailer’s `client_id` and `client_secret` base64 encoded:

`Authorization: "Basic" + base64encode(client_id + ":" + client_secret)`

You will need to add the following parameter using the `application/x-www-form-urlencoded` format in the HTTP request body:

`grant_type=client_credentials`

The request will look like the following:

```http
POST https://$BASE_URL/v1/oauth2/token
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64 encoded id+key>
grant_type=client_credentials
```

## Receiving your Access Token

The response will contain the following information

* `access_token`: The access token to be used when calling the Epsilon Retail Media APIs
* `expires_in`: The amount, in seconds, until the access token expires
* `token_type`: The type of the token returned. It will be always Bearer in this case

A sample response is below

```json
{
  "access_token": "xxxxx.yyyyy.zzzzz",
  "expires_in": 3600,
  "token_type": "Bearer"
}
```

## Using the Token

Making calls against the Epsilon Retail Media API endpoints can be done by simply adding the Access Token generate to the Authorization header on the request `Authorization: “Bearer “ <access_token>`

```http
POST $BASE_URL/v1/ads/generate HTTP/1.1
accept: application/json
content-type: application/json
Authorization: Bearer <access_token>
{
    "customerId": "wertg5432a",
    "sessionId": "ec9-4e07-881d-3e9",
    "placement": "category",
    "catalogId": "628dbe95-2ec9-4e07-881d-3e9f92ab2e0b",
    "productFilters": [
         ["category:Cupboard/Snacks"]
    ],
    "options": {
                             "filterMode": "AndOr"
                             },
    "maxNumberOfAds": 3
}
```

## Request Errors

### Invalid Client

If the `client_id` or `client_secret` sent in the request is incorrect, then you will receive a response like this:

```json
{
  "error": "invalid_client"
}
```

Make sure you are using the correct credentials. Double-check your `client_id` and `client_secret` and make sure you're using the Basic Authorization correctly when calling the /token endpoint. ##Invalid Request An invalid request error will be returned from the Authorization Server if the request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed.

```json
{
  "error": "invalid_request"
}
```

Ensure to:

* Only include `grant_type=client_credentials` to the request body
* Set the correct `Content-Type` to the request header
