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

# Signed message → bearer token



## OpenAPI

````yaml https://api.tozzecard.xyz/openapi.json post /auth/verify
openapi: 3.1.0
info:
  title: Tozzecard API
  version: 1.0.0
  description: >-
    Backend for the Tozzecard app: card sign-in, card face and statement, agent
    strategy, portfolio, agent feed, market hours and the demo B402 merchant.


    **Sign in with the card key** (the EOA the browser unlocks with the
    passkey):

    1. `POST /auth/challenge {address}` → `{message}`

    2. `account.signMessage({ message })` (viem)

    3. `POST /auth/verify {message, signature}` → `{token, address, kyc, card}`.

    4. Send `Authorization: Bearer <token>` on `/me*`, `/kyc/session` and `PUT
    /strategy`. Tokens last 30 days.


    **Activating the card** (identity check with Didit): while `kyc` is not
    `approved`, `card` is null. `POST /kyc/session {returnUrl?}` → `{url}`; open
    it; Didit sends the user back to `returnUrl`; poll `GET /me` while `kyc` is
    `pending`. On approval the card is issued with the holder name from the
    document.


    **Paying a merchant order** (B402 / x402 v2): `GET
    /merchant/orders/{id}/pay` → 402 with `accepts[0]`; build and sign with
    `@tozzecard/binance/eip3009` (`transferAuthorization`, `signTypedData`,
    `paymentHeader`); `POST` the same URL with header `PAYMENT-SIGNATURE`. The
    receipt comes back in `PAYMENT-RESPONSE`.


    Errors are `{error, code?}`. Amounts in USD are numbers; on-chain amounts
    are decimal strings.
servers:
  - url: https://api.tozzecard.xyz
    description: VPS (BSC mainnet)
  - url: http://localhost:8787
    description: Local
security: []
tags:
  - name: Card
    description: Sign-in and the card itself
  - name: Agent
    description: Strategy, portfolio and the agent's decisions
  - name: Market
    description: US market hours and tokenized stock prices
  - name: Merchant
    description: Demo merchant accepting USD1 through B402
  - name: System
paths:
  /auth/verify:
    post:
      tags:
        - Card
      summary: Signed message → bearer token
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - message
                - signature
              properties:
                message:
                  type: string
                  description: exactly as /auth/challenge returned it
                signature:
                  type: string
                  description: EIP-191 personal_sign by the card key
            example:
              message: |-
                Sign in to Tozzecard
                ...
              signature: 0x...
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                  address:
                    type: string
                  kyc:
                    $ref: '#/components/schemas/Kyc'
                  card:
                    anyOf:
                      - $ref: '#/components/schemas/Card'
                      - type: 'null'
                    description: null until kyc is approved
        '400':
          description: message and signature are required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Unknown, used or expired message, or not signed by the card key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  schemas:
    Kyc:
      enum:
        - none
        - pending
        - approved
        - declined
        - duplicate
      description: >-
        Identity check. none: not started (or abandoned/expired, start again);
        pending: in Didit or in review; declined: refused (may retry);
        duplicate: this document already holds another card.
    Card:
      type: object
      description: >-
        Card face, issued after the identity check. holder is the name on the
        verified document. number and cvv are derived from the card address
        (same card, same digits) and identify it in the app only (prefix 9406,
        Luhn-valid, not a payment-network number); payments are passkey-signed
        B402 authorizations.
      properties:
        address:
          type: string
          example: '0x0cA6De9ce4843846210Dec81C3f6032773376EAB'
        holder:
          type: string
          example: KIEL TAME
        number:
          type: string
          example: '9406472632795151'
        expiry:
          type: string
          description: MM/YY
          example: 10/29
        cvv:
          type: string
          example: '775'
        createdAt:
          type: number
          description: issued at, ms since epoch
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
        code:
          type: string

````

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