# Headless API Authentication

## Obtaining Credentials

1. Navigate to the Ucommerce Backoffice (`/ucommerce`) as an administrator.&#x20;
2. In the Settings menu, click `API Access`.
3. When having multiple stores, one must be selected in the top-right corner dropdown.
4. Take note of the `Client ID` and the matching `Secret`.
5. Add the URL of your client to the `URL Whitelist`.

The headless API uses OAuth2 for authentication. This involves 2 steps: getting an authentication code and exchanging the code for a token.

## Connect

```bash
curl -D- -G \
    <base_url>/api/v1/oauth/connect \
    -d client_id=<CLIENT_ID> \
    -d redirect_uri=<REDIRECT_URI> \
    -d response_type=code
```

* `redirect_uri` is where you will be redirected to after the call has finished. This needs to match a redirect URL specified in the `URL Whitelist`.

The expected response is a `302 (Found or Moved Temporarily)`.

The `location` header contains the authentication code. This will be used in the next step.

{% hint style="warning" %}
The code expires after 1 minute. A new code must be requested if it has not been exchanged for a token.
{% endhint %}

{% hint style="info" %}
The `code` is URL encoded. The code will need to be [URL-decoded](https://developer.mozilla.org/en-US/docs/Glossary/percent-encoding) before the next step. Some web frameworks might do that automatically.
{% endhint %}

## Exchange code for a token

```bash
curl -D- -X POST <base_url>/api/v1/oauth/token \
    -u <CLIENT_ID>:<CLIENT_SECRET> \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    -d '{
            "grant_type" : "authorization_code"
            "code": "<CODE>"
            "redirect_uri" : "<REDIRECT_URL>"
        }'
```

{% hint style="danger" %}
The authorization header above must be formatted. You can find an explanation and examples here: [token-endpoint-authorization-header](https://dev.ucommerce.net/readme/headless/headless-api-authentication/token-endpoint-authorization-header "mention")
{% endhint %}

An example of an expected response:

```json
{
  "access_token": "eyJhbGciOiJIUzI1Ni978juanR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiJmYTE4OTI3MS1mOTY1LTRmNWMtOTlmOS1lNDViNzNiYzI4MzkiLCJjbGllbnRJZCI6InZpaWEtZnBwIiwicm9sZSI6IkNsaWVudFVzZXIiLCJzZ67623aW9uSWQiOiJlZmE1NWU0ZS0xZTUxLTQ1YWMtYWEyYy01OThhNjFjMTZlOTYiLCJuYmYiOjE1Njc0MTQxNzMsImV4cCI6MTU2NzQxNzc3MywiaWF0IjoxNTY3NDE0MTczfQ.7QD6zGcdonYy79384buXOqsykWrbWa3L6LW4d9uzb-zA",
  "expires_in": 300,
  "redirect_uri": "https://httpbin.org/anything",
  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI687234pXVCJ9.eyJ1c2VySWQiOiJmYTE4OTI3MS1mOTY1LTRmNWMtOTlmOS1lNDViNzNiYzI4MzkiLCJjbGllbnRJZCI6InZpaWEtZnBwIiwiY29uc2VudElkIjoiYTYyODExYWYtNzUxMS00ZWQ0LoyiauasiYTEtMjAwNzc2NGQ1MTIwIiwic2Vzc2lvbklkIjoiZWZhNTVlNGUtMWU1MS00NWFjLWFhMmMtNTk4YTYxYzE2ZTk2Iiwicm9sZSI6IlJlZnJlc2hUb2tlbiIsIm5iZiI6MTU2NzQxNDE3MywiZXhwIjoxNTY4NjIzNzczLCJpYXQiOjE1Njc0MTQxNzN9.5-x0NNg5lMxPnZRYtu983764q0sbPcSb7U9b23e3Zwx0Ss9I",
  "token_type": "bearer"
}
```

* `access_token` will be used in all future requests.
* `expires_in` can be used to identify when to refresh the token.
* `refresh_token` will be used to refresh an expired or expiring token.

## Using the token

All subsequent requests to the Headless API require the `access_token` in their respective `Authorization` headers.&#x20;
