---
title: Authentication
description: How to authenticate with the Human Dashboard, set up your organization and generate the x-unico-accesskey used in every Human Token API request.
canonical: https://developer.unico.io/human-token/get-started/authentication
locale: en
generated_by: markdown-export
---

- [/](/)
- Get started
- Authentication

**On this page# Authentication

This guide walks you through authenticating with the Human Dashboard and generating the `x-unico-accesskey` you will use in all Human Token API requests.
The flow has two phases:

**Authenticate** — complete a login and obtain an access token. Two authentication methods are available:

**Biometric login** — face capture via the Unico SDK (available for both signup and signin)
**Email OTP login** — one-time code sent to the registered email address (signin only)

**Set up your organization** — create your company profile and generate an access key (first-time signup only)

### Two ways to set up your credentials​

Everything in this guide can also be done through the **Human Dashboard** at [dashboard.unico.app](https://dashboard.unico.app) — no API calls required.
OptionWhen to use**Dashboard**First-time setup, manual key rotation, occasional management**API**Automated provisioning, CI/CD pipelines, programmatic key management
#### Using the dashboard​

Go to [dashboard.unico.app](https://dashboard.unico.app)
**Sign up or sign in** — use biometric login (face capture) or email OTP
**Create your organization** — fill in your company name, country, and allowed domains
**Generate an access key** — go to **Access Keys** and click **Create key**; copy it immediately, it is shown only once
**Manage branches** — create and configure branches under **Branches**; each branch generates its own access key

The access key you get from the dashboard is the same `x-unico-accesskey` used in all API requests — the two approaches are fully interchangeable.
### Base URLs​

Every endpoint on this page is served by the Human Dashboard API. The Human Token API requests, such as Create Process and Get Process, go to the API host listed in [Environments](/human-token/get-started/environments).
EnvironmentAPIBase URLProductionHuman Dashboard API (login, organization, access keys and branches)`https://api.humantoken.unico.app`
### Authentication methods​

Two methods are available to authenticate and obtain an `authToken`:
MethodEndpointWhen to use**Biometric**`POST /api/console/v1/auth/biometric/sessions`Signup (new account) or Signin (returning user)**Email OTP**`POST /api/console/v1/auth/email/sessions`Signin only — account must already exist
### Biometric login intent​

Every call to `POST /api/console/v1/auth/biometric/sessions` must declare an `intent`:
`intent`When to use`email` field`name` field`LOGIN_INTENT_SIGNUP`First-time registration — creating a new account**Required****Required**`LOGIN_INTENT_SIGNIN`Returning user — account already existsNot usedNot used(omitted)Treated as `LOGIN_INTENT_SIGNIN`Not usedNot used
The intent controls the validation done when you poll the session (Step 2):

**SIGNUP** — rejects the login if that biometric identity is already registered (prevents duplicate accounts).
**SIGNIN** — rejects the login if that biometric identity is not registered (account must exist to log in).

### Phase 1 — Authenticate​

#### Step 1: Start a biometric login session​

**SIGNUP (first-time registration)**
```
curl -X POST https://api.humantoken.unico.app/api/console/v1/auth/biometric/sessions \  -H "Content-Type: application/json" \  -d '{    "intent": "LOGIN_INTENT_SIGNUP",    "email": "admin@acme.com",    "name": "Jane Doe"  }'
```

Email uniquenessIf an account is already registered with that email, the request returns `400 Bad Request`.
Response:
```
{  "session": {    "sessionId": "b3f1a2c4-0000-0000-0000-abcdef012345",    "link": "",    "token": ""  }}
```

For SIGNUP, the `link` and `token` fields are empty in the response — the biometric capture link is sent to the provided email address.
**SIGNIN (returning user)**
```
curl -X POST https://api.humantoken.unico.app/api/console/v1/auth/biometric/sessions \  -H "Content-Type: application/json" \  -d '{    "intent": "LOGIN_INTENT_SIGNIN"  }'
```

Response:
```
{  "session": {    "sessionId": "b3f1a2c4-0000-0000-0000-abcdef012345",    "link": "https://humantoken.unico.io/...",    "token": "eyJhbGciOiJSUzI1NiJ9..."  }}
```

Save the `sessionId`.

**SIGNUP**: the biometric capture link is sent to the email provided in Step 1. Ask the user to check their inbox and complete the capture.
**SIGNIN**: open `link` in your browser and complete the biometric capture.

#### Step 2: Poll until the session is resolved​

```
curl https://api.humantoken.unico.app/api/console/v1/auth/biometric/sessions/b3f1a2c4-0000-0000-0000-abcdef012345
```

Poll every 2–3 seconds until `status` reaches a terminal state.
`status``outcome`Meaning`pending``pending`User has not completed the capture yet — keep polling`processing``pending`Capture done, results being computed — keep polling`completed``matched`Login successful — `authToken` is present`completed``no_match`Biometric did not match any record`completed``inconclusive`Capture succeeded but could not be resolved`expired`—Link expired — restart from Step 1`canceled`—Session was canceled — restart from Step 1
**Additional intent-specific errors when polling the session:**
HTTPCondition`400`**SIGNUP** — biometric identity is already registered (duplicate account)`400`**SIGNIN** — biometric identity is not registered (account does not exist)
Successful response:
```
{  "result": {    "sessionId": "b3f1a2c4-0000-0000-0000-abcdef012345",    "status": "completed",    "outcome": "matched",    "authToken": "eyJhbGciOiJSUzI1NiJ9..."  }}
```

Save `authToken` — use it as the `x-console-authorization` header in all subsequent Human Dashboard API requests.
### Phase 1 (alternative) — Email OTP signin​

Use this flow instead of biometric if the user already has an account and prefers to authenticate via a one-time code sent to their registered email. **Signup is not supported via email OTP** — use the biometric flow for first-time registration.
#### Step 1: Send the OTP​

```
curl -X POST https://api.humantoken.unico.app/api/console/v1/auth/email/sessions \  -H "Content-Type: application/json" \  -d '{    "email": "admin@acme.com"  }'
```

noteThe email must belong to an existing account. If no account is found, Step 2 (validate the OTP) returns `404 Not Found`.
Response:
```
{  "session": {    "sessionId": "b3f1a2c4-0000-0000-0000-abcdef012345"  }}
```

Save the `sessionId`. A 6-digit code is sent to the provided email address.
#### Step 2: Validate the OTP​

```
curl https://api.humantoken.unico.app/api/console/v1/auth/email/sessions/{sessionId}/{code}
```

HTTPCondition`200`Code is valid — `authToken` is present`400`Code is wrong (`invalid otp code`)`400`OTP already used, max attempts reached, or expired`404`Email not registered
Successful response:
```
{  "result": {    "sessionId": "b3f1a2c4-0000-0000-0000-abcdef012345",    "status": "completed",    "outcome": "matched",    "authToken": "eyJhbGciOiJSUzI1NiJ9..."  }}
```

Save `authToken` — use it as the `x-console-authorization` header in all subsequent Human Dashboard API requests.
### Phase 2 — Set up your organization​

#### Step 3: Create your organization​

noteThis call can only be made **once**. It provisions your tenant and generates your `branchId`.
Any country is accepted. Use the [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) three-letter code (e.g. `BRA`, `USA`, `MEX`, `DEU`, `IND`). `taxId` is optional for all countries.
```
curl -X POST https://api.humantoken.unico.app/api/console/v1/organization \  -H "x-console-authorization: <authToken>" \  -H "Content-Type: application/json" \  -d '{    "name": "Acme Corp",    "responsibleEmail": "admin@acme.com",    "websiteUrl": "https://acme.com",    "countryCode": "BRA",    "logo": "https://acme.com/logo.png",    "allowedDomains": ["https://app.acme.com"]  }'
```

Response:
```
{  "organization": {    "id": "e5d3f1a2-0000-0000-0000-abcdef012345",    "name": "Acme Corp",    "responsibleEmail": "admin@acme.com",    "websiteUrl": "https://acme.com",    "countryCode": "BRA",    "tenantId": "tenant-acme-prod",    "branchId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",    "taxId": "12345678000195"  }}
```

Save `branchId` — it identifies your default branch and is used when managing branches and access keys.
#### Step 4: Create an access key​

```
curl -X POST https://api.humantoken.unico.app/api/console/v1/access-keys \  -H "x-console-authorization: <authToken>" \  -H "Content-Type: application/json" \  -d '{    "label": "production-key"  }'
```

Response:
```
{  "accessKey": "uip_ak.prod.a1b2c3d4.e5f6g7h8.i9j0k1l2"}
```

warning**The `accessKey` is returned only once and cannot be retrieved again.** Store it in your secrets manager immediately as `HUMAN_TOKEN_ACCESS_KEY`.
This value is the `x-unico-accesskey` header used in all Human Token API requests.
### What you now have​

ValueWhere to use it`branchId`Identifying your default branch; creating branch-specific access keys`accessKey``x-unico-accesskey` header in all Human Token requests
### Managing your organization​

#### Get organization​

```
curl https://api.humantoken.unico.app/api/console/v1/organization/<organizationId> \  -H "x-console-authorization: <authToken>"
```

Response:
```
{  "organization": {    "id": "e5d3f1a2-0000-0000-0000-abcdef012345",    "name": "Acme Corp",    "responsibleEmail": "admin@acme.com",    "websiteUrl": "https://acme.com",    "countryCode": "BRA",    "tenantId": "tenant-acme-prod",    "branchId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",    "taxId": "12345678000195"  }}
```

#### Update organization​

```
curl -X PUT https://api.humantoken.unico.app/api/console/v1/organization \  -H "x-console-authorization: <authToken>" \  -H "Content-Type: application/json" \  -d '{    "id": "e5d3f1a2-0000-0000-0000-abcdef012345",    "name": "Acme Corp",    "responsibleEmail": "admin@acme.com",    "websiteUrl": "https://acme.com",    "countryCode": "BRA",    "taxId": "12345678000195",    "logo": "https://acme.com/logo-updated.png",    "allowedDomains": ["https://app.acme.com", "https://checkout.acme.com"]  }'
```

### Managing access keys​

**List keys** (metadata only — secret is never returned):
```
curl https://api.humantoken.unico.app/api/console/v1/access-keys \  -H "x-console-authorization: <authToken>"
```

**Rotate a key** (old key is immediately invalidated):
```
curl -X POST https://api.humantoken.unico.app/api/console/v1/access-keys/rotate \  -H "x-console-authorization: <authToken>" \  -H "Content-Type: application/json" \  -d '{"accessKey": "uip_ak.prod.a1b2c3d4.e5f6g7h8.i9j0k1l2"}'
```

**Revoke a key** (irreversible):
```
curl -X DELETE https://api.humantoken.unico.app/api/console/v1/access-keys \  -H "x-console-authorization: <authToken>" \  -H "Content-Type: application/json" \  -d '{"accessKey": "uip_ak.prod.a1b2c3d4.e5f6g7h8.i9j0k1l2"}'
```

### Managing branches​

Branches let you segment your organization's configuration (name, logo, allowed domains) per product or environment. Each branch has its own access keys, so the branch context is resolved automatically from the key used in the request — no need to pass `branchId` in `CreateProcess`.
#### Create a branch​

```
curl -X POST https://api.humantoken.unico.app/api/console/v1/organization/branches \  -H "x-console-authorization: <authToken>" \  -H "Content-Type: application/json" \  -d '{    "name": "Mobile App",    "logo": "https://acme.com/mobile-logo.png",    "allowedDomains": ["https://mobile.acme.com"]  }'
```

Response:
```
{  "branchId": "7ab1c2d3-0000-0000-0000-abcdef012345"}
```

Save `branchId` — use it when creating a branch-specific access key.
#### Update a branch​

```
curl -X PUT https://api.humantoken.unico.app/api/console/v1/organization/branches \  -H "x-console-authorization: <authToken>" \  -H "Content-Type: application/json" \  -d '{    "branchId": "7ab1c2d3-0000-0000-0000-abcdef012345",    "name": "Mobile App v2",    "logo": "https://acme.com/mobile-logo-v2.png",    "allowedDomains": ["https://mobile.acme.com", "https://app.acme.com"]  }'
```

#### Create a branch-specific access key​

To generate an access key scoped to a specific branch, include `branchId` in the request body:
```
curl -X POST https://api.humantoken.unico.app/api/console/v1/access-keys \  -H "x-console-authorization: <authToken>" \  -H "Content-Type: application/json" \  -d '{    "label": "mobile-app-key",    "branchId": "7ab1c2d3-0000-0000-0000-abcdef012345"  }'
```

Response:
```
{  "accessKey": "uip_ak.prod.z9y8x7w6.v5u4t3s2.r1q0p9o8"}
```

warning**The `accessKey` is returned only once.** Store it immediately. Any `CreateProcess` request authenticated with this key will automatically use the branch configuration associated with it.Last updated on Oct 21, 2026**