# Authentication

> Authenticate with the 4N NextDay API using the bearer token issued for your merchant account.

Source: https://api-doc.4nortes.app/authentication

The 4N NextDay API uses bearer tokens. Your token is issued for your merchant account by 4N NextDay — there is no login endpoint for integrations.

<a id="get-a-token"></a>

## Get a token

API tokens are created by the 4N NextDay team in the admin panel, under your merchant account. Ask your account contact for one.

Keep in mind:

- The full token is shown **once**, when it is created. If you lose it, a new one has to be issued.
- A token may carry an **expiry date**. Once it passes, every request returns `401` until you get a new token.
- A token can be **revoked** at any time from the panel, or by you with [`POST /auth/logout`](#logout).
- One account can hold several tokens — use separate ones for staging and production.

> **Note:**
>
> Don't try to exchange panel credentials for a token. The API has no login flow for merchant integrations; the token you receive is the only credential you need.

<a id="use-the-token"></a>

## Use the token in requests

Include the token in the `Authorization` header of every API request:

```bash
Authorization: Bearer 1|abc123def456...
```

```bash
curl https://api.4nortes.app/api/v1/orders \
  -H "Authorization: Bearer 1|abc123def456..." \
  -H "Accept: application/json"
```

```js
const response = await fetch('https://api.4nortes.app/api/v1/orders', {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Accept': 'application/json',
  },
})
```

```python
response = requests.get(
    'https://api.4nortes.app/api/v1/orders',
    headers={
        'Authorization': f'Bearer {token}',
        'Accept': 'application/json',
    }
)
```

```php
$response = $client->get('https://api.4nortes.app/api/v1/orders', [
    'headers' => [
        'Authorization' => 'Bearer ' . $token,
        'Accept' => 'application/json',
    ],
]);
```

<a id="headers"></a>

## Headers to include

| Header          | Value              | Description                                          |
| --------------- | ------------------ | ---------------------------------------------------- |
| `Authorization` | `Bearer {token}`   | The token issued for your merchant account           |
| `Content-Type`  | `application/json` | Required when you send a JSON body (`POST`, `PATCH`) |
| `Accept`        | `application/json` | Recommended. Errors are returned as JSON either way  |

<a id="auth-failures"></a>

## If authentication fails

There are two different `401` bodies, depending on the cause. Branch on the status code, not on the body.

**Missing, invalid, expired or revoked token.** The request is rejected before it reaches the API logic, so the body is a bare `message` — no `success`, no `timestamp`.

Check that:

- the `Authorization` header is present and reads `Bearer {token}` (with the space)
- the token hasn't passed its expiry date
- the token wasn't revoked from the panel or via `/auth/logout`

**Valid token, wrong kind.** Merchant-only endpoints (`/orders/*`, `/services`) accept merchant API tokens only. A valid token of another kind gets the standard error envelope with `Authentication required.`. This should not happen with the token you were issued; if it does, ask your administrator to verify it was created under your merchant account.

```json
{
  "message": "Unauthenticated."
}
```

```json
{
  "success": false,
  "message": "Authentication required.",
  "errors": null,
  "timestamp": "2025-02-03T10:30:00.000000Z"
}
```

See [Error Handling](https://api-doc.4nortes.app/errors.md) for the full picture of response shapes.

<a id="logout"></a>

## Revoke the current token

`POST /auth/logout`

Revokes the token used to make the request. Use it when rotating credentials or decommissioning an integration.

No request body. The response is the standard success envelope with `data: null`.

> **Warning:**
>
> Revocation is permanent. The next request with that token returns `401 Unauthenticated.`, and you need a new token from your 4N NextDay administrator to continue.

```bash
curl -X POST https://api.4nortes.app/api/v1/auth/logout \
  -H "Authorization: Bearer {token}" \
  -H "Accept: application/json"
```

```js
const response = await fetch(
  'https://api.4nortes.app/api/v1/auth/logout',
  {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${token}`,
      'Accept': 'application/json',
    },
  }
)
```

```json
{
  "success": true,
  "message": "Logged out successfully",
  "data": null,
  "timestamp": "2025-02-03T10:30:00.000000Z"
}
```

<a id="token-safety"></a>

## Keep your token safe

1. **Use environment variables**: Don't hardcode the token in source control
2. **Rotate when needed**: Ask for a new token, switch your integration over, then revoke the old one
3. **Separate tokens**: Use different tokens for testing vs production
4. **Watch for `401`**: Alert on it — it means the token expired or was revoked, and nothing will work until it's replaced

```bash
# Set your token as an environment variable
export NEXTDAY_TOKEN="1|abc123def456..."

# Use it in your requests
curl https://api.4nortes.app/api/v1/orders \
  -H "Authorization: Bearer $NEXTDAY_TOKEN"
```
