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

# Sign in with the code

> Trades the emailed code for the buyer's token, which every other route of the Customer API takes as `Authorization: Bearer shoply_ct_...`. It reaches this buyer's own orders at this store and nothing else, and works for 30 days.

Keep it where only your page or app can read it, never in an address. A buyer holds 20 tokens at a store at most: a 21st ends their oldest.

A wrong code is `code_wrong`, and a code past its 10 minutes or its five tries is `code_expired`. After 20 wrong codes in a day for one address, none is checked for it until the day is over (`code_paused`).

It is counted for the address that asks: 30 in fifteen minutes.



## OpenAPI

````yaml /api-reference/openapi.json post /stores/{storeId}/customer/verify
openapi: 3.1.0
info:
  title: Shoply API
  version: '1'
  description: >-
    Everything a store's own server can do with a secret API key: its catalogue,
    orders, customers, marketing, finance and the rest of what the dashboard
    does. And the Customer API, which a buyer's own device asks with a token of
    theirs.
servers:
  - url: https://api.shoply.gg/v1
security:
  - apiKey: []
tags:
  - name: API key
  - name: Store
  - name: Domain
  - name: Payment methods
  - name: Analytics
  - name: Storefronts
  - name: Storefront code
  - name: Payment Routing
  - name: Custom payment methods
  - name: Products
  - name: Product pictures
  - name: Stock
  - name: Categories
  - name: Upsells
  - name: Subscriptions
  - name: Orders
  - name: Invoices
  - name: Reviews
  - name: Coupons
  - name: Coupon categories
  - name: Coupon pop-up
  - name: Sales
  - name: Blog
  - name: Search settings
  - name: Redirects
  - name: Sitemap
  - name: Cart Recovery
  - name: Email Marketing
  - name: Email Templates
  - name: Customers
  - name: Affiliates
  - name: Support Tickets
  - name: Blacklist
  - name: Fraud protection
  - name: Disputes
  - name: Finance
  - name: Tax
  - name: Expenses
  - name: Expense setup
  - name: API requests
  - name: Webhook endpoints
  - name: Webhook deliveries
  - name: Customer API
paths:
  /stores/{storeId}/customer/verify:
    post:
      tags:
        - Customer API
      summary: Sign in with the code
      description: >-
        Trades the emailed code for the buyer's token, which every other route
        of the Customer API takes as `Authorization: Bearer shoply_ct_...`. It
        reaches this buyer's own orders at this store and nothing else, and
        works for 30 days.


        Keep it where only your page or app can read it, never in an address. A
        buyer holds 20 tokens at a store at most: a 21st ends their oldest.


        A wrong code is `code_wrong`, and a code past its 10 minutes or its five
        tries is `code_expired`. After 20 wrong codes in a day for one address,
        none is checked for it until the day is over (`code_paused`).


        It is counted for the address that asks: 30 in fifteen minutes.
      operationId: customer.verify
      parameters:
        - name: storeId
          in: path
          required: true
          description: >-
            The store's ID, from Settings, General in its dashboard. It is not a
            secret: a page may show it.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                email:
                  type: string
                  description: The address the code was sent to.
                  example: ada@example.com
                code:
                  type: string
                  description: The six digits from the email.
                  example: '493021'
              required:
                - email
                - code
      responses:
        '200':
          description: It worked.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                  message:
                    nullable: true
                  code:
                    nullable: true
                  data:
                    type: object
                    properties:
                      token:
                        type: string
                      tokenType:
                        type: string
                      expiresAt:
                        type: string
                      email:
                        type: string
              example:
                success: true
                message: null
                code: null
                data:
                  token: shoply_ct_8e41d0…
                  tokenType: Bearer
                  expiresAt: '2026-11-21T16:20:19Z'
                  email: grace@example.com
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          $ref: '#/components/responses/Refused'
        '429':
          $ref: '#/components/responses/CustomerTooMany'
      security: []
      x-codeSamples:
        - lang: javascript
          label: Node.js
          source: |
            import { ShoplyCustomer } from "@shoplygg/node";

            const buyer = new ShoplyCustomer({ storeId: "YOUR_STORE_ID" });

            const result = await buyer.verify({
              email: "ada@example.com",
              code: "493021",
            });
        - lang: php
          label: PHP
          source: |
            <?php

            require 'vendor/autoload.php';

            $buyer = new Shoply\Customer(['storeId' => 'YOUR_STORE_ID']);

            $result = $buyer->verify([
                'email' => 'ada@example.com',
                'code' => '493021',
            ]);
        - lang: python
          label: Python
          source: |
            import shoply

            buyer = shoply.Customer("YOUR_STORE_ID")

            result = buyer.verify(email="ada@example.com", code="493021")
components:
  responses:
    NotFound:
      description: >-
        There is no such thing in this store: `not_found`. A store that is not
        the key's own is answered the same way.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Refusal'
    Refused:
      description: >-
        The request was understood and not carried out. `validation_failed` says
        what is wrong with each field under `errors`; other codes are the
        route's own.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Refusal'
    CustomerTooMany:
      description: >-
        Too many requests for now: `rate_limited`, or the route's own
        (`code_cooldown`, `code_paused`, `store_busy`). `Retry-After` says how
        many seconds to wait.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Refusal'
  schemas:
    Refusal:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          description: What is wrong, in words for a person.
        code:
          type: string
          description: What is wrong, as a word that does not change.
        data:
          nullable: true
        errors:
          type: object
          description: >-
            For `validation_failed`: what is wrong with each field, by the
            field's name.
          additionalProperties:
            type: string
      required:
        - success
        - message
        - code
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: >-
        A secret API key, made under Developers in the dashboard:
        `Authorization: Bearer shoply_sk_...`

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.