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

# Authenticate

> Exchange your vendor API key for a JWT token

<Note>
  **V2 Preview** — This endpoint is part of the V2 API preview. Breaking changes may occur.
</Note>

## Overview

Exchange your vendor API key for a short-lived JWT token. The token is scoped to your vendor account and carries the permissions granted to your API key.

Tokens expire after **24 hours**. When a token expires, either re-authenticate or use [POST /refresh-token](/api-reference/v2/endpoint/vendor-refresh-token) to get a new one.

### Use Cases

* **Vendor portal apps** — Secure, isolated access to your vendor data
* **Custom integrations** — Sync your orders, products, and payouts with external systems
* **AI agents** — Programmatic access with scoped permissions

## Request Body

<ParamField body="apiKey" type="string" required>
  Your vendor API key (starts with `vk_`). Create one in the vendor portal under Settings > API Keys, or ask your merchant.
</ParamField>

<ParamField body="shopDomain" type="string">
  Optional. The shop is resolved from your API key. Only send this if your key works across multiple shops — if it doesn't match, the request is rejected.
</ParamField>

## Response

```json 200 theme={null}
{
  "success": true,
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "expiresIn": 86400,
    "scope": "vendor",
    "permissions": ["orders:read", "products:read", "products:write", "fulfillments:read"],
    "shopDomain": "my-store.myshopify.com",
    "mode": "live",
    "vendorId": "507f1f77bcf86cd799439012"
  }
}
```

### Response Fields

| Field         | Type      | Description                                                                                                                                            |
| ------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `token`       | string    | JWT token to use in the `x-access-token` header                                                                                                        |
| `expiresIn`   | number    | Token lifetime in seconds (always 86400 = 24 hours)                                                                                                    |
| `scope`       | string    | Always `"vendor"` for vendor API keys                                                                                                                  |
| `permissions` | string\[] | The specific scopes granted to your API key (e.g., `orders:read`, `products:write`). See [API Keys & Scopes](/api-reference/v2/vendor/api-keys-scopes) |
| `shopDomain`  | string    | The Shopify store domain associated with your key                                                                                                      |
| `mode`        | string    | `"live"` or `"test"` — matches your API key mode                                                                                                       |
| `vendorId`    | string    | Your vendor account ID                                                                                                                                 |

### Error Responses

```json 401 theme={null}
{ "success": false, "error": { "message": "Invalid API key", "code": "UNAUTHORIZED" } }
```

```json 401 theme={null}
{ "success": false, "error": { "message": "API key revoked", "code": "UNAUTHORIZED" } }
```

```json 401 theme={null}
{ "success": false, "error": { "message": "Shop is not active", "code": "UNAUTHORIZED" } }
```

```json 401 theme={null}
{ "success": false, "error": { "message": "The provided shopDomain is not available.", "code": "UNAUTHORIZED" } }
```

```json 429 theme={null}
{ "success": false, "error": { "message": "Too many authentication requests", "code": "RATE_LIMITED" } }
```

## Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://staging-api.puppetvendors.com/authenticate \
    -H "Content-Type: application/json" \
    -d '{
      "apiKey": "vk_live_x9y8z7w6v5u4..."
    }'
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://staging-api.puppetvendors.com/authenticate",
      json={"apiKey": "vk_live_x9y8z7w6v5u4..."}
  )

  data = response.json()["data"]
  token = data["token"]
  permissions = data["permissions"]
  print(f"Token scope: {data['scope']}, permissions: {permissions}")
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch("https://staging-api.puppetvendors.com/authenticate", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ apiKey: "vk_live_x9y8z7w6v5u4..." })
  });

  const { data } = await response.json();
  const token = data.token;
  // Use token in subsequent requests:
  // headers: { "x-access-token": token }
  ```
</CodeGroup>
