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

# Create a checkout

> Creates a checkout from your server with its product, plan, buyer email and your reference
fixed, and returns its `checkout_url` for you to send the buyer to. On that page the buyer
cannot change the email you set; the other details stay theirs to correct. Your `metadata`
and `external_reference` cannot be changed by the buyer and arrive on the order's webhooks.

**`checkout_url` comes only with the create response.** The checkout stores a digest of its
token, so retrieving the checkout does not return it; a repeat of the create with the same
`Idempotency-Key` within 24 hours replays that response, link included.

**`Idempotency-Key` is required.** A repeat with the same key answers with the same checkout.

Ids are COPE's public ids: a line's `plan_id` is the plan's `plan_` id; an integer is refused
with `validation_error` (422). A `success_url` or `cancel_url` must be one you registered as a
redirect URL, or the request is refused with `invalid_redirect_url` (422). A key COPE reserves
inside `metadata` is refused with `reserved_metadata_key` (422), and a member this operation
does not take with `invalid_request` (400).

To confirm a payment, retrieve the checkout by its `chk_` id and read `order`, rather than
matching on `external_reference`.

Requires the `orders` permission at `write`. An API key holds a permission at the lower of its own level (`read` for a read-only key) and its holder's role; a key without it is refused with 403.



## OpenAPI

````yaml /api-reference/commerce-v1.openapi.json post /v1/commerce/checkouts
openapi: 3.0.3
info:
  description: >-
    Public REST API for COPE vendor integrations. Authenticate with a COPE API
    key and call the endpoints described below.
  title: COPE Public API
  version: v1
servers:
  - description: Production
    url: https://api.cope.com
security:
  - cope_sk: []
