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

# Create a payment

> Creates a payment from one of the entity's internal accounts to one of its external accounts. An `Idempotency-Key` header is required so the request is safe to retry.




## OpenAPI

````yaml /openapi.json post /payments
openapi: 3.0.3
info:
  title: Melio Payouts API
  version: '1.0'
  description: >
    Self-serve payouts API. Partners onboard an Entity, which is the business

    (organization plus owner, with the details required to be payment-eligible),

    then attach accounts (internal accounts and external accounts) and make

    payments.


    ## Resource ids


    Every resource has an opaque, prefixed id that is stable for the life of the
    resource:

    `ent_` (entity), `pay_` (payment), `acct_` (account, internal or external).

    Ids are Melio-issued; treat them as opaque strings and never parse or
    construct them. To

    attach your own identifier to a resource, use `externalId`.


    ## Pagination


    List endpoints are cursor-paginated and always return results newest-first

    (`createdAt` descending). The response envelope is:


    ```json

    { "data": [ /* resources */ ], "hasMore": true }

    ```


    Page through results with `limit` (1 to 50, default 50) plus a cursor:


    - `startingAfter=<id>`: return the page immediately **after** the given
    resource id
      (the next, older page). This is how you walk forward through a list.
    - `endingBefore=<id>`: return the page immediately **before** the given
    resource id
      (the previous, newer page).

    `startingAfter` and `endingBefore` are mutually exclusive. The cursor is a
    resource id

    you already received (e.g. the `id` of the last item on the current page),
    not an index.

    Keep requesting the next page until `hasMore` is `false`.


    ## Filtering & sorting


    Ordering is fixed (newest-first); there is no `sortBy`. To narrow a list,
    filter it.

    Each list endpoint documents its own filter parameters (there is no generic
    query

    language). Date-range filters use bracket suffixes and accept RFC 3339
    timestamps:

    `created[gte]`, `created[lte]`. Filter by your own identifier with
    `externalId`, and

    by metadata with `metadata[<key>]=<value>` (matches resources whose metadata
    contains

    every supplied key/value pair). Filters combine with AND and compose with
    pagination.


    ## External ids


    Every created resource accepts an optional `externalId`, your own unique
    identifier for

    the resource (≤255 chars, letters/digits/`-`/`_`). It is unique per partner
    per resource

    type: reusing one returns `409 DUPLICATE_EXTERNAL_ID`. Use it to correlate
    Melio resources

    with records in your system and to look resources up (`?externalId=`)
    without storing

    Melio ids. `externalId` identifies a *resource*; it is not a
    request-deduplication key

    (that is the `Idempotency-Key` header, below); the two are complementary.


    ## Idempotency


    Send an `Idempotency-Key` header on every create so retries are safe: the
    original response

    is replayed instead of creating a second resource. It is required on `POST
    /payments`.


    ## Metadata


    Most resources accept a `metadata` object: free-form string key/value pairs
    that Melio

    stores and returns verbatim but never interprets. Limits: up to 50 keys, key
    ≤40 chars,

    value ≤100 chars. Use it to stash your own structured context on a resource;
    it is also

    filterable (see above).


    ## Melio Sonar Session Token


    Write endpoints optionally accept a `Melio-Sonar-Token` header: a signed
    session token

    minted by the MelioSonar SDK on the end user's device, carrying device
    signals used for

    risk evaluation. Omit it when no SDK session is available.
  contact:
    name: Melio Platform External API
    email: platform@melio.com
servers:
  - description: Production
    url: https://api.melio.com/v2
  - description: Staging01
    url: https://api.staging01.melio.com/v2
security: []
tags:
  - name: Entities
    description: >-
      A business you onboard and operate on behalf of: its profile, compliance
      details, and per-operation limitations.
  - name: Accounts
    description: Accounts the entity pays from (internal) and payees it pays to (external).
  - name: Payments
    description: >-
      Money moved from an internal account to an external account, and their
      lifecycle.
  - name: Tools
    description: >-
      Pre-flight calculators for fees, fast-payment eligibility, and delivery
      estimates. No resource is created.
  - name: Webhooks
    description: >-
      Your single endpoint for event notifications, and the events you can
      subscribe to.
