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

# Register a Dry-Run Provider Event

> Register provider request, response, or webhook payloads for pre-production validation.

Dry-run is a pre-production validation surface. It receives the API calls your integration sends to a payment provider — request, response, and webhook payloads — and correlates them with the equivalent Yuno public-API call you make **in parallel** with the `Dry-run: true` header set.

Yuno then executes an automated validation pipeline that grades the quality of the public-API request against the provider payload: missing fields, shape mismatches, wrong enum values, unmapped metadata, and any other inconsistency that would cause the real payment to fail or behave differently once you go live.

### How the pair works

1. Your integration makes its normal call to the provider (e.g. Stripe, Adyen, dlocal).
2. Your integration also calls the relevant Yuno public-API endpoint (e.g. `POST /v1/payments`) with the header **`Dry-run: true`**. Yuno accepts the request, does not route it to any provider, and stores it for comparison.
3. Your integration calls `POST /v1/dry-run/provider-events` with the raw provider exchange (request, response, webhook) it just performed, correlated to the same `merchant_reference`.
4. Yuno pairs the two records by `merchant_reference` + `account_id` and runs the validation pipeline. Results are available through the dashboard and via `GET /v1/dry-run/provider-events/{id}` (read API, separate reference).

The outcome tells you whether the public-API request you are building today would produce the same provider behavior once Yuno starts routing it — without touching production money or sending a live transaction to the provider through Yuno.

### When to use it

* **Pre-launch**: certify your public-API integration against the provider behavior you already have working.
* **Provider migrations**: verify a new provider accepts the fields Yuno forwards before switching traffic.
* **Regression checks**: re-run dry-runs in CI to catch drift when your integration or the provider's contract changes.