paths:
  /v1/commerce/checkouts:
    post:
      tags:
        - Checkouts
      summary: Create a checkout
      description: >-
        Creates a checkout from your server with its product, plan, buyer email
        and your reference

        fixed, and returns its `checkout_url` for you to send the buyer to. On
        that page the buyer

        cannot change the email you set; the other details stay theirs to
        correct. Your `metadata`

        and `external_reference` cannot be changed by the buyer and arrive on
        the order's webhooks.


        **`checkout_url` comes only with the create response.** The checkout
        stores a digest of its

        token, so retrieving the checkout does not return it; a repeat of the
        create with the same

        `Idempotency-Key` within 24 hours replays that response, link included.


        **`Idempotency-Key` is required.** A repeat with the same key answers
        with the same checkout.


        Ids are COPE's public ids: a line's `plan_id` is the plan's `plan_` id;
        an integer is refused

        with `validation_error` (422). A `success_url` or `cancel_url` must be
        one you registered as a

        redirect URL, or the request is refused with `invalid_redirect_url`
        (422). A key COPE reserves

        inside `metadata` is refused with `reserved_metadata_key` (422), and a
        member this operation

        does not take with `invalid_request` (400).


        To confirm a payment, retrieve the checkout by its `chk_` id and read
        `order`, rather than

        matching on `external_reference`.


        Requires the `orders` permission at `write`. An API key holds a
        permission at the lower of its own level (`read` for a read-only key)
        and its holder's role; a key without it is refused with 403.
      operationId: commerce.checkouts.create
      parameters:
        - description: >-
            Required. At most 255 characters of valid UTF-8 with no NUL byte. A
            retry that carries the same key and the same body returns the
            original response instead of performing the write a second time. The
            same key with a different body is refused with 409
            idempotency_conflict. Keys are remembered for 24 hours. A returned
            original response carries the header `Idempotent-Replayed: true`.
          in: header
          name: Idempotency-Key
          required: true
          schema:
            maxLength: 255
            type: string
      requestBody:
        content:
          application/json:
            schema:
              additionalProperties: false
              properties:
                buyer_identity:
                  additionalProperties: false
                  properties:
                    billing_address:
                      additionalProperties: false
                      properties:
                        city:
                          type: string
                        country:
                          type: string
                        line1:
                          type: string
                        line2:
                          type: string
                        postal_code:
                          type: string
                        region:
                          type: string
                      type: object
                    buyer_type:
                      type: string
                    company:
                      type: string
                    country:
                      type: string
                    email:
                      type: string
                    first_name:
                      type: string
                    last_name:
                      type: string
                    phone:
                      type: string
                    postal_code:
                      type: string
                    shipping_address:
                      additionalProperties: false
                      properties:
                        city:
                          type: string
                        country:
                          type: string
                        line1:
                          type: string
                        line2:
                          type: string
                        postal_code:
                          type: string
                        region:
                          type: string
                      type: object
                    vat_id:
                      type: string
                  required:
                    - email
                    - country
                    - postal_code
                  type: object
                checkout:
                  additionalProperties: false
                  properties:
                    cancel_url:
                      format: uri
                      type: string
                    embed_origin:
                      type: string
                    success_url:
                      format: uri
                      type: string
                  type: object
                currency:
                  type: string
                external_reference:
                  maxLength: 255
                  minLength: 1
                  type: string
                lines:
                  items:
                    additionalProperties: false
                    properties:
                      plan_id:
                        pattern: ^plan_[A-Za-z0-9]+$
                        type: string
                      product_id:
                        example: prod_A1b2C3d4
                        pattern: ^prod_[A-Za-z0-9]{8,32}$
                        type: string
                      quantity:
                        maximum: 1000
                        minimum: 1
                        type: integer
                    required:
                      - product_id
                    type: object
                  minItems: 1
                  type: array
                locale:
                  type: string
                metadata:
                  allOf:
                    - $ref: '#/components/schemas/CommerceMerchantMetadata'
                  description: >-
                    Your own keys. `external_reference`,
                    `intended_payment_method` and the keys COPE reserves are
                    refused inside it with `reserved_metadata_key`.
              required:
                - external_reference
                - currency
                - lines
                - buyer_identity
              type: object
      responses:
        '201':
          content:
            application/json:
              schema:
                additionalProperties: false
                properties:
                  data:
                    additionalProperties: false
                    properties:
                      buyer_email_locked:
                        type: boolean
                      cancel_url:
                        nullable: true
                        type: string
                      checkout_url:
                        description: 'Returned by create only: COPE stores a digest of it.'
                        format: uri
                        type: string
                      created_at:
                        format: date-time
                        type: string
                      embed_origin:
                        description: Returned by create only, when embeddable.
                        type: string
                      embed_url:
                        description: Returned by create only, when embeddable.
                        format: uri
                        type: string
                      expires_at:
                        format: date-time
                        type: string
                      external_reference:
                        nullable: true
                        type: string
                      id:
                        example: chk_A1b2C3d4E5f6G7h8
                        pattern: ^chk_[A-Za-z0-9]{8,32}$
                        type: string
                      metadata:
                        allOf:
                          - $ref: '#/components/schemas/CommerceMerchantMetadata'
                        description: Your own keys the checkout carries, as you sent them.
                      object:
                        enum:
                          - checkout
                        type: string
                      order:
                        additionalProperties: false
                        nullable: true
                        properties:
                          id:
                            example: ord_A1b2C3d4E5f6
                            pattern: ^ord_[A-Za-z0-9]{8,32}$
                            type: string
                          object:
                            enum:
                              - order
                            type: string
                        required:
                          - object
                          - id
                        type: object
                      status:
                        enum:
                          - open
                          - completed
                          - expired
                          - cancelled
                        type: string
                      success_url:
                        nullable: true
                        type: string
                      totals:
                        additionalProperties: false
                        properties:
                          currency:
                            type: string
                          discount_minor_units:
                            type: integer
                          shipping_minor_units:
                            type: integer
                          subtotal_minor_units:
                            type: integer
                          tax_minor_units:
                            type: integer
                          total_minor_units:
                            type: integer
                        type: object
                    required:
                      - object
                      - id
                      - status
                      - created_at
                      - expires_at
                      - success_url
                      - cancel_url
                      - external_reference
                      - metadata
                      - buyer_email_locked
                      - totals
                      - order
                    type: object
                required:
                  - data
                type: object
          description: Successful response
        '400':
          content:
            application/problem+json:
              examples:
                invalid_request:
                  summary: Invalid request
                  value:
                    code: invalid_request
                    detail: null
                    errors:
                      - code: unsupported
                        detail: funnel_id is not supported by this public endpoint
                        param: funnel_id
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 400
                    title: Invalid Request
                    type: https://docs.cope.com/errors/invalid_request
                unparsable_request:
                  summary: Unparsable request
                  value:
                    code: invalid_request
                    detail: >-
                      The request could not be parsed. Check the query string
                      and the request body.
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 400
                    title: Invalid Request
                    type: https://docs.cope.com/errors/invalid_request
                invalid_idempotency_key:
                  summary: Malformed Idempotency-Key header
                  value:
                    code: invalid_idempotency_key
                    detail: >-
                      Idempotency-Key header must be at most 255 characters of
                      valid UTF-8 without a NUL byte
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 400
                    title: Invalid Idempotency Key
                    type: https://docs.cope.com/errors/invalid_idempotency_key
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: Invalid request
        '401':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: Missing or invalid bearer token
        '403':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: Bearer token is not authorized for this route
        '404':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: Resource not found
        '409':
          content:
            application/problem+json:
              examples:
                idempotency_conflict_in_flight:
                  summary: A request with this key is still processing
                  value:
                    code: idempotency_conflict
                    detail: >-
                      A request with this idempotency key is currently being
                      processed
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 409
                    title: Idempotency Conflict
                    type: https://docs.cope.com/errors/idempotency_conflict
                idempotency_conflict_body_mismatch:
                  summary: The key was reused with a different body
                  value:
                    code: idempotency_conflict
                    detail: >-
                      Request body does not match the original request for this
                      idempotency key
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 409
                    title: Idempotency Conflict
                    type: https://docs.cope.com/errors/idempotency_conflict
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: >-
            The idempotency key cannot be honoured: either the first request
            carrying it is still processing, or it was reused with a different
            body. Retry the first case unchanged to collect the original
            response; the second needs the original body, or a new key for a
            genuinely new request.
        '422':
          content:
            application/problem+json:
              examples:
                checkout_validation_error:
                  summary: A line names a product the business does not have
                  value:
                    code: not_found
                    detail: null
                    errors:
                      - code: not_found
                        detail: Product not found
                        param: lines.1.product_id
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 422
                    title: Not Found
                    type: https://docs.cope.com/errors/not_found
                checkout_reserved_metadata_key:
                  summary: A key COPE reserves sent inside metadata
                  value:
                    code: reserved_metadata_key
                    detail: null
                    errors:
                      - code: reserved_metadata_key
                        detail: metadata.clerk_user_id is reserved by COPE
                        param: metadata.clerk_user_id
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 422
                    title: Reserved Metadata Key
                    type: https://docs.cope.com/errors/reserved_metadata_key
                checkout_invalid_redirect_url:
                  summary: success_url is not a registered redirect URL
                  value:
                    code: invalid_redirect_url
                    detail: null
                    errors:
                      - code: invalid_redirect_url
                        detail: >-
                          success_url is not a registered redirect URL. Register
                          it at Settings → API → Redirect URLs.
                        param: checkout.success_url
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 422
                    title: Invalid Redirect Url
                    type: https://docs.cope.com/errors/invalid_redirect_url
                offer_embed_origin_not_allowed:
                  summary: >-
                    embed_origin is not a registered, enabled origin for this
                    seller
                  value:
                    code: embed_origin_not_allowed
                    detail: >-
                      embed_origin is not a registered, enabled embed domain for
                      this seller. Register it first, then create the offer.
                    errors:
                      - code: embed_origin_not_allowed
                        detail: >-
                          embed_origin is not a registered, enabled embed domain
                          for this seller. Register it first, then create the
                          offer.
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 422
                    title: Embed Origin Not Allowed
                    type: https://docs.cope.com/errors/embed_origin_not_allowed
                tax_address_invalid:
                  summary: Tax address invalid
                  value:
                    code: tax_address_invalid
                    detail: >-
                      We couldn't calculate tax for this address. Please check
                      it and try again.
                    errors:
                      - code: tax_address_invalid
                        detail: >-
                          We couldn't calculate tax for this address. Please
                          check it and try again.
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 422
                    title: Tax Address Invalid
                    type: https://docs.cope.com/errors/tax_address_invalid
                tax_request_rejected:
                  summary: Tax request rejected
                  value:
                    code: tax_request_rejected
                    detail: >-
                      We couldn't calculate tax for this order. Please review
                      the billing details, or contact support if the problem
                      continues.
                    errors:
                      - code: tax_request_rejected
                        detail: >-
                          We couldn't calculate tax for this order. Please
                          review the billing details, or contact support if the
                          problem continues.
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 422
                    title: Tax Request Rejected
                    type: https://docs.cope.com/errors/tax_request_rejected
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: >-
            Public commerce validation problem. The code says why, and the set
            is open: treat a code you do not know as a refusal to show. It
            includes `validation_error` (a member is invalid; `errors[].param`
            names it, with a line's index when the refusal is about one line,
            e.g. `lines.1.product_id`, and is absent when the refusal is about
            the whole cart), `validation_failed` (metadata or
            `external_reference` over its limits), `not_found` (a line names a
            product or plan the business does not have), `not_saleable` (with
            `block_reason`, also for a plan that cannot be sold),
            `product_unavailable` and `insufficient_stock`, `mixed_seller_cart`
            and `mixed_vat_mode_cart`, `unsupported_checkout_locale` and
            `checkout_locale_not_allowed`, `invalid_redirect_url`,
            `reserved_metadata_key`, `embed_origin_not_allowed`,
            `tax_address_invalid`, `tax_request_rejected`, and a total outside
            the charge bounds (`below_minimum_charge`, `above_maximum_charge`).
            Nothing was created.
        '500':
          content:
            application/problem+json:
              examples:
                tax_calculation_failed:
                  summary: Tax could not be calculated
                  value:
                    code: tax_calculation_failed
                    detail: Tax could not be calculated for this order.
                    errors:
                      - code: tax_calculation_failed
                        detail: Tax could not be calculated for this order.
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 500
                    title: Tax Calculation Failed
                    type: https://docs.cope.com/errors/tax_calculation_failed
                checkout_internal_error:
                  summary: An internal defect; quote request_id to support
                  value:
                    code: internal_error
                    detail: >-
                      The checkout could not be created. Quote request_id to
                      COPE support.
                    errors:
                      - code: internal_error
                        detail: >-
                          The checkout could not be created. Quote request_id to
                          COPE support.
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 500
                    title: Internal Error
                    type: https://docs.cope.com/errors/internal_error
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: >-
            The checkout could not be created because of a defect on COPE's
            side: tax could not be calculated (`tax_calculation_failed`), or
            another internal error (`internal_error`). Nothing was created, and
            the request is not stored for replay. Quote `request_id` to COPE
            support.
        '503':
          content:
            application/problem+json:
              examples:
                tax_service_unavailable:
                  summary: Tax service unavailable
                  value:
                    code: tax_service_unavailable
                    detail: Tax calculation is temporarily unavailable
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 503
                    title: Tax Service Unavailable
                    type: https://docs.cope.com/errors/tax_service_unavailable
                charge_amount_unavailable:
                  summary: The checkout total could not be resolved
                  value:
                    code: charge_amount_unavailable
                    detail: The checkout total could not be resolved. Retry shortly.
                    errors:
                      - code: charge_amount_unavailable
                        detail: >-
                          The checkout total could not be resolved. Retry
                          shortly.
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 503
                    title: Charge Amount Unavailable
                    type: https://docs.cope.com/errors/charge_amount_unavailable
                user_not_ready:
                  summary: The key's user is not available yet
                  value:
                    code: user_not_ready
                    detail: Retry after 2 seconds
                    errors:
                      - code: user_not_ready
                        detail: Retry after 2 seconds
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 503
                    title: User Not Ready
                    type: https://docs.cope.com/errors/user_not_ready
                tenant_not_ready:
                  summary: The key's business is not available yet
                  value:
                    code: tenant_not_ready
                    detail: Retry after 2 seconds
                    errors:
                      - code: tenant_not_ready
                        detail: Retry after 2 seconds
                    request_id: 0b6e3f2a-8c4d-4f1e-9a7b-5d2c8e1f4a90
                    status: 503
                    title: Tenant Not Ready
                    type: https://docs.cope.com/errors/tenant_not_ready
              schema:
                $ref: '#/components/schemas/PublicProblemDetail'
          description: >-
            Temporarily unavailable, nothing was created: tax could not be
            calculated now (`tax_service_unavailable`), or the checkout total
            could not be resolved (`charge_amount_unavailable`). Retry with the
            same Idempotency-Key. Or: The API key is valid but its user or
            business is not available to this API yet (`user_not_ready`,
            `tenant_not_ready`). Retry after the `Retry-After` seconds.
      security:
        - cope_sk: []
