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

# Required headers

> Headers required when calling the Dfns API, including the authentication token (`Authorization: Bearer`) and how to obtain one for users and service accounts.

To use Dfns API endpoints, you will generally need to:

## 1. Get an authentication token

Login and obtain an Authentication tokens (also referred to as token) to present when calling our API.

| Header                          | Description                                                                               |
| ------------------------------- | ----------------------------------------------------------------------------------------- |
| `Authorization: Bearer <token>` | Authentication token <br /> (see [Authentication flows](/api-reference/auth/login-flows)) |

To get a token, you can either:

* as a User (human 👨)
  * Follow the [Login](/api-reference/auth/login-flows) flow. You'll get a authentication token at the end of this flow, which expires after a relatively short period of time.
  * Create a [Personal Access Token](/api-reference/auth/personal-access-tokens) (PAT) [^1], which is a long-lived authentication token for the User, and that you can use as an authentication token directly.
* as a Service Account (machine 🤖)
  * Create a [Service Account Token](/api-reference/auth/service-accounts) [^1], which is a long-lived authentication token for the Service Account, and that you can use as an authentication token directly.

Note: while registering a new user (see [Registration flows](/api-reference/auth/registration-flows)), the initial step will get you a temporary registration token ([example](/api-reference/auth/create-registration-challenge)) that you should use as a Bearer token in the `Authorization` header for the next step of the registration ([example](/api-reference/auth/complete-user-registration)).

[^1]: ⚠️ Once generated, Dfns system do not keep a trace of your Service Account Token or your Personal Access Token, only
    you will hold on to those. If you lose them, you'll just need to create a new
    one.

## 2. Sign API requests (User Action Signing)

Sign a User Action Challenge using a cryptographic key that you own (referred to Credential Key or just Credentials). This is only required for actions which mutate state (non-readonly API calls). We call that process: "User Action Signing".

| Header                                       | Description                                                                                    |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `X-DFNS-USERACTION: <user-action-signature>` | One time signature <br /> (see [User Action Signing flows](/api-reference/auth/signing-flows)) |

To obtain that signature, you need to follow the [User Action Signing flows](/api-reference/auth/signing-flows):

1. You tell Dfns "I want to perform this exact request"
2. Dfns sends you back a challenge to be signed with your Credential.
3. You sign the challenge with your Credentials, and send it to Dfns.
4. Dfns gives you back a "user action signature", which you'll need include in the headers when you perform the actual request (`X-DFNS-USERACTION` header)

The credential -- essentially being a cryptographic key -- you'll need to use to sign the challenge will depend on who is calling the api (User / Service Account), see more about that on the [dedicated page](/api-reference/auth/credentials).

## Getting current user info

There is no `/me` or `/whoami` API endpoint. Instead, decode the JWT token to extract user information. You can use [jwt.io](https://jwt.io) for debugging or any JWT library in your code.

### Decoding the token

```typescript theme={null}
// Using jose library
import { decodeJwt } from 'jose'

const token = 'eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...'
const payload = decodeJwt(token)

const userId = payload['https://custom/app_metadata'].userId
const orgId = payload['https://custom/app_metadata'].orgId
const email = payload['https://custom/username']
```

A decoded token looks like this:

```json theme={null}
{
  "iss": "auth.dfns.io",
  "aud": "dfns:auth:user",
  "sub": "or-xxxxx-xxxxx-xxxxxxxxxxxxxxxx",
  "jti": "uj-xxxxx-xxxxx-xxxxxxxxxxxxxxxx",
  "https://custom/username": "user@example.com",
  "https://custom/app_metadata": {
    "tokenKind": "Token",
    "userId": "us-xxxxx-xxxxx-xxxxxxxxxxxxxxxx",
    "orgId": "or-xxxxx-xxxxx-xxxxxxxxxxxxxxxx"
  },
  "iat": 1767947321,
  "exp": 1767968921
}
```

| Field                                | Description                            |
| ------------------------------------ | -------------------------------------- |
| `https://custom/username`            | The user's email address               |
| `https://custom/app_metadata.userId` | The user's ID                          |
| `https://custom/app_metadata.orgId`  | The organization ID                    |
| `exp`                                | Token expiration time (Unix timestamp) |

## Common errors

See [Error codes](/api-reference/error-codes) for a full list of errors. Here are the most common authentication errors:

### 401 Unauthorized

Your `Authorization` header is missing, malformed, or the token is invalid/expired.

**Solutions:**

* Verify the token is included as `Authorization: Bearer <token>`
* Check the token hasn't expired - decode it at [jwt.io](https://jwt.io) and check the `exp` field
* Ensure you're using the correct [region](/api-reference/regions) (`api.dfns.io` vs `api.uae.dfns.io`)

### 403 User action signature is missing

You're calling a state-changing endpoint (POST, PUT, DELETE) without the `X-DFNS-USERACTION` header.

**Solutions:**

* Follow the [User Action Signing flow](/api-reference/auth/signing-flows) to get the signature
* If using Postman, ensure the pre-request script is running - see [Postman setup](/api-reference/openapi-postman)
* If using the SDK, ensure you've configured a signer - see [SDKs](/sdks)

<Tip>
  GET requests don't require the `X-DFNS-USERACTION` header. If you're getting this error, you're likely making a POST/PUT/DELETE request.
</Tip>

***
