> ## Documentation Index
> Fetch the complete documentation index at: https://docs.waffo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Issue Session Token

> Issue a session token for a customer to create orders in your store

Issue a Session Token for a customer to create orders in your store. This is an **API Key exclusive** endpoint.

```
POST /v1/actions/auth/issue-session-token
```

**Authentication:** API Key

## How It Works

1. Your server calls this endpoint with API Key authentication
2. You receive a short-lived session token
3. Pass the token to the customer's browser
4. The customer uses the token (`Authorization: Bearer <token>`) to create orders and interact with checkout

Session tokens are scoped to a single store and expire automatically.

## Request Body

| Field           | Type   | Required | Description                                                                                                             |
| --------------- | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| `storeId`       | string | No       | Target store ID (Short ID format `STO_xxx`). Required when `productId` is not provided                                  |
| `productId`     | string | No       | Product ID (Short ID format `PROD_xxx`). When provided without `storeId`, the server derives the store from the product |
| `buyerIdentity` | string | Yes      | Customer identity for order attribution (e.g., email or internal user ID). Encoded into the session JWT                 |

## Example Request

<CodeGroup>
  ```typescript SDK theme={"system"}
  // Using storeId
  const { token, expiresAt } = await client.auth.issueSessionToken({
    storeId: "STO_2aUyqjCzEIiEcYMKj7TZtw",
    buyerIdentity: "customer@example.com",
  });

  // Using productId (storeId derived automatically)
  const { token, expiresAt } = await client.auth.issueSessionToken({
    productId: "PROD_7J3K5L8M2N4P6Q9R",
    buyerIdentity: "customer@example.com",
  });
  ```

  ```bash cURL (with storeId) theme={"system"}
  MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
  TIMESTAMP=$(date +%s)
  BODY='{"storeId":"STO_2aUyqjCzEIiEcYMKj7TZtw","buyerIdentity":"customer@example.com"}'
  BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 -w 0)
  CANONICAL_REQUEST="POST
  /v1/actions/auth/issue-session-token
  $TIMESTAMP
  $BODY_HASH"

  SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 -w 0)

  curl -X POST "https://api.waffo.ai/v1/actions/auth/issue-session-token" \
    -H "Content-Type: application/json" \
    -H "X-Merchant-Id: $MERCHANT_ID" \
    -H "X-Timestamp: $TIMESTAMP" \
    -H "X-Signature: $SIGNATURE" \
    -d "$BODY"
  ```

  ```bash cURL (with productId) theme={"system"}
  MERCHANT_ID="MER_2aUyqjCzEIiEcYMKj7TZtw"
  TIMESTAMP=$(date +%s)
  BODY='{"productId":"PROD_7J3K5L8M2N4P6Q9R","buyerIdentity":"customer@example.com"}'
  BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 -binary | base64 -w 0)
  CANONICAL_REQUEST="POST
  /v1/actions/auth/issue-session-token
  $TIMESTAMP
  $BODY_HASH"

  SIGNATURE=$(echo -n "$CANONICAL_REQUEST" | openssl dgst -sha256 -sign private_key.pem | base64 -w 0)

  curl -X POST "https://api.waffo.ai/v1/actions/auth/issue-session-token" \
    -H "Content-Type: application/json" \
    -H "X-Merchant-Id: $MERCHANT_ID" \
    -H "X-Timestamp: $TIMESTAMP" \
    -H "X-Signature: $SIGNATURE" \
    -d "$BODY"
  ```

  ```python Python theme={"system"}
  # Using storeId
  result = call_api_with_signature('POST', '/v1/actions/auth/issue-session-token', {
      'storeId': 'STO_2aUyqjCzEIiEcYMKj7TZtw',
      'buyerIdentity': 'customer@example.com'
  })

  # Using productId
  result = call_api_with_signature('POST', '/v1/actions/auth/issue-session-token', {
      'productId': 'PROD_7J3K5L8M2N4P6Q9R',
      'buyerIdentity': 'customer@example.com'
  })
  print(result['data']['token'])
  ```
</CodeGroup>

## Success Response (200)

```json theme={"system"}
{
  "data": {
    "token": "opaque-session-token...",
    "expiresAt": "2024-01-15T11:00:00.000Z"
  }
}
```

## Response Fields

| Field       | Type   | Description                |
| ----------- | ------ | -------------------------- |
| `token`     | string | Session Token              |
| `expiresAt` | string | Expiration time (ISO 8601) |

## Errors

> **Retry policy:** Never retry 4xx — fix the request and resubmit. Retry 5xx with exponential backoff (start 5s, max 3 attempts).

| Status | `errors[0].message`                                       | What it means                                     | Recommended handling                                      |
| ------ | --------------------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------- |
| 400    | `Missing required field: buyerIdentity`                   | `buyerIdentity` is empty or missing               | Fix the request body, then resubmit                       |
| 400    | `Missing required field: provide storeId or productId`    | Neither `storeId` nor `productId` was provided    | Provide one of them, then resubmit                        |
| 400    | `Expected format: STO_xxx, got "..."`                     | `storeId` Short ID could not be decoded           | Fix the `storeId` format, then resubmit                   |
| 400    | `Expected format: PROD_xxx, got "..."`                    | `productId` Short ID could not be decoded         | Fix the `productId` format, then resubmit                 |
| 400    | `Store is not active`                                     | Store exists but its status is not `active`       | Activate the store, then resubmit                         |
| 401    | `Missing merchantId in request context`                   | API Key authentication did not resolve a merchant | Verify API Key headers and signature                      |
| 403    | `Access denied: you do not have permission to this store` | Merchant does not own the store                   | Verify store ownership                                    |
| 404    | `Store not found`                                         | Store does not exist or has been deleted          | Verify the store ID                                       |
| 404    | `Product not found`                                       | Product does not exist                            | Verify the product ID                                     |
| 500    | `Internal server error`                                   | Unexpected server-side failure                    | Retry with exponential backoff (start 5s, max 3 attempts) |