components:
  schemas:
    CommerceMerchantMetadata:
      additionalProperties: true
      description: >-
        Key-value data of your own. Values may be strings, numbers, booleans,
        null, arrays and objects.
      maxProperties: 50
      type: object
    PublicProblemDetail:
      additionalProperties: false
      properties:
        code:
          type: string
        detail:
          nullable: true
          type: string
        errors:
          items:
            additionalProperties: false
            properties:
              code:
                type: string
              detail:
                type: string
              param:
                type: string
            required:
              - code
              - detail
            type: object
          type: array
        request_id:
          description: >-
            Correlates this response with COPE's logs; the response also carries
            it as `X-Request-Id`. It is the `X-Request-Id` you sent when that is
            1-128 letters, digits, `_`, `@` or `-`, and otherwise one COPE
            generated. Quote it when you contact support.
          type: string
        status:
          type: integer
        title:
          type: string
        type:
          type: string
      required:
        - type
        - title
        - status
        - code
        - request_id
      type: object
  securitySchemes:
    cope_sk:
      description: >-
        Bearer credential for the public API: a live COPE API key (`ck_live_*`;
        keys issued earlier as `cope_sk_live_*` keep working). Dashboard sign-in
        tokens are not accepted.
      scheme: bearer
      type: http

````

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