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

# Execute Recovery

> The core recovery endpoint. When a payment fails in your billing system, call this to trigger the intelligent recovery engine.

**Rate limit:** 60 requests per minute per API key.

### Response Summary

| Status | Meaning |
|--------|---------|
| `200` + `success: true` | Payment recovered immediately |
| `200` + `success: false` | All strategies exhausted, payment not recovered |
| `202` | Queued for smart-time retry |
| `403` | Blocked by risk engine — do NOT retry |
| `409` | Duplicate request (idempotency key already used) |
| `429` | Rate limit exceeded |

### Decline Codes

| Category | Example Codes | What Happens |
|----------|---------------|--------------|
| Recoverable | `insufficient_funds`, `do_not_honor`, `call_issuer`, `try_again_later`, `card_declined` | Optimal recovery strategy applied |
| Authentication required | `authentication_required` | No retry — issuer needs the customer to authenticate. `403` returned, webhook fired |
| Blocked | `fraudulent`, `lost_card`, `pickup_card`, `restricted_card` | Transaction blocked, webhook fired |
| Unknown | Any unrecognised code | Conservative recovery attempted |




## OpenAPI

````yaml /api-reference/openapi.yaml post /api/recovery/execute
openapi: 3.0.3
info:
  title: Revtain API
  description: >
    Recover failed payments. No checkout changes. Works with your existing
    payment stack.


    ## Choose Your Path


    **Using Chargebee, Recurly, Stripe Billing, Braintree, Zuora, or Shopify
    (ReCharge)?**

    Use a Connector — paste one webhook URL, no code, 5 minutes.


    **Custom billing system or want full API control?**

    Use the Recovery Engine directly. The quickstart gets you to a working
    recovery call in 60 seconds.


    ## Authentication


    Pass your API key via the `X-API-KEY` header on all requests:


    ```

    X-API-KEY: rev_dTviCg52T8gLPCjrrW4KA0NKf_f5pQgk

    ```


    Keep this secret. Your API key can trigger charges. Never expose it in
    client-side code, public repos, or logs.


    ## Base URL


    ```

    https://api.revtain.com

    ```


    Same URL for testing and production. Test mode is controlled by your gateway
    type — onboard with a test gateway (e.g., Stripe `sk_test_...`) for sandbox,
    live key for production.
  version: 1.0.0
  contact:
    email: support@revtain.com
servers:
  - url: https://api.revtain.com
    description: Production & Sandbox (test mode controlled by gateway key)
security:
  - ApiKeyAuth: []
tags:
  - name: Recovery Engine
    description: Trigger and track payment recovery attempts
  - name: Predictive Risk Engine
    description: Pre-screen payments before they fail
  - name: Retention
    description: Hosted cancel flow to reduce voluntary churn
  - name: Health
    description: Service health check
