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

# Release Hold

> Releases a payment that is currently `HELD`, returning the held funds to the cardholder. The endpoint takes no request body. A successful release leaves the payment `HOLD_RELEASED` with `holdReleasedAt` set. A hold that is never captured or released is released automatically by a sweep that runs twice each night, at 23:00 and again at 23:15 America/Mexico_City, at the end of the 7th natural day counting from the day it was placed, and ends up as `HOLD_EXPIRED`. The 23:15 run is a catch-up in case the 23:00 run is slow or fails, it lands before the bank closes its day at 23:30, and it is a no-op when the first run already succeeded. It does not extend the capture window: capture is still refused from 23:00 on the last day. Unlike capture, release has NO time cutoff: releasing a hold after 23:00 on its last day, or after its window closed, still works. The hold window is counted in NATURAL DAYS, not in elapsed hours. The day the hold is placed counts as day 1 and the time of day it was placed is irrelevant: a hold placed Monday 10:00 and one placed Monday 23:29 both expire at the same instant, at the end of the following Sunday. The bank closes its day at 23:30 America/Mexico_City and Compago closes the hold at 23:00, 30 minutes earlier, so the last minute to capture is 22:59 on the last day.



## OpenAPI

````yaml POST /payment-method/{id}/payment/{paymentId}/release
openapi: 3.1.0
info:
  title: Compago API
  version: 1.0.0
  description: >-
    Public and private API endpoints for Compago's payment infrastructure. This
    specification currently includes endpoints for one-time payments. More
    endpoints will be added as the platform evolves.
servers:
  - url: https://demo-api-harmony.compago.com/api
  - url: https://api-harmony.compago.com/api
security: []
tags:
  - name: OneTimePayment
    description: Endpoints for creating and processing one-time payment links
  - name: PaymentMethod
    description: >-
      Endpoints for saving cards, charging saved payment methods, holding and
      capturing funds, and processing refunds
  - name: PaymentIntent
    description: >-
      Endpoints for creating and managing card-present payment intents for POS
      terminal integrations
  - name: Payments
    description: Read the payments your organization has taken
  - name: Subscriptions
    description: Read and manage recurring billing agreements
  - name: PaymentLinks
    description: Create, edit and retire hosted checkout links
  - name: Products
    description: Manage the catalogue behind product-based payment links
  - name: Promotions
    description: Read the promotions your organization funds or benefits from
  - name: Salespeople
    description: Read the point-of-sale operators in your organization
  - name: Organization
    description: Read your organization profile and its members
  - name: SavedCards
    description: Read saved payment methods and their payments
paths:
  /payment-method/{id}/payment/{paymentId}/release:
    post:
      tags:
        - PaymentMethod
      summary: Release a held payment
      description: >-
        Releases a payment that is currently `HELD`, returning the held funds to
        the cardholder. The endpoint takes no request body. A successful release
        leaves the payment `HOLD_RELEASED` with `holdReleasedAt` set. A hold
        that is never captured or released is released automatically by a sweep
        that runs twice each night, at 23:00 and again at 23:15
        America/Mexico_City, at the end of the 7th natural day counting from the
        day it was placed, and ends up as `HOLD_EXPIRED`. The 23:15 run is a
        catch-up in case the 23:00 run is slow or fails, it lands before the
        bank closes its day at 23:30, and it is a no-op when the first run
        already succeeded. It does not extend the capture window: capture is
        still refused from 23:00 on the last day. Unlike capture, release has NO
        time cutoff: releasing a hold after 23:00 on its last day, or after its
        window closed, still works. The hold window is counted in NATURAL DAYS,
        not in elapsed hours. The day the hold is placed counts as day 1 and the
        time of day it was placed is irrelevant: a hold placed Monday 10:00 and
        one placed Monday 23:29 both expire at the same instant, at the end of
        the following Sunday. The bank closes its day at 23:30
        America/Mexico_City and Compago closes the hold at 23:00, 30 minutes
        earlier, so the last minute to capture is 22:59 on the last day.
      operationId: releaseHoldPaymentMethodPayment
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The unique identifier of the payment method
        - name: paymentId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          description: The unique identifier of the held payment to release
      responses:
        '200':
          description: Hold released successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReleaseHoldPaymentResponse'
        '400':
          description: >-
            The payment does not belong to this payment method, or is not a
            payment method charge
        '401':
          description: Unauthorized – missing or invalid API key
        '404':
          description: Payment method or payment not found
        '409':
          description: >-
            `PAYMENT_NOT_HELD`: the payment is not in the `HELD` status. This
            covers a release of an already released or expired hold, and a
            release of an ordinary charge.
        '502':
          description: >-
            `RELEASE_FAILED`: the bank leg of the release did not go through.
            The payment stays `HELD`, and the automatic expiry sweep retries it.
      security:
        - ApiKeyAuth: []
components:
  schemas:
    ReleaseHoldPaymentResponse:
      type: object
      description: Response after releasing a held payment
      properties:
        id:
          type: string
          format: uuid
          example: 11111111-2222-3333-4444-555555555555
          description: Unique identifier of the payment
        status:
          type: string
          enum:
            - HOLD_RELEASED
          example: HOLD_RELEASED
          description: >-
            Payment status after a successful release. A hold released by the
            automatic nightly expiry sweep (23:00 and again at 23:15
            America/Mexico_City) instead of by this endpoint ends up as
            HOLD_EXPIRED.
        amount:
          type: number
          format: decimal
          description: The released amount
        heldAmount:
          type:
            - number
            - 'null'
          format: decimal
          example: 3500
          description: >-
            What the bank authorized when the hold was placed. On a released
            hold nothing was ever captured, so it equals `amount`.
        currency:
          type: string
          example: MXN
        externalId:
          type:
            - string
            - 'null'
          example: invoice-2025-01-8842
          description: >-
            The idempotency key supplied when the payment was created, echoed
            back so you can map this payment id to your own order reference.
            Null when none was supplied. Not to be confused with the payment
            method externalId, which identifies the saved card.
        heldAt:
          type:
            - string
            - 'null'
          format: date-time
          example: '2026-08-12T10:00:00.000Z'
          description: When the bank approved the hold
        capturedAt:
          type:
            - string
            - 'null'
          format: date-time
          description: 'Null on a released hold: nothing was ever captured.'
        holdReleasedAt:
          type:
            - string
            - 'null'
          format: date-time
          example: '2026-08-14T09:30:00.000Z'
          description: When the hold was released
        holdExpiresAt:
          type:
            - string
            - 'null'
          format: date-time
          example: '2026-08-19T05:00:00.000Z'
          description: >-
            When the hold would have expired: 23:00 America/Mexico_City on the
            7th natural day, counting the day of heldAt as day 1. The hold
            window is counted in NATURAL DAYS, not in elapsed hours. The day the
            hold is placed counts as day 1 and the time of day it was placed is
            irrelevant: a hold placed Monday 10:00 and one placed Monday 23:29
            both expire at the same instant, at the end of the following Sunday.
            The bank closes its day at 23:30 America/Mexico_City and Compago
            closes the hold at 23:00, 30 minutes earlier, so the last minute to
            capture is 22:59 on the last day. It keeps being reported after the
            release, because it is a fact about the payment.
        holdExpired:
          type: boolean
          description: >-
            Whether the hold window has closed. It flips at 23:00
            America/Mexico_City on the last natural day, not 7 times 24 hours
            after heldAt.
        holdDaysRemaining:
          type:
            - integer
            - 'null'
          description: >-
            Null once the hold is released: it is only reported while the
            payment is HELD.
      required:
        - id
        - status
        - amount
        - currency
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key

````