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 (see Authentication flows) |
To get a token, you can either:
- as a User (human 👨)
- Follow the Login 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 (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 ⚠️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), the initial step will get you a temporary registration token (example) that you should use as a Bearer token in the Authorization header for the next step of the registration (example).
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 (see User Action Signing flows) |
To obtain that signature, you need to follow the User Action Signing flows:
- You tell Dfns “I want to perform this exact request”
- Dfns sends you back a challenge to be signed with your Credential.
- You sign the challenge with your Credentials, and send it to Dfns.
- 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.
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 for debugging or any JWT library in your code.
Decoding the token
// 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:
{
"iss": "auth.dfns.io",
"aud": "dfns:auth:user",
"sub": "or-xxxxx-xxxxx-xxxxxxxxxxxxxxxx",
"jti": "uj-xxxxx-xxxxx-xxxxxxxxxxxxxxxx",
"https://custom/username": "[email protected]",
"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 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 and check the
exp field
- Ensure you’re using the correct region (
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:
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.