paths:
  /api/recovery/execute:
    post:
      tags:
        - Recovery Engine
      summary: Execute Recovery
      description: >
        The core recovery endpoint. When a payment fails in your billing system,
        call this to trigger the intelligent recovery engine.


        **Rate limit:** 60 requests per minute per API key.


        ### Response Summary


        | Status | Meaning |

        |--------|---------|

        | `200` + `success: true` | Payment recovered immediately |

        | `200` + `success: false` | All strategies exhausted, payment not
        recovered |

        | `202` | Queued for smart-time retry |

        | `403` | Blocked by risk engine — do NOT retry |

        | `409` | Duplicate request (idempotency key already used) |

        | `429` | Rate limit exceeded |


        ### Decline Codes


        | Category | Example Codes | What Happens |

        |----------|---------------|--------------|

        | Recoverable | `insufficient_funds`, `do_not_honor`, `call_issuer`,
        `try_again_later`, `card_declined` | Optimal recovery strategy applied |

        | Authentication required | `authentication_required` | No retry —
        issuer needs the customer to authenticate. `403` returned, webhook fired
        |

        | Blocked | `fraudulent`, `lost_card`, `pickup_card`, `restricted_card`
        | Transaction blocked, webhook fired |

        | Unknown | Any unrecognised code | Conservative recovery attempted |
      operationId: executeRecovery
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecuteRecoveryRequest'
            examples:
              basic:
                summary: Basic recovery request
                value:
                  paymentMethodToken: pm_1234567890
                  amount: 5000
                  currency: USD
                  originalDeclineCode: do_not_honor
                  idempotencyKey: order_12345_retry_1
              full:
                summary: Full request with all optional fields
                value:
                  paymentMethodToken: pm_1234567890
                  amount: 5000
                  currency: USD
                  originalDeclineCode: do_not_honor
                  cardOrigin: US
                  idempotencyKey: order_12345_retry_1
                  binPrefix: '411111'
                  customerEmail: customer@example.com
              simulate_success:
                summary: Simulate success (sandbox only)
                value:
                  paymentMethodToken: pm_test_123
                  amount: 5000
                  currency: USD
                  originalDeclineCode: do_not_honor
                  simulateOutcome: success
              simulate_failed:
                summary: Simulate failure (sandbox only)
                value:
                  paymentMethodToken: pm_test_123
                  amount: 5000
                  currency: USD
                  originalDeclineCode: do_not_honor
                  simulateOutcome: failed
              simulate_blocked:
                summary: Simulate block (sandbox only)
                value:
                  paymentMethodToken: pm_test_123
                  amount: 5000
                  currency: USD
                  originalDeclineCode: fraudulent
                  simulateOutcome: blocked
      responses:
        '200':
          description: Recovery attempt completed (check `success` field for outcome)
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ExecuteRecoverySuccess'
                  - $ref: '#/components/schemas/ExecuteRecoveryFailed'
              examples:
                recovered:
                  summary: Payment recovered
                  value:
                    success: true
                    message: Revenue Recovered
                    error: null
                    transactionId: 01KKZ14FEZK152ZBXEM2XK1B0C
                    strategyUsed: primary
                    gatewaysAttempted: 1
                    recoveryEngineApplied: true
                    ai:
                      score: 72.5
                      confidence: 68
                      reasoning: >-
                        Analysed 142 similar "do_not_honor" declines during
                        afternoon hours.
                      dataSource: blended
                failed:
                  summary: Recovery failed
                  value:
                    success: false
                    message: Recovery Failed
                    error: 'Purchase request failed: Card declined'
                    transactionId: FAILED_API_1773792234011
                    strategyUsed: all_failed
                    gatewaysAttempted: 1
                    recoveryEngineApplied: true
                    recommendedAction: retry_later
                    recommendedActionReason: >-
                      The issuer returned a soft decline. A later retry, or a
                      card update, may succeed.
                    ai:
                      score: 35.2
                      confidence: 45
                      reasoning: >-
                        Recovery engine applied optimal strategy for this
                        decline type.
                      dataSource: static
        '202':
          description: >-
            Queued for smart-time retry. You'll receive a webhook when the
            outcome is final.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecuteRecoveryQueued'
              example:
                message: >-
                  Insufficient funds. Queued for Smart-Time Retry at
                  2026-04-04T06:00:00.000Z.
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationError'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedError'
        '403':
          description: Blocked by risk engine — do NOT retry this payment
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecuteRecoveryBlocked'
              example:
                error: >-
                  Transaction blocked by Revtain Risk Engine to protect Merchant
                  Health.
                declineCode: fraudulent
                action: blocked
                recommendedAction: manual_review
                recommendation: >-
                  The issuer flagged this card for fraud. Do not retry — review
                  the account.
        '409':
          description: Duplicate recovery request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExecuteRecoveryDuplicate'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RateLimitError'
