> Source: https://builder-docs.ema.ai/api-reference/authentication
> Title: Authentication

# Authentication

Ema's API uses a two-step authentication flow: first generate an API key, then exchange it for a short-lived access token (JWT). All subsequent API calls use the access token in the `Authorization` header.

## Authentication Flow

```
1. GenerateApiKey (gRPC-Web) --> API Key (long-lived)
2. GenerateAccessToken (REST) --> Access Token (JWT, short-lived)
3. Use Access Token in Authorization header for all API calls
```

## Step 1: Generate an API Key

Create an API key for a user within a specific tenant. This is a gRPC-Web endpoint.

Property

Value

URL

`/auth.v1.AuthService/GenerateApiKey`

HTTP Method

POST

Protocol

gRPC-Web over HTTP

### Headers

Header

Type

Required

Description

`Authorization`

string

Yes

Bearer token with user authentication

`Content-Type`

string

Yes

`application/grpc-web+proto`

`x-grpc-web`

string

Yes

`1`

### Request

Field

Type

Required

Description

`email`

string

Yes

Email address of the user to generate the key for

`scope`

ApiKeyScope

No

The scope for the API key. Default: `API_KEY_SCOPE_GLOBAL`.

### Response

Field

Type

Description

`api_key`

string

The generated API key

`api_key_id`

string

The generated API key ID

### Example

```bash
# Encode the request
cat <<EOF | protoc -I=. --encode=auth.v1.GenerateApiKeyRequest \
 service/auth/v1/auth.proto > request.bin
email: "user@example.com"
EOF

# Frame the request
python3 -c 'import sys,struct; data=sys.stdin.buffer.read(); \
 sys.stdout.buffer.write(b"\x00"+struct.pack(">I",len(data))+data)' \
 < request.bin > framed_request.bin

# Send the request
curl -X POST https://your-instance.ema.co/auth.v1.AuthService/GenerateApiKey \
 -H "Authorization: Bearer <token>" \
 -H "Content-Type: application/grpc-web+proto" \
 -H "x-grpc-web: 1" \
 --data-binary @framed_request.bin \
 --output response.bin
```

> **First-time setup:** If you do not yet have an access token, see [Access Token for Root Tenant API Key](/legacy-docs/api-reference/misc/root-tenant-token) for instructions on obtaining one from your browser session.

For the full gRPC-Web encoding/decoding process, see [Handling gRPC-Web Requests](/legacy-docs/api-reference/misc/grpc-web).

## Step 2: Generate an Access Token

Exchange an API key for a JWT access token using the REST endpoint.

Property

Value

URL

`/api/auth/generate_access_token`

HTTP Method

POST

Protocol

REST (HTTP)

### Headers

Header

Type

Required

Description

`x-ema-api-key`

string

Yes

Your API key

### Request Body

This endpoint does not require a request body. Pass the API key in the `x-ema-api-key` header.

### Response Body

Field

Type

Description

`access_token`

string

JWT access token for API authorization

### Example

```bash
curl -X POST https://your-instance.ema.co/api/auth/generate_access_token \
 -H "x-ema-api-key: your-api-key-here"
```

**Response:**

```json
{
 "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
```

## Token Expiration

API Key Type

Token Lifetime

Global API key

24 hours

Chatbot API key

30 minutes

When a token expires, generate a new one by calling `GenerateAccessToken` again with the same API key.

## Using the Access Token

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

```
Authorization: Bearer <access_token>
```

This applies to both REST and gRPC-Web endpoints.

## API Key Types

Ema supports two types of API keys:

-   **Global API key**: Full access to all Builder Platform APIs. Tokens last 24 hours.
-   **Chatbot API key**: Restricted to chatbot-related endpoints. Tokens last 30 minutes.

## Related

-   [Getting Started](/legacy-docs/api-reference/getting-started) -- End-to-end quickstart
-   [Handling gRPC-Web Requests](/legacy-docs/api-reference/misc/grpc-web) -- Detailed gRPC-Web encoding guide
-   [Access Token for Root Tenant API Key](/legacy-docs/api-reference/misc/root-tenant-token) -- First-time token setup
