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

# Create a payment link

> Add a price and a shareable payment link to an existing product.

Authenticate with an API key that belongs to the product's organization and has Full access or the `products:payment_links:write` permission (**Payment links** under **Can create and change** in the dashboard). Only the Owner and Admin roles can grant it.

* `id` is the ID of a product in your organization, whether it was created through the API or in the dashboard. A product from another organization, or one that doesn't exist, returns `404`.
* Each call creates a new price for the product and its payment link, so one product can have several prices.
* Send a unique `Idempotency-Key` header (required; 1–255 ASCII characters from `0x21` to `0x7E`, no spaces), the same rule as checkout sessions. The same key with the same body returns the link created the first time (`201`) and creates nothing new. The same key with a different body, or for another product, returns `409`. If the link created with that key was later removed, a retry also returns `409`; send a new key.
* `pricingType` is `ONE_TIME` or `SUBSCRIPTION`. `pricing` is a string in major units, such as `"9.99"`. Omit `pricing` for a flexible "pay what you want" amount; this works for `ONE_TIME` only, and `minAmount` and `maxAmount` are then optional.
* A `SUBSCRIPTION` price needs `billingInterval` (`DAY`, `MONTH` or `YEAR`). `billingIntervalCount` is optional and defaults to `1`.
* `successUrl` is an absolute HTTPS URL to send the customer to after they pay. If you leave it out, the customer sees the Anyway receipt.
* Payments are collected on Anyway's platform account. Links created through the API are card payment links only; crypto payment links are not available.
* Unknown fields are rejected with `400`.
* Share the returned `paymentLinkUrl` as provided. The response has the same shape as an item from [Get product payment links](https://docs.anyway.sh/api-reference/endpoint/get-product-payment-links.md).

> [!NOTE]
>
> Checkout sessions can't sell a flexible amount. To let the customer choose what to pay, create a flexible one-time payment link here instead.

| Status | Code | Meaning |
| - | - | - |
| `400` | | Validation failed: bad currency, a subscription without an interval, a flexible subscription, an amount of 0 or less, a `successUrl` that isn't an absolute HTTPS URL, an unknown field, or a missing or invalid `Idempotency-Key`. |
| `401` | | The API key is missing or invalid. |
| `403` | `INSUFFICIENT_SCOPE` | The key lacks `products:payment_links:write`. |
| `403` | `ORG_FROZEN` | The organization's payments are frozen. |
| `403` | `CARD_USD_VERIFICATION_REQUIRED` | Business verification must be completed before creating USD card payment links. |
| `404` | | The product doesn't exist or belongs to another organization. |
| `409` | `PRODUCT_CONFLICT` | The `Idempotency-Key` was already used with a different body or another product, or the link it created was removed. |
| `413` | `PAYLOAD_TOO_LARGE` | The request body is larger than 64 KB. |
| `503` | `CARD_USD_CAPABILITY_UNAVAILABLE` | Business verification status is temporarily unavailable. Try again later. |


## OpenAPI

````yaml api-reference/openapi.json POST /v1/product/{id}/payment-link
openapi: 3.0.3
info:
  description: >-
    Organization-scoped commerce API for merchant backends: create and manage
    checkout sessions, and query commerce records.
  title: Anyway Merchant API
  contact: {}
  version: '1.0'
  x-source: anyway-backend-go
servers:
  - url: https://merchant-api-prod.anyway.sh
security: []
paths:
  /v1/product/{id}/payment-link:
    post:
      tags:
        - products
      summary: Create a payment link
      description: >-
        Creates a new price for an existing product and its card payment link.
        Requires Full access or the `products:payment_links:write` permission.
        The product can be created by API or in the dashboard. Send a unique
        `Idempotency-Key` (required): the same key with the same body returns
        the link created the first time (201); the same key with a different
        body or product, or a link removed since, returns 409 PRODUCT_CONFLICT.
        Unknown request fields return 400. Crypto payment links are not
        available through the API. Checkout sessions can't sell flexible
        amounts; a flexible one-time payment link can.
      parameters:
        - description: Product ID
          name: id
          in: path
          required: true
          schema:
            type: string
        - description: >-
            Unique creation request key: 1-255 ASCII characters in the range
            0x21-0x7E (no spaces or control characters)
          name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 1
            maxLength: 255
      requestBody:
        required: true
        description: Price and payment link
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/product.CreatePaymentLinkRequest'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/response.ApiResponse-product_PaymentLinkResponse
        '400':
          description: >-
            Bad Request. Invalid currency, a subscription without a billing
            interval, a flexible subscription, an amount of 0 or less, a
            successUrl that is not an absolute HTTPS URL, an unknown field, or
            an invalid Idempotency-Key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response.ApiResponse-any'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response.ApiResponse-any'
        '403':
          description: >-
            Forbidden. The API key lacks the required permission
            (INSUFFICIENT_SCOPE), or the organization is frozen.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response.ApiResponse-any'
        '404':
          description: >-
            Not Found. The product does not exist or belongs to another
            organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response.ApiResponse-any'
        '409':
          description: >-
            Conflict. The Idempotency-Key was already used with a different body
            (PRODUCT_CONFLICT).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response.ApiResponse-any'
        '413':
          description: Request body larger than 64 KB (`PAYLOAD_TOO_LARGE`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/response.ApiResponse-any'
      security:
        - APIKeyAuth: []
components:
  schemas:
    product.CreatePaymentLinkRequest:
      type: object
      required:
        - pricingType
        - currency
      properties:
        pricingType:
          $ref: '#/components/schemas/product.PricingType'
        currency:
          type: string
          description: Currency code, for example USD
        pricing:
          type: string
          description: >-
            Fixed amount in major units, for example "9.99". Omit for a flexible
            (pay what you want) amount, which is ONE_TIME only.
        minAmount:
          description: Optional minimum for a flexible amount (ONE_TIME only)
          type: number
        maxAmount:
          description: Optional maximum for a flexible amount (ONE_TIME only)
          type: number
        billingInterval:
          $ref: '#/components/schemas/product.BillingInterval'
        billingIntervalCount:
          type: integer
          description: Number of intervals between charges (SUBSCRIPTION). Defaults to 1.
        pricingName:
          type: string
          description: Name of the price
        successUrl:
          type: string
          description: >-
            Absolute HTTPS URL to send the customer to after paying. Defaults to
            the Anyway receipt.
    response.ApiResponse-product_PaymentLinkResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/product.PaymentLinkResponse'
        error:
          $ref: '#/components/schemas/response.ErrorDetail'
        message:
          type: string
        success:
          type: boolean
    response.ApiResponse-any:
      type: object
      properties:
        data: {}
        error:
          $ref: '#/components/schemas/response.ErrorDetail'
        message:
          type: string
        success:
          type: boolean
    product.PricingType:
      type: string
      enum:
        - SUBSCRIPTION
        - ONE_TIME
      x-enum-varnames:
        - PricingTypeSubscription
        - PricingTypeOneTime
    product.BillingInterval:
      type: string
      enum:
        - DAY
        - MONTH
        - YEAR
      x-enum-varnames:
        - BillingIntervalDay
        - BillingIntervalMonth
        - BillingIntervalYear
    product.PaymentLinkResponse:
      type: object
      properties:
        amount:
          type: number
          nullable: true
        createdAt:
          type: string
        currency:
          type: string
        flexibleAmount:
          type: boolean
        isActive:
          type: boolean
        name:
          type: string
        paymentLinkUrl:
          type: string
        pricingId:
          type: string
        pricingType:
          type: string
        provider:
          type: string
        title:
          type: string
        description:
          type: string
        minAmount:
          type: number
          nullable: true
        maxAmount:
          type: number
          nullable: true
        successUrl:
          type: string
          description: >-
            Where the customer is sent after paying. Empty when the Anyway
            receipt is used.
    response.ErrorDetail:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
  securitySchemes:
    APIKeyAuth:
      description: 'Merchant API key (format: ak_BASE64)'
      type: apiKey
      name: X-API-Key
      in: header

````

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