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

# Prepare checkout

> Prepare a Permit2 authorization for the selected cards, recipient, destination and courier at the quoted price.

1. Show the exact cards, recipient, address, courier and total to the wallet owner.
2. Use the server’s quote for the fee. The preparation binds these details to your builder.
3. Before submission, check the wallet’s USDT allowance for Permit2 at `permitTypedData.domain.verifyingContract`. It must cover `permitTypedData.message.permitted.amount`. If it is short, approve the required amount and wait for confirmation. The witness signature alone does not grant this allowance.
4. Save the preparation ID and ask the wallet to sign the single Permit2 witness authorization.

## Request

Builder key and wallet access token

## Response

## Error codes

Match the HTTP status and response text to a row below. For guidance on codes shared across endpoints, see [Error meanings and recovery](https://docs.renaiss.xyz/api-reference/errors.md).

| HTTP | Error code | Text field | Response text and recovery |
| :- | :- | :- | :- |
| `400` | `WRONG_REQUEST_PARAMS` | `error` | `Invalid redemption input` `Request body is too large` A field is missing or has the wrong form; a collectible is not ready for redemption; the collectibles are not in one region; a collectible has no declared value; or the destination is not supported or needs a state. Fix the request and send it again. It is also used when the quote has expired or the courier is not part of the quote: ask for a new quote. |
| `401` | `API_AUTH_INVALID_CREDENTIAL` | `error` | `Invalid authentication credential` The builder key or the wallet access token is malformed, unknown, expired or revoked. Check the key. For the token, refresh the tokens or have the wallet sign in again. |
| `401` | `API_AUTH_MISSING_CREDENTIAL` | `error` | `Required authentication credential is missing` The builder key or the wallet access token is missing. Send both: the key in the `x-builder-api-key` header and the token as a Bearer token. |
| `403` | `API_AUTH_CREDENTIAL_NOT_ALLOWED` | `error` | `Credential is not allowed by this policy` A credential this route does not take was sent. Send the builder key and the wallet access token only. |
| `403` | `API_AUTH_INSUFFICIENT_SCOPE` | `error` | `Required authentication scope is missing` The wallet access token lacks the scope this route needs: `redeem:read` to read, `redeem:write` to change. Have the wallet sign in again and ask for the scope. |
| `403` | `API_AUTH_INTEGRATION_MISMATCH` | `error` | `Authentication integrations do not match` The wallet access token was issued to another builder than the key. Use the key of the builder that issued the token. |
| `403` | `API_AUTH_SUBJECT_MISMATCH` | `error` | `Authentication subjects do not match` The wallet access token is not for the chain of this API. Have the wallet sign in again for the right chain. |
| `403` | `GACHA_V3_BUILDER_NOT_ACCEPTED_ON_PUBLIC_API` | `error` | `This builder checks out on its own surface, not on the public API` This builder key cannot be used on this API. Do not retry; contact Renaiss. |
| `403` | `WRONG_REQUEST_PARAMS` | `error` | `Every collectible must be owned by the authenticated EOA` A collectible in the cart is not owned by the wallet of the wallet access token. Send only collectibles the wallet owns. |
| `404` | `REDEMPTION_ORDER_NOT_FOUND` | `error` | `Not found or expired` `Not found` There is no such quote or preparation for this wallet and builder, or it has expired. Ask for a new quote. |
| `429` | `API_AUTH_RATE_LIMITED` | `error` | `Authentication rate limit exceeded` The builder key hit its rate limit. Wait a little, then retry at a lower rate. |
| `500` | `API_AUTH_INVALID_CONFIGURATION` | `error` | `Internal server error` Contact Renaiss with `x-request-id` if wallet authentication keeps failing. |
| `500` | `API_AUTH_ERROR` | `error` | `Internal server error` |
| `500` | `FUNCTION_ERROR` | `error` | `Internal server error` |
| `503` | `FUNCTION_ERROR` | `error` | `Internal server error` |


## OpenAPI

````yaml api-reference/openapi.json POST /v2/redeem/checkout/prepare
openapi: 3.1.1
info:
  version: 1.0.0
  title: Renaiss Builder API v2
  description: >-
    Builder API v2 for gacha, marketplace and redemption with external wallets
    on BNB Smart Chain (chain 56). Any active, approved builder key can prepare
    purchases.


    A collectible is an item a wallet can pull, trade, sell back or redeem, such
    as a card. This API calls every such item a collectible (e.g. cards), in
    paths, fields and descriptions.


    Browse publicly, then prepare and sign actions with the buyer wallet. Gacha
    history and buyback offers require your builder key; purchases and buybacks
    also require a wallet action signature. Private shipping data and redemption
    require a wallet access token, which the API issues from a registered
    partner origin after the wallet signs a sign-in message. Gacha and
    marketplace never use a wallet access token. Keep the builder key on your
    backend.


    The acting wallet is an EOA or a deployed ERC-1271 contract account.
    EIP-7702 delegated accounts, ERC-6492 and ERC-8010 wrapped signatures and
    Renaiss-managed Safes are refused (a Safe only after its signature
    verified). A pull to a contract account that cannot receive ERC-721 tokens
    returns `CONTRACT_WALLET_CANNOT_RECEIVE_NFT`. A failed chain read returns
    `API_AUTH_ERROR` (500). Wallet access tokens and redemption are EOA only.
servers:
  - url: https://api.renaiss.xyz
    description: BNB Smart Chain
  - url: https://dev-api.renaiss.xyz
    description: BNB testnet
security: []
tags:
  - name: Gacha v2
    description: >-
      Direct-EOA pack browsing, purchases, collectible (e.g. card) reveals,
      purchase history and buybacks. Start here; no wallet access token is
      needed.
  - name: Marketplace
    description: >-
      Public collectible (e.g. card) browsing and external-wallet asks, bids,
      purchases and cancellations. Trading requires builder authorization and
      wallet action signatures.
  - name: Users
    description: >-
      What one wallet address has and did: its collectibles (e.g. cards), their
      total market value and its activities. The whole wallet, whichever builder
      it used. Requires your builder key only.
  - name: Redemption
    description: >-
      Shipping eligibility, quotes, redemption preparation, submission and
      tracking. Requires your builder key and a wallet access token for the same
      wallet.
  - name: Wallet access tokens
    description: >-
      Get, refresh and revoke the wallet access tokens that Redeem needs. The
      wallet signs a sign-in message (valid 5 minutes, one use); the API returns
      a wallet access token (15 minutes) and a refresh token (7 days, single
      use). Register exact partner frontend origins with Renaiss before use.
      Gacha and marketplace never use a wallet access token.
paths:
  /v2/redeem/checkout/prepare:
    post:
      tags:
        - Redemption
      summary: Prepare an EOA Permit2 redemption from a saved quote
      description: >-
        Prepare a Permit2 authorization for the selected cards, recipient,
        destination and courier at the quoted price.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                quoteId:
                  type: string
                  format: uuid
                courierId:
                  type: string
                recipient:
                  type: object
                  properties:
                    name:
                      type: string
                      minLength: 1
                      maxLength: 22
                    phone:
                      type: string
                      pattern: ^\+[1-9]\d{6,14}$
                    email:
                      type: string
                      maxLength: 50
                      format: email
                    taxId:
                      type: string
                      maxLength: 100
                    chineseName:
                      type: string
                      maxLength: 100
                  required:
                    - name
                    - phone
                    - email
                  additionalProperties: false
                insurance:
                  type: boolean
              required:
                - quoteId
                - courierId
                - recipient
                - insurance
              additionalProperties: false
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                type: object
                properties:
                  preparationId:
                    type: string
                    format: uuid
                  requestId:
                    type: string
                    description: 32 bytes encoded as 0x followed by 64 hexadecimal digits.
                  walletAddress:
                    type: string
                    description: >-
                      20-byte, 0x-prefixed wallet or contract address. Use
                      lowercase or a valid checksum.
                  tokenIds:
                    type: array
                    items:
                      type: string
                      pattern: ^\d{1,78}$
                      description: >-
                        Unsigned decimal integer smaller than 2^256, encoded as
                        a string.
                    minItems: 1
                    maxItems: 50
                    description: >-
                      Each numeric token ID may occur once. For example, "1" and
                      "01" identify the same token.
                  expiresAt:
                    type: string
                    format: date-time
                  address:
                    type: object
                    properties:
                      countryCode:
                        type: string
                        pattern: ^[A-Z]{2}$
                      addressLine1:
                        type: string
                        minLength: 1
                        maxLength: 35
                      addressLine2:
                        type: string
                        maxLength: 35
                      city:
                        type: string
                        minLength: 1
                        maxLength: 200
                      state:
                        type: string
                        maxLength: 200
                      postalCode:
                        type: string
                        minLength: 1
                        maxLength: 20
                    required:
                      - countryCode
                      - addressLine1
                      - city
                      - postalCode
                    additionalProperties: false
                  recipient:
                    type: object
                    properties:
                      name:
                        type: string
                        minLength: 1
                        maxLength: 22
                      phone:
                        type: string
                        pattern: ^\+[1-9]\d{6,14}$
                      email:
                        type: string
                        maxLength: 50
                        format: email
                      taxId:
                        type: string
                        maxLength: 100
                      chineseName:
                        type: string
                        maxLength: 100
                    required:
                      - name
                      - phone
                      - email
                    additionalProperties: false
                  courierName:
                    type: string
                  fees:
                    type: object
                    properties:
                      handlingFeeInUsd:
                        type: string
                        pattern: ^\d{1,78}$
                        description: >-
                          Unsigned decimal integer smaller than 2^256, encoded
                          as a string.
                      shippingFeeInUsd:
                        type: string
                        pattern: ^\d{1,78}$
                        description: >-
                          Unsigned decimal integer smaller than 2^256, encoded
                          as a string.
                      insuranceFeeInUsd:
                        type: string
                        pattern: ^\d{1,78}$
                        description: >-
                          Unsigned decimal integer smaller than 2^256, encoded
                          as a string.
                      dutyAndTaxesInUsd:
                        type: string
                        pattern: ^\d{1,78}$
                        description: >-
                          Unsigned decimal integer smaller than 2^256, encoded
                          as a string.
                      totalFeeInUsdt:
                        type: string
                        pattern: ^\d{1,78}$
                        description: >-
                          Unsigned decimal integer smaller than 2^256, encoded
                          as a string.
                    required:
                      - handlingFeeInUsd
                      - shippingFeeInUsd
                      - insuranceFeeInUsd
                      - dutyAndTaxesInUsd
                      - totalFeeInUsdt
                  redemptionTypedData:
                    type: object
                    properties:
                      domain:
                        type: object
                        properties:
                          name:
                            type: string
                          version:
                            type: string
                          chainId:
                            type: integer
                          verifyingContract:
                            type: string
                            description: >-
                              20-byte, 0x-prefixed wallet or contract address.
                              Use lowercase or a valid checksum.
                        required:
                          - name
                          - chainId
                          - verifyingContract
                      types:
                        type: object
                        additionalProperties:
                          type: array
                          items:
                            type: object
                            properties:
                              name:
                                type: string
                              type:
                                type: string
                            required:
                              - name
                              - type
                      primaryType:
                        type: string
                      message:
                        type: object
                        additionalProperties: {}
                    required:
                      - domain
                      - types
                      - primaryType
                      - message
                  permitTypedData:
                    type: object
                    properties:
                      domain:
                        type: object
                        properties:
                          name:
                            type: string
                          version:
                            type: string
                          chainId:
                            type: integer
                          verifyingContract:
                            type: string
                            description: >-
                              20-byte, 0x-prefixed wallet or contract address.
                              Use lowercase or a valid checksum.
                        required:
                          - name
                          - chainId
                          - verifyingContract
                      types:
                        type: object
                        additionalProperties:
                          type: array
                          items:
                            type: object
                            properties:
                              name:
                                type: string
                              type:
                                type: string
                            required:
                              - name
                              - type
                      primaryType:
                        type: string
                      message:
                        type: object
                        additionalProperties: {}
                    required:
                      - domain
                      - types
                      - primaryType
                      - message
                required:
                  - preparationId
                  - requestId
                  - walletAddress
                  - tokenIds
                  - expiresAt
                  - address
                  - recipient
                  - courierName
                  - fees
                  - redemptionTypedData
                  - permitTypedData
        '400':
          description: >-
            The request was refused before anything happened.


            See [error codes and
            recovery](/api-reference/redeem/prepare-checkout#http-errors).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: A short sentence about what went wrong.
                  code:
                    type: string
                    enum:
                      - WRONG_REQUEST_PARAMS
                required:
                  - error
                  - code
              example:
                error: Invalid redemption input
                code: WRONG_REQUEST_PARAMS
        '401':
          description: >-
            The builder key or the wallet access token is not accepted.


            See [error codes and
            recovery](/api-reference/redeem/prepare-checkout#http-errors).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: A short sentence about what went wrong.
                  code:
                    type: string
                    enum:
                      - API_AUTH_MISSING_CREDENTIAL
                      - API_AUTH_INVALID_CREDENTIAL
                required:
                  - error
                  - code
              example:
                error: Required authentication credential is missing
                code: API_AUTH_MISSING_CREDENTIAL
        '403':
          description: >-
            A collectible is not owned by this wallet.


            See [error codes and
            recovery](/api-reference/redeem/prepare-checkout#http-errors).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: A short sentence about what went wrong.
                  code:
                    type: string
                    enum:
                      - WRONG_REQUEST_PARAMS
                      - API_AUTH_INSUFFICIENT_SCOPE
                      - API_AUTH_INTEGRATION_MISMATCH
                      - API_AUTH_SUBJECT_MISMATCH
                      - API_AUTH_CREDENTIAL_NOT_ALLOWED
                      - GACHA_V3_BUILDER_NOT_ACCEPTED_ON_PUBLIC_API
                required:
                  - error
                  - code
              example:
                error: Every collectible must be owned by the authenticated EOA
                code: WRONG_REQUEST_PARAMS
        '404':
          description: >-
            The quote or preparation was not found.


            See [error codes and
            recovery](/api-reference/redeem/prepare-checkout#http-errors).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: A short sentence about what went wrong.
                  code:
                    type: string
                    enum:
                      - REDEMPTION_ORDER_NOT_FOUND
                required:
                  - error
                  - code
              example:
                error: Not found or expired
                code: REDEMPTION_ORDER_NOT_FOUND
        '429':
          description: >-
            Too many requests with this builder key.


            See [error codes and
            recovery](/api-reference/redeem/prepare-checkout#http-errors).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: A short sentence about what went wrong.
                  code:
                    type: string
                    enum:
                      - API_AUTH_RATE_LIMITED
                required:
                  - error
                  - code
              example:
                error: Authentication rate limit exceeded
                code: API_AUTH_RATE_LIMITED
        '500':
          description: >-
            A failure on our side. Retry later.


            See [error codes and
            recovery](/api-reference/redeem/prepare-checkout#http-errors).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: A short sentence about what went wrong.
                  code:
                    type: string
                required:
                  - error
                  - code
              example:
                error: Internal server error
                code: FUNCTION_ERROR
        '503':
          description: >-
            A failure on our side: checkout storage is not available. Retry in a
            few seconds.


            See [error codes and
            recovery](/api-reference/redeem/prepare-checkout#http-errors).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    description: A short sentence about what went wrong.
                  code:
                    type: string
                required:
                  - error
                  - code
              example:
                error: Internal server error
                code: FUNCTION_ERROR
      security:
        - builderAuth: []
          walletSession: []
components:
  securitySchemes:
    builderAuth:
      type: apiKey
      in: header
      name: x-builder-api-key
      description: >-
        Your approved builder API key. Keep it on your backend. Gacha and
        marketplace writes also require wallet action signatures. Redeem also
        needs a wallet access token, a Bearer token the API issues after the
        wallet signs a sign-in message.
    walletSession:
      type: http
      scheme: bearer
      description: 'Wallet access token: Bearer authentication for Redeem'

````

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