components:
  schemas:
    ExecuteRecoveryRequest:
      type: object
      required:
        - paymentMethodToken
        - amount
      properties:
        paymentMethodToken:
          type: string
          description: >
            Your gateway's payment token. Format varies per gateway — see the
            full

            per-gateway token-format table at

            [Supported Gateways](/concepts/supported-gateways).


            Common examples:
              - **Stripe**: `pm_xxx` (PaymentMethod ID) — works for cards, Apple Pay, Google Pay
              - **Checkout.com**: `src_xxx` (saved instrument token)
              - **Adyen**: `<merchantAccount>|<storedPaymentMethodId>|<shopperReference>`
              - **Braintree**: `<paymentMethodToken>|<customerId>`
              - **GoCardless**: `<mandateId>` (MD-xxx)
              - **PayPal**: `billing-agreement|<BA-token>` or `reference|<previous-payment-id>`

            Apple Pay and Google Pay tokens issued by your gateway work the same
            way as card tokens — pass them as the underlying gateway token, and
            set `paymentMethodType` to identify the wallet.
          example: pm_1234567890
        fallbackPaymentMethodTokens:
          type: array
          maxItems: 5
          items:
            type: string
          description: |
            Optional list of alternative payment tokens for the same customer
            (for example, a backup card-on-file when the primary is a wallet).
            When the primary payment method can't be recovered on a recoverable
            decline (insufficient funds, do not honor, gateway timeout, and
            similar), Revtain automatically tries each fallback token in
            order — no orchestration code on your side.

            Tokens that fail with hard cardholder-state declines (lost,
            stolen, fraud, expired) skip the fallback step, because the
            issuer's flag applies to the cardholder rather than the
            individual token.

            Pass the tokens in priority order. Up to 5 supported.
          example:
            - pm_card_backup_5678
            - pm_secondary_card_9012
        amount:
          type: integer
          minimum: 50
          maximum: 100000000
          description: >-
            Amount in the smallest currency unit (e.g., 5000 = $50.00 USD). For
            zero-decimal currencies (JPY, KRW, VND), pass the whole amount.
          example: 5000
        currency:
          type: string
          description: 3-letter ISO 4217 currency code.
          default: USD
          example: USD
        originalDeclineCode:
          type: string
          description: >-
            The decline code from your processor. Dramatically improves recovery
            rate.
          example: do_not_honor
        cardOrigin:
          type: string
          description: >-
            2-letter ISO country code of the card issuer. Enables geographic
            routing optimisation.
          example: US
        idempotencyKey:
          type: string
          maxLength: 128
          description: >-
            Unique key to prevent duplicate recovery attempts. Strongly
            recommended for production.
          example: order_12345_retry_1
        binPrefix:
          type: string
          description: >-
            First 6 digits of the card (BIN). Enables issuer-level analytics and
            smarter routing.
          example: '411111'
        customerEmail:
          type: string
          format: email
          description: >-
            The end customer's email address. Optional but recommended — unlocks
            customer-level intelligence, proactive retention events, and richer
            recovery webhooks.
          example: customer@example.com
        paymentMethodType:
          type: string
          enum:
            - card
            - apple_pay
            - google_pay
            - paypal
            - venmo
          default: card
          description: >
            How the customer originally paid. Lets Revtain apply the right
            recovery

            approach per rail — wallet payments are routed only to processing

            options that support recurring wallet charges.


            Defaults to `card` when omitted. Always pass this if the failed
            payment

            originated via Apple Pay, Google Pay, PayPal, or Venmo — recovery
            rates

            are materially higher when set correctly.
          example: apple_pay
        isTrialConversion:
          type: boolean
          default: false
          description: >
            Set to `true` if this failure occurred on the customer's first paid
            charge

            after a free trial. Trial-conversion failures are prioritised for
            recovery

            (effective priority bumps to `critical`) — losing the customer at
            the

            trial-to-paid moment is the highest-cost churn event a subscription
            business

            faces.
          example: true
        simulateOutcome:
          type: string
          enum:
            - success
            - failed
            - blocked
          description: >-
            **Sandbox only.** Force a specific outcome for testing. Only
            honoured when primary gateway is a Test Gateway.
    ExecuteRecoverySuccess:
      type: object
      properties:
        success:
          type: boolean
          example: true
        message:
          type: string
          example: Revenue Recovered
        error:
          type: string
          nullable: true
          example: null
        transactionId:
          type: string
          example: 01KKZ14FEZK152ZBXEM2XK1B0C
        strategyUsed:
          type: string
          example: primary
        gatewaysAttempted:
          type: integer
          example: 1
        recoveryEngineApplied:
          type: boolean
          example: true
        ai:
          type: object
          properties:
            score:
              type: number
              example: 72.5
            confidence:
              type: integer
              example: 68
            reasoning:
              type: string
              example: >-
                Analysed 142 similar "do_not_honor" declines during afternoon
                hours. $50.00 matches a recoverable pattern.
            dataSource:
              type: string
              example: blended
    ExecuteRecoveryFailed:
      type: object
      properties:
        success:
          type: boolean
          example: false
        message:
          type: string
          example: Recovery Failed
        error:
          type: string
          example: 'Purchase request failed: Card declined'
        transactionId:
          type: string
          example: FAILED_API_1773792234011
        strategyUsed:
          type: string
          example: all_failed
        gatewaysAttempted:
          type: integer
          example: 1
        recoveryEngineApplied:
          type: boolean
          example: true
        recommendedAction:
          type: string
          enum:
            - request_card_update
            - retry_later
            - manual_review
            - monitor
          description: >-
            What to do next about this failure. Branch your dunning logic on
            this stable signal rather than parsing the raw decline code.
          example: retry_later
        recommendedActionReason:
          type: string
          description: Human-readable explanation of the recommended action.
          example: >-
            The issuer returned a soft decline. A later retry, or a card update,
            may succeed.
        ai:
          type: object
          properties:
            score:
              type: number
              example: 35.2
            confidence:
              type: integer
              example: 45
            reasoning:
              type: string
            dataSource:
              type: string
              example: static
    ExecuteRecoveryQueued:
      type: object
      properties:
        message:
          type: string
          example: >-
            Insufficient funds. Queued for Smart-Time Retry at
            2026-04-04T06:00:00.000Z.
    ValidationError:
      type: object
      properties:
        error:
          type: string
          example: Validation failed.
        details:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
          example:
            paymentMethodToken:
              - Payment method token is required
            amount:
              - Amount must be a positive number
    UnauthorizedError:
      type: object
      properties:
        error:
          type: string
          example: Unauthorized. Missing or invalid API key.
    ExecuteRecoveryBlocked:
      type: object
      properties:
        error:
          type: string
          example: >-
            Transaction blocked by Revtain Risk Engine to protect Merchant
            Health.
        declineCode:
          type: string
          example: fraudulent
        action:
          type: string
          example: blocked
        recommendedAction:
          type: string
          enum:
            - request_card_update
            - retry_later
            - manual_review
            - monitor
          description: >-
            What to do next. `manual_review` for fraud signals;
            `request_card_update` when the issuer requires authentication or a
            new card.
          example: manual_review
        recommendation:
          type: string
          description: Human-readable explanation of the recommended action.
          example: >-
            The issuer flagged this card for fraud. Do not retry — review the
            account.
    ExecuteRecoveryDuplicate:
      type: object
      properties:
        error:
          type: string
          example: Duplicate recovery request.
        message:
          type: string
          example: >-
            A recovery attempt with this idempotencyKey has already been
            processed.
        existingTransactionId:
          type: string
          example: da646dba-ce56-4483-ad0a-2a4fac54a5e2
        existingStatus:
          type: string
          example: succeeded
        existingRecovered:
          type: boolean
          example: true
    RateLimitError:
      type: object
      properties:
        error:
          type: string
          example: >-
            Too many recovery requests. Rate limit: 60 requests per minute per
            API key.
        retryAfter:
          type: string
          example: 60 seconds
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-KEY
      description: 'Your Revtain API key (format: `rev_xxx`). Provided during onboarding.'

````