paths:
  /payments:
    parameters:
      - $ref: '#/components/parameters/MelioEntityId'
    post:
      tags:
        - Payments
      summary: Create a payment
      description: >
        Creates a payment from one of the entity's internal accounts to one of
        its external accounts. An `Idempotency-Key` header is required so the
        request is safe to retry.
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          description: >
            Required unique key (UUID recommended) that makes payment creation
            safe to retry by replaying the original response; retained 24h per
            partner, omitting it returns 400.
          schema:
            type: string
            maxLength: 255
        - $ref: '#/components/parameters/MelioSonarToken'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePaymentRequest'
            example:
              amount: 125000
              currency: USD
              originatingAccountId: acct_3f2504e0-4f89-41d3-9a0c-0305e82c3301
              receivingAccountId: acct_9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
              deductionDate: '2026-07-10'
              deliveryPreference: standard-ach
              compliance:
                type: goods-and-services
              externalId: invoice-2043
              noteToRecipient: July materials order
              metadata:
                invoiceId: INV-2043
                department: operations
      responses:
        '201':
          description: Payment created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
              example:
                id: pay_9f8c7b6a5d4e3f21
                externalId: invoice-2043
                amount: 125000
                currency: USD
                originatingAccountId: acct_3f2504e0-4f89-41d3-9a0c-0305e82c3301
                receivingAccountId: acct_9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d
                deductionDate: '2026-07-10'
                deliveryDate: '2026-07-14'
                status: scheduled
                noteToRecipient: July materials order
                metadata:
                  invoiceId: INV-2043
                  department: operations
                createdAt: '2026-07-08T15:04:05Z'
                updatedAt: '2026-07-08T15:04:05Z'
        '400':
          description: >
            Validation error, or the required `Idempotency-Key` header is
            missing (IDEMPOTENCY_KEY_REQUIRED).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: >
            The business is restricted by a risk/compliance limitation from
            making payments (BUSINESS_NOT_ELIGIBLE).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: authorization_error
                  code: BUSINESS_NOT_ELIGIBLE
                  message: >-
                    Business is not eligible to make payments. See the
                    limitations endpoint for details.
        '404':
          description: Entity / internal account / external account not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >
            A payment already exists for this request (DUPLICATE_PAYMENT), the
            `externalId` is already used by another payment
            (DUPLICATE_EXTERNAL_ID), or the `Idempotency-Key` was reused with a
            different body (IDEMPOTENCY_KEY_REUSED) / is still being processed
            by an earlier request (IDEMPOTENCY_KEY_IN_PROGRESS).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  type: conflict_error
                  code: DUPLICATE_EXTERNAL_ID
                  message: A payment with externalId 'invoice-2043' already exists.
      security:
        - ApiKey: []
