---
llm-context: api-documentation
purpose: Assist LLMs and developers with integrating the DoorFlow API API
service: doorflow
version: 3.0
endpoint: POST /api/3/element_sessions
summary: Create an Elements widget session
auth: oauth2
format: markdown
updated: 2026-06-14
---

# POST /api/3/element_sessions

Create an Elements widget session

Mints a short-lived JWT session token authorising one Elements widget
instance for one identified subject. The token is delivered to the
widget shell via the host page or app, then forwarded to DoorFlow.
Tokens expire after 15 minutes; long-lived widgets refresh by
calling this endpoint again from the host backend.

The `member` block is the integrator&#39;s CRM-side identity for the
person; DoorFlow find-or-creates a `Person` against `external_id`
on the authenticated account.


## Authentication

This endpoint requires authentication using one of the following methods:

### OAuth 2.0 (Recommended)

Use an OAuth 2.0 access token in the Authorization header. This is the recommended authentication method for all integrations. OAuth provides automatic token expiration, granular permission scopes, detailed usage tracking, and per-integration revocation.

**Example:**
```
Authorization: Bearer YOUR_ACCESS_TOKEN
```

## Request Body

### Fields

**`widget_type`** *string* - **Required**
Which widget kind this session authorises. `admin` exposes
credential issue/revoke and group management; `member` exposes
wallet provisioning and self-deactivation.


**`member`** *object* - **Required**

**`identity_assertion`** *string | null*
Optional partner-signed JWT (RFC 7521 / RFC 7523) carrying
verified-identity claims. When present and verified against
the partner&#39;s published JWKS, downstream wallet provisioning
may skip its own SMS verification step.


**`platform`** *string | null*
Optional platform hint. Only honoured by the iOS-side
`/sdk/button` host page; ignored by the JS shell.


**`config`** *object*
Theme and widget-configuration flags. Each value is validated
on the server; invalid values fall back to defaults rather than
rejecting the session.


**`credentials`** *array&lt;string&gt;*
Optional explicit credential-type slugs (or well-known aliases)
to expose in the widget. Defaults to all wallet-eligible types
for the requested widget kind.


### Example

```json
{
  "widget_type": "member",
  "member": {
    "external_id": "u_42",
    "name": "Alice Smith",
    "email": "alice@example.com"
  },
  "identity_assertion": "string",
  "platform": "string",
  "config": {
    "theme": "string",
    "accent_color": "#FF6600",
    "border_radius": 0,
    "font_family": "Inter, -apple-system, sans-serif",
    "manage_groups": false,
    "show_member": false
  },
  "credentials": [
    "string"
  ]
}
```

## Responses

### 200 - Session token minted successfully

#### Response Fields

**`token`** *string* - **Required**
Short-lived JWT to forward to the widget shell.
*Example:* `eyJhbGciOiJIUzI1NiJ9...`

**`expires_in`** *integer* - **Required**
Seconds until the token expires.
*Example:* `900`

#### Example Response

```json
{
  "token": "eyJhbGciOiJIUzI1NiJ9...",
  "expires_in": 900
}
```

### 401 - Unauthorized - Invalid or missing authentication

#### Response Fields

**`error`** *string*
*Example:* `unauthorized`

**`error_description`** *string*
*Example:* `The access token is invalid`

#### Example Response

```json
{
  "error": "unauthorized",
  "error_description": "The access token is invalid"
}
```

### 403 - Forbidden - User does not have permission

#### Response Fields

**`error`** *string*
*Example:* `forbidden`

**`error_description`** *string*
*Example:* `You are not authorized to access this resource`

#### Example Response

```json
{
  "error": "forbidden",
  "error_description": "You are not authorized to access this resource"
}
```

### 422 - Session could not be minted — typed error in the response body

#### Response Fields

**`error`** *string* - **Required**
Typed error code so SDK callers can branch without parsing
the human-readable message.


**`message`** *string*
Human-readable description of the error.

#### Example Response

```json
{
  "error": "string",
  "message": "string"
}
```

### 503 - Identity-assertion verification could not complete because the partner JWKS endpoint was unreachable

#### Response Fields

**`error`** *string* - **Required**
Typed error code so SDK callers can branch without parsing
the human-readable message.


**`message`** *string*
Human-readable description of the error.

#### Example Response

```json
{
  "error": "string",
  "message": "string"
}
```

### 500 - Internal Server Error

#### Response Fields

**`error`** *string*
*Example:* `internal_server_error`

**`error_description`** *string*
*Example:* `An unexpected error occurred`

#### Example Response

```json
{
  "error": "internal_server_error",
  "error_description": "An unexpected error occurred"
}
```
