---
# @generated by sylphx-gen 0.1.0 from contracts@6a1bce71c4562366bcd933dde7dec01abbf14a9dde109a6ef2c4ea7c79f1fb3a. Do not edit.
title: "Issue in Tokens"
description: "`realtime.tokens.issue` (POST /v1/tokens:issue): Mints a connection or channel token for an end user."
type: reference
product: realtime
summary: "Mints a connection or channel token for an end user."
updated: 2026-09-28
nav: false
---

Mints a connection or channel token for an end user. The customer's server calls it with the secret key after authenticating the user, and hands the token to the client.

**Not available yet.** Sylphx Realtime is declared in the registry but no backend serves it: every call answers `501` with the problem code `UNIMPLEMENTED`.

- **Path** `POST https://api.realtime.sylphx.com/v1/tokens:issue`
- **Scope** `realtime:token`
- **Effect** `write` — a successful call changes state.
- **Collection** [tokens](/docs/api/tokens)
- **Host** `https://api.realtime.sylphx.com`

## Request

| Field | Type | What it is |
| --- | --- | --- |
| `kind` | `TokenKind` | Which kind of token to mint. Required. One of `connection`, `channel`. |
| `user` | `string` | The end user's id. Required for a connection token. |
| `grants` | `ChannelGrant[]` | The channels and capabilities to grant. A channel token takes exactly one grant whose pattern has no `*`. At most 64 grants. Required. |
| `ttl` | `duration` | How long the token lives; 1 minute to 24 hours, default 1 hour. |

### ChannelGrant

| Field | Type | What it is |
| --- | --- | --- |
| `pattern` | `string` | A channel name or pattern: `room:42`, or `room:*` for every channel of the namespace. `*` is allowed only as the whole name part, and never in the namespace part. Required. |
| `capabilities` | `Capability[]` | The capabilities granted. At least one. Required. One of `subscribe`, `publish`, `presence`. |

## Response

| Field | Type | What it is |
| --- | --- | --- |
| `token` | `string` | The token. Opaque; sent in the `connect` frame or the `Authorization` header, never in a URL. Never returned again. |
| `expire_time` | `timestamp` | When it expires. |
| `claims` | `TokenClaims` | The claims the service put in it, for the caller to log or check. |
| `connect_uri` | `string` | The realtime host the client connects to. Never hard-code it: it can change, with no port, and the protocol-v1 paths are fixed. |
| `refresh_time` | `timestamp` | The earliest the client should ask for a replacement: the in-band `refresh_required` frame arrives at this time. |

### TokenClaims

| Field | Type | What it is |
| --- | --- | --- |
| `kind` | `TokenKind` | The token's kind. One of `connection`, `channel`. |
| `environment` | `string` | The authoritative Access environment id, not a client-supplied value. Valid only within the organization, project and cell below. |
| `user` | `string` | The end user's id (`sub`). Required for a connection token; it is the user shown in presence. |
| `grants` | `ChannelGrant[]` | The channels the holder may use. A connection token holds the grants of every channel its connection may touch; a channel token holds exactly one. |
| `issue_time` | `timestamp` | When the token was issued. |
| `expire_time` | `timestamp` | When the token expires. Between issue time plus 1 minute and 24 hours. The service closes a connection whose token has expired and was not refreshed. |
| `token_id` | `string` | A unique id; the service can revoke a token by it until it expires. |
| `issuer_key_id` | `string` | The issuing Access key id (not its secret). Required: the service rechecks its freshness, expiry, revocation and token-issuing authority through the Access verifier at admission, refresh and while the connection is open. |
| `organization` | `string` | The authoritative Access organization id of the issuing tenant. Required. |
| `project` | `string` | The authoritative Access project id of the issuing tenant. Required. |
| `cell` | `string` | The authoritative Access cell id of the issuing tenant. Required. |

### ChannelGrant

| Field | Type | What it is |
| --- | --- | --- |
| `pattern` | `string` | A channel name or pattern: `room:42`, or `room:*` for every channel of the namespace. `*` is allowed only as the whole name part, and never in the namespace part. Required. |
| `capabilities` | `Capability[]` | The capabilities granted. At least one. Required. One of `subscribe`, `publish`, `presence`. |

## Errors

- [`UNAUTHENTICATED`](/docs/api/errors/UNAUTHENTICATED) — No valid key or token was presented.
- [`PERMISSION_DENIED`](/docs/api/errors/PERMISSION_DENIED) — The key lacks the method's permission.
- [`INVALID_FIELD`](/docs/api/errors/INVALID_FIELD) — A field failed validation.

Every error arrives in the body [Errors](/docs/platform/errors) describes.

## Examples

**cURL**

```curl
curl -X POST "https://api.realtime.sylphx.com/v1/tokens:issue" \
  -H "Authorization: Bearer $SYLPHX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"grants":[{"capabilities":["subscribe"],"pattern":"…"}],"kind":"connection"}'
```

**TypeScript**

```ts
const response = await sylphx.realtime.tokens.issue({ grants: [{ capabilities: ['subscribe'], pattern: '…' }], kind: 'connection' })
```

**Rust**

```rust
let mut req = sylphx::realtime::IssueTokenRequest::default();
req.grants = vec![Default::default()];
req.kind = sylphx::realtime::TokenKind::Connection;
let response = sx.realtime().tokens().issue(req).await?;
```

**MCP**

```json
{ "method_id": "realtime.tokens.issue", "args": {"grants":[{"capabilities":["subscribe"],"pattern":"…"}],"kind":"connection"} }
```
