---
title: Generate Access Token
protocol: rest
method: POST
endpoint: /v1/projects/{projectId}/audiences/{profileId}/token
description: "Generate an access token for an audience profile"
---

# Generate Access Token

Generate a new access token for an audience profile. The token grants access to all pages that match the profile's audience tags.

<Endpoint method="POST" path="/v1/projects/{projectId}/audiences/{profileId}/token" />

## Path Parameters

<ParamField path="projectId" type="string" required>
  The project ID.
</ParamField>

<ParamField path="profileId" type="string" required>
  The audience profile ID.
</ParamField>

## Request Body

<ParamField body="expiresIn" type="string">
  Token expiration duration. Format: `30d`, `90d`, `1y`, or `never`.
  
  **Default**: `30d`
</ParamField>

<ParamField body="label" type="string">
  Optional label to identify this token. Useful when generating multiple tokens for the same profile.
</ParamField>

## Response

Returns the generated token and a ready-to-use magic link.

<ResponseField name="token" type="string">
  The access token. Store securely — it cannot be retrieved again.
</ResponseField>

<ResponseField name="magicLink" type="string">
  A full URL with the token appended as `?_stx_token=...`. Share this for one-click access.
</ResponseField>

<ResponseField name="expiresAt" type="string">
  ISO 8601 timestamp when the token expires. `null` if token never expires.
</ResponseField>

<ResponseField name="audiences" type="string[]">
  The audience tags this token grants access to.
</ResponseField>

## Example

<CodeGroup>
```bash cURL
curl -X POST https://api.syntext.dev/v1/projects/proj_abc123/audiences/aud_xyz789/token \
  -H "Authorization: Bearer stx_abc12345_..." \
  -H "Content-Type: application/json" \
  -d '{
    "expiresIn": "90d",
    "label": "Q1 2024 Access"
  }'
```

```typescript SDK
import { Syntext } from '@syntext/sdk'

const client = new Syntext('stx_abc12345_...')

const { token, magicLink } = await client.audiences.generateToken(
  'proj_abc123',
  'aud_xyz789',
  { expiresIn: '90d', label: 'Q1 2024 Access' }
)
```

```python Python
from syntext import Syntext

client = Syntext("stx_abc12345_...")

result = client.audiences.generate_token(
    "proj_abc123",
    "aud_xyz789",
    expires_in="90d",
    label="Q1 2024 Access",
)
```
</CodeGroup>

### Response

```json
{
  "token": "eyJwcm9qZWN0SWQiOiJwcm9qX2FiYzEyMyIsInRpbWVzdGFtcCI6MTcxMDUwMjQwMCwicHJvZmlsZVNsdWciOiJhY21lLWNvcnAifQ.a1b2c3d4e5f6",
  "magicLink": "https://acme-docs.syntext.dev?_stx_token=eyJwcm9qZWN0SWQiOiJwcm9qX2FiYzEyMyIsInRpbWVzdGFtcCI6MTcxMDUwMjQwMCwicHJvZmlsZVNsdWciOiJhY21lLWNvcnAifQ.a1b2c3d4e5f6",
  "expiresAt": "2024-06-15T10:30:00Z",
  "audiences": ["otc", "virtual-accounts"],
  "label": "Q1 2024 Access"
}
```

## Sharing the Token

### Magic Link (Recommended)

Send the `magicLink` to clients. When they click it:

1. Token is validated automatically
2. A cookie is set for 30 days
3. They're redirected to the docs homepage

### Raw Token

If clients prefer to enter the token manually:

1. Send them the `token` value
2. They visit any gated page
3. A gate page appears with a token input form
4. They paste the token and submit

### For API Consumers

Non-browser clients should send the token in a header:

```bash
curl https://acme-docs.syntext.dev/guides/otc \
  -H "x-audience-token: eyJwcm9qZWN0SWQ..."
```

## Security Notes

- Tokens are signed with HMAC-SHA256 using your project's secret
- Store tokens securely — they grant documentation access
- Rotate tokens periodically, especially when client relationships change
- Deleting a profile invalidates all its tokens immediately