components:
  parameters:
    MelioEntityId:
      name: Melio-Entity-Id
      in: header
      required: true
      description: >-
        Entity the request operates on — an entity id (`ent_<uuid>`) or `me`
        (the partner's sole entity).
      schema:
        type: string
    MelioSonarToken:
      name: Melio-Sonar-Token
      in: header
      required: false
      description: >
        Signed MelioSonar session token from the initiating device, used for
        risk evaluation; invalid or expired tokens return 403.
      schema:
        type: string
  schemas:
    CreatePaymentRequest:
      type: object
      required:
        - amount
        - originatingAccountId
        - receivingAccountId
        - deductionDate
        - deliveryPreference
        - compliance
      properties:
        amount:
          type: integer
          description: Minor units (cents)
        currency:
          type: string
          default: USD
        originatingAccountId:
          type: string
          description: Internal originating account id (acct_<id>), the debit account
        receivingAccountId:
          type: string
          description: External receiving account id (acct_<id>), the credit account
        deductionDate:
          type: string
          format: date
        deliveryPreference:
          type: string
          enum:
            - standard-ach
            - same-day-ach
            - rtp
            - standard-check
            - express-check
            - overnight-check
            - domestic-wire
            - instant-domestic-wire
            - virtual-card
            - instant-virtual-card
          description: >
            Required, and explicit about the receiving rail. Pick the
            normal-speed value that matches the receiving external account
            (`standard-ach`, `standard-check`, `domestic-wire`, `virtual-card`).
            The faster variants, `same-day-ach` / `rtp` (ach), `express-check` /
            `overnight-check` (check), `instant-domestic-wire` (domestic-wire),
            and `instant-virtual-card` (virtual-card), require an ACH
            originating account and pass a per-payment eligibility check. The
            preference's rail must match the receiving external account,
            otherwise the request is rejected with `400`; a faster variant that
            is ineligible for the payment is likewise rejected with `400` (never
            silently downgraded).
        noteToSelf:
          type: string
          description: Payer-private memo, never shown to the recipient
        noteToRecipient:
          type: string
          description: Note shown to the payment recipient
        compliance:
          $ref: '#/components/schemas/PaymentCompliance'
        externalId:
          $ref: '#/components/schemas/ExternalId'
        metadata:
          $ref: '#/components/schemas/Metadata'
    Payment:
      type: object
      required:
        - fees
      properties:
        id:
          type: string
          description: Opaque payment id (pay_<id>)
        externalId:
          $ref: '#/components/schemas/ExternalId'
        amount:
          type: integer
        currency:
          type: string
        originatingAccountId:
          type: string
          description: Internal originating account id (acct_<id>)
        receivingAccountId:
          type: string
          description: External receiving account id (acct_<id>)
        deductionDate:
          type: string
          format: date
        deliveryPreference:
          type: string
          enum:
            - standard-ach
            - same-day-ach
            - rtp
            - standard-check
            - express-check
            - overnight-check
            - domestic-wire
            - instant-domestic-wire
            - virtual-card
            - instant-virtual-card
          description: >
            Effective delivery preference. Reflects the faster variant when one
            was applied, otherwise the receiving rail's normal-speed value.
        deliveryDate:
          type: string
          format: date
        status:
          type: string
          enum:
            - scheduled
            - in-progress
            - completed
            - failed
            - canceled
          description: >
            While a payment is being reviewed it is reported as `scheduled`;
            there is no separate review status.
        noteToSelf:
          type: string
          description: Payer-private memo, never shown to the recipient
        noteToRecipient:
          type: string
          description: Note shown to the payment recipient
        metadata:
          $ref: '#/components/schemas/Metadata'
        fees:
          type: array
          description: >
            The fees charged for this payment, as recorded by the fees service.
            Includes both the originator-side and receiver-side fees; use
            `chargeTo` on each item to tell them apart. Always present — an
            empty array when no fees have been recorded yet (e.g. a freshly
            created payment).
          items:
            $ref: '#/components/schemas/PaymentFee'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    ErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          $ref: '#/components/schemas/Error'
    PaymentCompliance:
      description: >
        Compliance details, discriminated by `type`. Only `goods-and-services`
        is supported today; future payment types (internal money movement, mass
        payouts) will add their own variants with different fields.
      oneOf:
        - $ref: '#/components/schemas/GoodsAndServicesCompliance'
      discriminator:
        propertyName: type
        mapping:
          goods-and-services:
            $ref: '#/components/schemas/GoodsAndServicesCompliance'
    ExternalId:
      type: string
      description: >
        Your own unique identifier for the resource. Unique per partner per
        resource type (reusing one returns 409 DUPLICATE_EXTERNAL_ID). Distinct
        from the Idempotency-Key header, which dedupes the request rather than
        identifying the resource.
      maxLength: 255
      pattern: ^[A-Za-z0-9_-]+$
    Metadata:
      type: object
      description: >
        Free-form string key/value pairs stored and returned verbatim, never
        interpreted by Melio. Up to 50 keys; each key 1 to 40 chars and may not
        contain square brackets (`[` `]`, reserved for the `metadata[key]`
        filter); value ≤100 chars. Filterable via `metadata[key]`.
      additionalProperties:
        type: string
        maxLength: 100
      maxProperties: 50
    PaymentFee:
      description: >
        A single fee charged for a payment. Shares the `Fee` shape used by the
        fee calculator (`type`, `chargeTo`, `fixed`/`percent`, `amount`, all
        monetary values in minor units), and adds `status`, which only applies
        once a fee has actually been applied to a payment.
      allOf:
        - $ref: '#/components/schemas/Fee'
        - type: object
          required:
            - status
          properties:
            status:
              type: string
              enum:
                - charged
                - pending
              description: Whether the fee has been charged or is still pending.
    Error:
      type: object
      required:
        - type
        - code
        - message
      properties:
        type:
          type: string
          description: >-
            Coarse, machine-readable error category. Branch on this to handle a
            whole class of failures without enumerating every `code`.
          enum:
            - invalid_request_error
            - authentication_error
            - authorization_error
            - not_found_error
            - conflict_error
            - rate_limit_error
            - service_unavailable_error
            - internal_error
        code:
          type: string
          description: Machine-readable error code.
          enum:
            - VALIDATION_ERROR
            - INVALID_ACCOUNT_TYPE
            - INVALID_DELIVERY_PREFERENCE
            - MCC_REQUIRED
            - GOODS_RECEIVED_REQUIRED
            - IDEMPOTENCY_KEY_REQUIRED
            - FEE_CALCULATION_FAILED
            - UNAUTHORIZED
            - NOT_FOUND
            - NO_ACTIVE_API_KEY
            - DUPLICATE_ENTITY
            - DUPLICATE_ACCOUNT
            - DUPLICATE_PAYMENT
            - DUPLICATE_EXTERNAL_ID
            - ACCOUNT_IN_USE
            - BUSINESS_NOT_ELIGIBLE
            - PAYMENT_NOT_EDITABLE
            - PAYMENT_NOT_CANCELABLE
            - IDEMPOTENCY_KEY_REUSED
            - IDEMPOTENCY_KEY_IN_PROGRESS
            - IDEMPOTENCY_STORE_UNAVAILABLE
            - INTERNAL_ERROR
        message:
          type: string
          description: Human-readable error message.
        details:
          type: object
          description: Additional error context (e.g. field-level validation failures).
    GoodsAndServicesCompliance:
      type: object
      description: Compliance details for a goods-and-services payment.
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - goods-and-services
        goodsReceived:
          type: boolean
          description: >
            The payer confirms the goods or services were received. Required to
            be `true` for payments above $3,000 (amount greater than 300000
            minor units).
        merchantCategoryCode:
          type: string
          description: >
            The counterparty's 4-digit MCC (merchant category code). Required
            when the originating account is a card.
          pattern: ^\d{4}$
    Fee:
      type: object
      description: >-
        A single fee that would apply to the payment. All monetary values are
        minor units (cents).
      required:
        - type
        - chargeTo
      properties:
        type:
          type: string
          description: The fee category (e.g. ach, card, expedited-ach).
        chargeTo:
          type: string
          enum:
            - originator
            - receiver
          description: >
            Which side of the payment the fee is levied on: the account
            originating the payment or the account receiving it. Works for both
            estimated (calculator) and applied (payment) fees.
        fixed:
          type: object
          description: Present when the fee is a flat amount.
          properties:
            value:
              type: integer
              description: Flat fee, minor units (cents)
        percent:
          type: object
          description: Present when the fee is a percentage of the payment amount.
          properties:
            rate:
              type: number
              description: Percentage rate (e.g. 2.9 = 2.9%)
            min:
              type: integer
              description: Minimum fee, minor units (cents)
            max:
              type: integer
              description: Maximum fee, minor units (cents)
        amount:
          type: integer
          description: >
            The resolved fee for the requested payment amount, in minor units
            (cents). Absent only when the fee cannot be resolved without a
            per-payment quote (e.g. tiered pricing).
  securitySchemes:
    ApiKey:
      type: apiKey
      in: header
      name: api-key

````