> ## 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 and get API token

> Authenticate using an API key to obtain a JWT token.
The key's prefix determines the token scope:
- **Merchant key** (`mk_live_…` / `mk_test_…`, from Settings → API Access):
  returns a merchant-scoped token with full access. Named, rotatable and
  revocable per integration.
- **Vendor key** (`vk_live_…` / `vk_test_…`, from the vendor portal):
  returns a vendor-scoped token limited to that vendor's data, carrying
  the scopes declared on the key.

A rotated key keeps working until the end of its grace window, so a
rotation is an overlap rather than a cutover.




## OpenAPI

````yaml openapi-merchant.json POST /authenticate
openapi: 3.0.0
info:
  title: PuppetVendors Merchant API V2
  version: 2.0.0
  description: >-
    The endpoints reachable with a merchant API key (`mk_live_…`), minted from
    Settings → API Access in the PuppetVendors admin. A merchant key administers
    users and vendors, and renews its own token. Everything else in the V2 API,
    including orders, products, payouts, fulfillments and documents, stays on
    the v1 API token and is refused here with a 403. Keys are revealed once at
    creation; rotating one leaves the previous key working for a 24 hour grace
    window.
  contact:
    name: PuppetVendors Support
    url: https://puppetvendors.com
  license:
    name: Proprietary
servers:
  - url: https://production-api.puppetvendors.com
    description: Production
  - url: http://localhost:8082
    description: Local development
security:
  - bearerAuth: []
tags:
  - name: Auth
    description: Authentication endpoints for obtaining and refreshing API tokens
  - name: Portal - Auth
    description: Vendor portal authentication endpoints (vendor user login, token refresh)
  - name: Products
    description: Product management and synchronization
  - name: Orders
    description: Order retrieval and management
  - name: Payouts
    description: Vendor payout information
  - name: Fulfillments
    description: Order fulfillment operations
  - name: Reports
    description: Vendor sales reports and analytics
  - name: Vendors
    description: Vendor management operations
  - name: Settings
    description: Settings endpoints for vendor configuration and management
  - name: Users
    description: User account management
  - name: Shop
    description: Shop configuration and settings
  - name: Commissions
    description: Commission rate management
  - name: Integrations
    description: Vendor integration configuration endpoints
  - name: Line Items
    description: Order line item operations
paths:
  /authenticate:
    post:
      tags:
        - Auth
      summary: Authenticate and get API token
      description: >
        Authenticate using an API key to obtain a JWT token.

        The key's prefix determines the token scope:

        - **Merchant key** (`mk_live_…` / `mk_test_…`, from Settings → API
        Access):
          returns a merchant-scoped token with full access. Named, rotatable and
          revocable per integration.
        - **Vendor key** (`vk_live_…` / `vk_test_…`, from the vendor portal):
          returns a vendor-scoped token limited to that vendor's data, carrying
          the scopes declared on the key.

        A rotated key keeps working until the end of its grace window, so a

        rotation is an overlap rather than a cutover.
      operationId: authenticate
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuthenticateRequest'
            examples:
              merchant:
                summary: Authenticate with a merchant key
                value:
                  apiKey: >-
                    mk_live_9f2ac1b0e7d84a3c5b1f6e8d0a2c4b6f8e0d2c4b6a8f0e2d4c6b8a0f2e4d6c8b
              vendor:
                summary: Authenticate with a vendor key
                value:
                  apiKey: vk_live_xyz789ghi012
      responses:
        '200':
          description: Authentication successful
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthenticateResponse'
              example:
                success: true
                data:
                  token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
                  expiresIn: 1209600
                  scope: merchant
                  shopDomain: my-store.myshopify.com
        '401':
          description: Invalid API key or inactive shop
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                success: false
                error:
                  message: Invalid API key
                  code: UNAUTHORIZED
      security: []
components:
  schemas:
    AuthenticateRequest:
      type: object
      required:
        - apiKey
      properties:
        apiKey:
          type: string
          description: Shop's openApiToken for authentication
          example: sk_live_abc123def456
        shopDomain:
          type: string
          description: >-
            Optional shop domain (V1 compatibility). When provided, must match
            the shop for the apiKey.
          example: my-store.myshopify.com
        vendorId:
          type: string
          description: Optional vendor ObjectId for vendor-scoped token
          example: 507f1f77bcf86cd799439011
    AuthenticateResponse:
      type: object
      properties:
        success:
          type: boolean
          enum:
            - true
        data:
          type: object
          properties:
            token:
              type: string
              description: JWT token for API authentication
              example: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
            expiresIn:
              type: integer
              description: Token expiry time in seconds
              example: 1209600
            scope:
              type: string
              enum:
                - merchant
                - vendor
              description: Token scope indicating access level
            permissions:
              type: array
              items:
                type: string
              description: >-
                Optional list of coarse-grained permissions granted to this
                token (e.g., admin:users, admin:vendors). When omitted, the
                token has full access for its scope.
            shopDomain:
              type: string
              description: Shop domain (included for V1 API compatibility)
              example: my-store.myshopify.com
            vendorId:
              type: string
              description: >-
                Vendor ID — only present for vendor-scope tokens (when
                authenticating with a `vk_*` vendor key). Identifies which
                vendor the public API call originates from.
              example: 507f1f77bcf86cd799439011
            vendorEmail:
              type: string
              description: >-
                Vendor reporting email — only present for vendor-scope tokens
                when the vendor has a reportingEmail set. Useful for confirming
                which vendor account the key belongs to.
              example: vendor@example.com
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          enum:
            - false
          description: Indicates the request failed
        error:
          type: object
          required:
            - message
          properties:
            message:
              type: string
              description: Human-readable error message
              example: Resource not found
            code:
              type: string
              description: >-
                Stable machine-readable error code. The frontend uses this as
                its localisation key (e.g. errors.api.<code>). Server errors
                always report INTERNAL_SERVER_ERROR.
              example: NOT_FOUND
            errorId:
              type: string
              description: >-
                Correlation id for support/log lookup. Present on opaque 5xx
                responses so a user can quote a reference for the underlying
                (server-side logged) error.
              example: err_1783365360839_j281w7b
            details:
              type: object
              description: >-
                Additional client-error context (e.g. field-level validation
                errors). Never populated for server errors.
  securitySchemes:
    bearerAuth:
      type: apiKey
      in: header
      name: x-access-token
      description: >-
        JWT minted from a merchant API key (`mk_live_…`) by POST /authenticate.
        Send the token value directly, with no "Bearer" prefix. Tokens last 14
        days and can be renewed at POST /refresh-token; revoking the key refuses
        the next request made with any token minted from it.

````