<Note>
  One call can carry up to **10** event entries (REQUEST, RESPONSE, and/or WEBHOOK), all tied to the same payment via `merchant_reference`. See the [correlation rules](#correlation).
</Note>

<Note>
  This endpoint has a companion: `POST /v1/payments` accepts a `Dry-run: true` request header that tells Yuno to validate instead of routing. Both legs must share the same `merchant_reference` so validation can pair them.
</Note>

<Note>
  Use `X-Idempotency-Key` for safe retries. Same key + same payload returns the original response; same key + different payload returns `409`.
</Note>

<Warning>
  **PCI boundary**

  `headers` and `body` are sent **base64-encoded**. Yuno base64-decodes on ingest, applies deterministic PAN/CVV/auth-token redaction, and persists only the redacted form. See [PCI Compliance](/docs/security-and-compliance/pci-compliance).
</Warning>

***

## Correlation

* `merchant_reference` is always required and uniquely identifies the order on your side. Yuno uses it to resolve the event to a payment asynchronously when `payment_id` is not supplied.
* `payment_id`, if supplied, is resolved immediately. If the id is unknown for your account the request returns `404 PAYMENT_NOT_FOUND`.
* `provider_id` + `payment_method_type` optionally identify which integration surface the dry-run exercises (e.g. `stripe` + `CREDIT_CARD`). if omitted, Yuno uses the information from the associated payment.


## OpenAPI

````yaml openapi/dry-run/register-dry-run-provider-event.json POST /dry-run/provider-events
openapi: 3.1.0
info:
  title: Yuno Dry-Run API
  version: '1.0'
servers:
  - url: https://api-sandbox.y.uno/v1
  - url: https://api.y.uno/v1
security: []
paths:
  /dry-run/provider-events:
    post:
      summary: Register provider request / response / webhook payloads
      description: >
        Stores the HTTP traffic that the merchant exchanged directly with a
        payment

        provider (request, response, and webhook) for correlation to a Yuno
        payment.
      operationId: registerDryRunProviderEvent
      parameters:
        - in: header
          name: PUBLIC-API-KEY
          schema:
            type: string
          description: Public API key. One of PUBLIC-API-KEY / PRIVATE-SECRET-KEY required.
        - in: header
          name: PRIVATE-SECRET-KEY
          schema:
            type: string
          description: >-
            Private secret key for server-to-server calls. One of PUBLIC-API-KEY
            / PRIVATE-SECRET-KEY required.
        - in: header
          name: X-Idempotency-Key
          schema:
            type: string
            maxLength: 64
          description: Free-form string (MAX 64). 24-hour replay window.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DryRunRequest'
      responses:
        '201':
          description: Dry-run registered
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DryRunResponse'
        '400':
          description: Validation failure
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          description: Missing or invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '404':
          description: Payment not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '409':
          description: Idempotency replay with a different payload
        '413':
          description: Payload or batch exceeds size limits
        '415':
          description: Unsupported Content-Type (must be application/json)
        '429':
          description: Rate limit exceeded
components:
  schemas:
    DryRunRequest:
      type: object
      required:
        - merchant_reference
        - events
      properties:
        merchant_reference:
          type: string
          minLength: 3
          maxLength: 255
          description: Merchant-assigned identifier (MAX 255; MIN 3). Unique per account.
          example: ORD-12345
        payment_id:
          type: string
          format: uuid
          description: Yuno payment UUID. If supplied, resolved immediately.
          example: fb9e5fa4-684c-4747-9755-9d332617f16f
        account_id:
          type: string
          format: uuid
          description: Yuno account UUID — same shape as account_id in POST /v1/payments.
          example: a389f417-ecd1-4355-89f5-7489564f264d
        provider_id:
          type: string
          description: Provider identifier. Allowed values aligned to the Yuno catalog.
          example: STRIPE
          enum:
            - STRIPE
            - ADYEN
            - CYBERSOURCE
            - BRAINTREE
            - NMI
            - CHECKOUT
            - WORLDPAY
            - PAYPAL
            - EBANX
            - GLOBALPAYMENTS
            - NUVEI
            - CIELO
            - MPGS
            - PRISMA
            - FISERV
            - WORLDLINE
            - ANTOM
            - ORBITAL
            - GOCARDLESS
            - AUTHORIZE_NET
            - SONY
            - CITI
            - EPX
            - HPAY
            - PAYSTACK
            - PLAID
            - SAFERPAY
            - SIKA_HEALTH
            - VALIDIFI
            - WEPAY
            - CARD_CONNECT
            - GMO_PG
            - MONERIS
            - BLUESNAP
            - QUICK_GATEWAY
            - TWENTYFOUR_HOUR_FITNESS
            - MERCHANT_ESOLUTIONS
            - NETS
            - FAT_ZEBRA
            - WINDCAVE
            - CHASE_MOBILITY
            - HELIX
            - ANB
            - AMAZON_PAY
            - OPAYO
            - IP_PAYMENTS
            - KLARNA
            - BILLDESK
            - WELLS_FARGO
            - SAGEPAY
            - PLANET
        payment_method_type:
          type: string
          description: >-
            Payment method exercised by this dry-run. Same vocabulary as
            payment_method.type in POST /v1/payments.
          example: CREDIT_CARD
          enum:
            - ''
            - CARD
            - CREDIT_CARD
            - CREDIT_CARD_REFERENCE_TRANSACTION
            - DEBIT_CARD
            - EPX_TOKEN
            - TEST_CREDIT_CARD
            - UPC_TOKEN_TRANSACTION
            - APPLE_PAY
            - GOOGLE_PAY
            - PIX
            - PSE
            - OXXO
            - BOLETO
            - ALI_PAY
            - AMAZON_PAY
            - GCASH
            - IDEAL
            - KAKAO_PAY
            - KLARNA
            - MOMO_PAY
            - NAVER_PAY
            - OVO
            - PAYPAL
            - PAYPAL_CREDIT
            - PAYPAY
            - PAZE
            - TOSS_PAY
            - UPI
            - VENMO
            - ACH
            - BANK_TRANSFER
            - CRYPTO
            - CASH
        events:
          type: array
          minItems: 1
          maxItems: 10
          description: 1–10 HTTP exchange entries for this dry-run (MAX 10; MIN 1).
          items:
            $ref: '#/components/schemas/Event'
          example:
            - type: REQUEST
              http_method: POST
              operation_type: PURCHASE
              base_url: https://api.stripe.com
              endpoint: /v1/charges
              headers: eyBDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL2pzb24gfQ==
              body: eyBhbW91bnQ6IDIwMDAsIGN1cnJlbmN5OiAidXNkIiB9
    DryRunResponse:
      type: object
      required:
        - id
        - status
        - merchant_reference
      properties:
        id:
          type: string
          description: Public identifier of the dry-run registration (nano_id, 21 chars).
          example: drun_1209fnkw428ufwd
        status:
          type: string
          enum:
            - REGISTERED
          description: Lifecycle state.
          example: REGISTERED
        merchant_reference:
          type: string
          example: ORD-12345
        payment_id:
          type: string
          format: uuid
          nullable: true
          example: fb9e5fa4-684c-4747-9755-9d332617f16f
        account_id:
          type: string
          format: uuid
          nullable: true
          example: a389f417-ecd1-4355-89f5-7489564f264d
        provider_id:
          type: string
          example: STRIPE
        payment_method_type:
          type: string
          example: CARD
          enum:
            - ''
            - CARD
            - CREDIT_CARD
            - CREDIT_CARD_REFERENCE_TRANSACTION
            - DEBIT_CARD
            - EPX_TOKEN
            - TEST_CREDIT_CARD
            - UPC_TOKEN_TRANSACTION
            - APPLE_PAY
            - GOOGLE_PAY
            - PIX
            - PSE
            - OXXO
            - BOLETO
            - ALI_PAY
            - AMAZON_PAY
            - GCASH
            - IDEAL
            - KAKAO_PAY
            - KLARNA
            - MOMO_PAY
            - NAVER_PAY
            - OVO
            - PAYPAL
            - PAYPAL_CREDIT
            - PAYPAY
            - PAZE
            - TOSS_PAY
            - UPI
            - VENMO
            - ACH
            - BANK_TRANSFER
            - CRYPTO
            - CASH
        operation_type:
          type: string
          example: PURCHASE
    Error:
      type: object
      required:
        - code
        - messages
        - httpCode
      properties:
        code:
          type: string
          description: Stable error code.
          enum:
            - NOT_AUTHENTICATED
            - AuthenticationFail
            - INVALID_PARAMETERS
            - TRAFFIC_LOG_VALIDATION_FAILED
            - TRAFFIC_LOG_MERCHANT_REFERENCE_REQUIRED
            - TRAFFIC_LOG_BODY_ENCODING_MISMATCH
            - TRAFFIC_LOG_IDEMPOTENCY_REPLAY
            - TRAFFIC_LOG_PAYLOAD_TOO_LARGE
            - TRAFFIC_LOG_UNSUPPORTED_CONTENT_TYPE
            - TRAFFIC_LOG_SEMANTIC_INVALID
            - PAYMENT_NOT_FOUND
            - RATE_LIMITED
        messages:
          type: array
          items:
            type: string
          description: Human-readable error details.
        httpCode:
          type: integer
          format: int32
    Event:
      type: object
      required:
        - type
        - http_method
        - operation_type
        - headers
      properties:
        type:
          type: string
          enum:
            - REQUEST
            - RESPONSE
            - WEBHOOK
          description: Which leg of the exchange this entry captures.
          example: REQUEST
        http_method:
          type: string
          enum:
            - GET
            - POST
            - PUT
            - PATCH
            - DELETE
          example: POST
        operation_type:
          type: string
          enum:
            - PURCHASE
            - AUTHORIZE
            - CAPTURE
            - CANCEL
            - REFUND
            - CHARGEBACK
            - THREE_D_SECURE
          description: Identifies the payment operation type being simulated.
          example: PURCHASE
        base_url:
          type: string
          format: uri
          description: >-
            Required for REQUEST and WEBHOOK. Origin of the provider endpoint —
            scheme + host + port (e.g. https://api.stripe.com).
          example: https://api.stripe.com
        endpoint:
          type: string
          description: >-
            Required for REQUEST and WEBHOOK. Path and query portion (e.g.
            /v1/charges?expand=customer).
          example: /v1/charges
        http_status_code:
          type: integer
          format: int32
          minimum: 100
          maximum: 599
          description: Required for RESPONSE and WEBHOOK. Omit for REQUEST.
        headers:
          type: string
          format: byte
          maxLength: 87400
          description: >
            Base64-encoded header payload. Decoded content may be a
            JSON-serialized

            `{header-name: header-value}` map or the raw HTTP header block. Hard

            cap: 64 KB of decoded bytes per event.
          example: eyBDb250ZW50LVR5cGU6IGFwcGxpY2F0aW9uL2pzb24gfQ==
        body:
          type: string
          format: byte
          maxLength: 1398000
          description: >
            Base64-encoded body payload. Omit for empty bodies. Hard cap: 1 MB
            of

            decoded bytes per event. For non-UTF-8 bodies (protobuf, gzip),

            base64-encode the raw bytes directly.
          example: eyBhbW91bnQ6IDIwMDAsIGN1cnJlbmN5OiAidXNkIiB9

````