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

# Simular uma mudança de status

> Leva um registro do sandbox ao status que você quer testar. Disponível só no sandbox.

> [card] [Guia: Testes no sandbox](https://developers.javalibridge.com/pt-BR/guides/testing.md)
>
> O que você pode simular, os caminhos a testar e o checklist antes de ir para produção.


## OpenAPI

````yaml api-reference/openapi.yaml POST /v1/sandbox/simulations
openapi: 3.1.0
info:
  title: Javali Bridge API
  version: 1.0.0
  description: >
    Javali Bridge international payments API — v1: USD→BRL
    (fromCurrency/toCurrency), FX contracted remittance by remittance (SPOT) and
    payment via Pix.


    ## Principles

    - Quote and operation are separate domains. The quote (`POST /v1/fx/quotes`)
    is only a price and does not create a remittance. The remittance is created
    by the operation the client wants to perform — in v1, a withdrawal to a
    beneficiary: `POST /v1/fx/quotes` → `POST /v1/remittances/withdrawals`.

    - The quote is only a price: a single price, the same for PREFUNDED and
    CREDIT, valid for any sender of the client. The only fee of the remittance
    is the FX spread, as a percentage. The advance cost (CREDIT) follows the
    contract and is charged in the settlement batch. Sender, beneficiary,
    purpose and funding are informed in the withdrawal.

    - USDC Inventory: the client can contract FX in advance. A quote with `usage
    = INVENTORY` is used once to create an Inventory Lot (`POST
    /v1/inventories`), which locks rate, volume and the due date of the
    obligation and creates a fixed USDC obligation. Lot usage does not expire;
    with the obligation overdue and unpaid, the lot becomes `SUSPENDED`. The lot
    is consumed later by withdrawals with `funding.mode = INVENTORY`.

    - Monetary amounts are decimal strings. Request amounts must be greater than
    zero.

    - Lists use cursor pagination (`cursor`, `limit`; response with
    `nextCursor`).


    ## Rate limiting

    429 responses carry `Retry-After` (seconds). Clients must respect the header
    and apply exponential backoff with jitter.


    ## Errors

    Every error returns `ApiError`. The `code` field follows the catalog in
    `components.x-error-catalog`; new codes may be added without a version
    change — clients must handle unknown codes by the HTTP status.

    Business rejections of a withdrawal are not errors: the remittance goes to
    `REJECTED` with `rejectedCode` and `rejectedDescription`, from the catalog
    in `components.x-rejection-catalog`. An HTTP error means the request was not
    accepted and no remittance was created. A rejection is a remittance that
    exists, with an ID, and was stopped before FX.


    ## Enums

    New status values and new event types may be added without a version change,
    with the same policy as error codes. Clients must tolerate unknown values.


    ## Webhooks

    Events are documented in `webhooks`. Each delivery is a `POST` with the
    `WebhookEvent` envelope and the headers:

    - `JavaliBridge-Event-Id`: same as `eventId`; use it to deduplicate
    (delivery is at-least-once).

    - `JavaliBridge-Timestamp`: unix epoch (seconds) of the delivery.

    - `JavaliBridge-Signature`: `v1=<hex(HMAC-SHA256(signingSecret, timestamp +
    "." + rawBody))>`. Reject if the signature does not match or if |now −
    timestamp| > 300s.

    Respond 2xx within 10s; failures are retried with exponential backoff for up
    to 24h. Delivery order is not guaranteed — use `occurredAt` and the state of
    the resource, or read the resource via GET.


    ## Reconciliation keys

    Every remittance is traceable by the same keys in every object:

    `externalId` (MSB ID, unique per client and immutable) · `quoteId` ·
    `remittanceId` · `settlementId` (CREDIT) · `transactionId` (Pix payment) ·
    `inventoryId` (INVENTORY).

    - Quote → `remittanceId`, `externalId` (filled when the quote is used by a
    withdrawal)

    - Remittance → `externalId`, `quoteId` (null in INVENTORY), `inventoryId`
    (INVENTORY), `settlement.settlementId`, `payout.transactionId`

    - Inventory → `quoteId` (the quote that created the lot), `externalId`;
    remittances of the lot in `GET /v1/remittances?inventoryId=`

    - SettlementItem → `remittanceId`, `externalId`, `quoteId`, `transactionId`

    - Receipt → `remittanceId`, `externalId`, `quoteId`, `transactionId`

    - Remittance webhooks → full Remittance snapshot
servers:
  - url: https://api.javalibridge.com
    description: Production
  - url: https://sandbox.javalibridge.com
    description: Sandbox
security:
  - BearerAuth: []
tags:
  - name: Authentication
  - name: Health
  - name: FX Quotes
  - name: Inventories
  - name: Remittances
  - name: Senders
  - name: Beneficiaries
  - name: Credit Line
  - name: Limits
  - name: Wallets
  - name: Settlements
  - name: Webhooks
  - name: Sandbox
    description: Endpoints that exist only in the sandbox, to test your integration.
paths:
  /v1/sandbox/simulations:
    post:
      tags:
        - Sandbox
      summary: Simulate a status change (sandbox only)
      description: >
        Moves a sandbox record to the requested status and sends the
        corresponding webhook. Not available in production: the route does not
        exist there and returns `404`.


        In the sandbox no record moves on its own: senders and beneficiaries
        stay `PENDING`, Pix keys stay `SCREENING` and remittances stay
        `RECEIVED` until you simulate the next status.


        - One transition per call. The webhook is sent by the real flow, with
        the same payload as in production.

        - The effects are the real ones: reservation and release of limit, entry
        in the settlement batch, Inventory Lot suspended, receipt available.

        - Only the transitions that exist in production are accepted. An invalid
        one returns `409` `INVALID_STATUS_TRANSITION`, with the accepted
        statuses in `details`.

        - `REMITTANCE` → `PROCESSING` runs the real validation. If it fails, the
        result is `REJECTED` with the real code, and the response shows it.

        - `REJECTED` requires `rejectedCode`: a validation code from `RECEIVED`,
        or `COMPLIANCE_REJECTED` from `PROCESSING` or `ON_HOLD`.
        `rejectedDescription` is filled by the system.


        Accepted transitions:


        | `resourceType` | From | To | Webhook |

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

        | `SENDER` | Any | `ACTIVE`, `PENDING`, `RESTRICTED`, `BLOCKED`,
        `INACTIVE` | `sender.status_changed` |

        | `BENEFICIARY` | Any | `ACTIVE`, `PENDING`, `BLOCKED`, `INACTIVE` |
        `beneficiary.status_changed` |

        | `PIX_KEY` | `SCREENING` | `APPROVED`, `REJECTED` |
        `beneficiary.status_changed` |

        | `PIX_KEY` | `APPROVED` | `REJECTED` | `beneficiary.status_changed` |

        | `QUOTE` | `AVAILABLE` | `EXPIRED` | — |

        | `REMITTANCE` | `RECEIVED` | `PROCESSING`, `REJECTED` (validation
        codes) | `remittance.status_changed` |

        | `REMITTANCE` | `PROCESSING` | `COMPLETED`, `ON_HOLD`,
        `FUNDS_HELD_BRL`, `REJECTED` (`COMPLIANCE_REJECTED`) |
        `remittance.status_changed` |

        | `REMITTANCE` | `ON_HOLD` | `PROCESSING`, `REJECTED`
        (`COMPLIANCE_REJECTED`) | `remittance.status_changed` |

        | `REMITTANCE` | `COMPLETED` | `REFUNDED_BY_USER` |
        `remittance.status_changed` |

        | `SETTLEMENT` | `OPEN`, `CLOSED`, `DUE` | The next one, in the order
        `OPEN` → `CLOSED` → `DUE` → `OVERDUE` | — |

        | `SETTLEMENT` | `CLOSED`, `DUE`, `OVERDUE` | `COMPLETED` | — |

        | `INVENTORY_OBLIGATION` | `PENDING` | `OVERDUE`, `PAID` | — |

        | `INVENTORY_OBLIGATION` | `OVERDUE` | `PAID` | — |


        Authentication: the same Bearer token of the sandbox. `Idempotency-Key`
        is not required.
      operationId: createSandboxSimulation
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SandboxSimulationRequest'
            examples:
              remittanceProcessing:
                summary: 'Remittance: validation passed'
                value:
                  resourceType: REMITTANCE
                  resourceId: rem_123
                  status: PROCESSING
              remittanceRejected:
                summary: 'Remittance: rejected with a code'
                value:
                  resourceType: REMITTANCE
                  resourceId: rem_123
                  status: REJECTED
                  rejectedCode: CREDIT_LIMIT_EXCEEDED
              senderActive:
                summary: Sender approved
                value:
                  resourceType: SENDER
                  resourceId: snd_789
                  status: ACTIVE
              pixKeyApproved:
                summary: Pix key approved
                value:
                  resourceType: PIX_KEY
                  resourceId: pi_456
                  status: APPROVED
      responses:
        '200':
          description: Status changed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SandboxSimulation'
              examples:
                processing:
                  summary: RECEIVED → PROCESSING
                  value:
                    resourceType: REMITTANCE
                    resourceId: rem_123
                    previousStatus: RECEIVED
                    status: PROCESSING
                    rejectedCode: null
                    rejectedDescription: null
                    simulatedAt: '2026-11-11T14:02:10Z'
                realValidationFailed:
                  summary: PROCESSING requested, real validation failed
                  value:
                    resourceType: REMITTANCE
                    resourceId: rem_123
                    previousStatus: RECEIVED
                    status: REJECTED
                    rejectedCode: SENDER_NOT_ELIGIBLE
                    rejectedDescription: >-
                      The sender does not exist, is not ACTIVE, is LEVEL_0 or
                      cannot send this remittance.
                    simulatedAt: '2026-11-11T14:02:10Z'
        '400':
          $ref: '#/components/responses/BadRequest'
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: >-
            `INVALID_STATUS_TRANSITION`: the record cannot go from its current
            status to the one requested. `details` lists the accepted statuses.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                code: INVALID_STATUS_TRANSITION
                message: REMITTANCE rem_123 cannot go from COMPLETED to PROCESSING.
                requestId: req_7c2d
                retryable: false
                details:
                  - field: status
                    reason: 'accepted: REFUNDED_BY_USER'
        '429':
          $ref: '#/components/responses/TooManyRequests'
      servers:
        - url: https://sandbox.javalibridge.com
          description: Sandbox
components:
  schemas:
    SandboxSimulationRequest:
      type: object
      required:
        - resourceType
        - resourceId
        - status
      properties:
        resourceType:
          type: string
          enum:
            - SENDER
            - BENEFICIARY
            - PIX_KEY
            - QUOTE
            - REMITTANCE
            - SETTLEMENT
            - INVENTORY_OBLIGATION
          description: >-
            Type of the record. `PIX_KEY` is a payment instruction of a
            beneficiary. `INVENTORY_OBLIGATION` is the USDC obligation of an
            Inventory Lot.
        resourceId:
          type: string
          description: >-
            ID of the record: `senderId`, `beneficiaryId`,
            `paymentInstructionId` (for `PIX_KEY`), `quoteId`, `remittanceId`,
            `settlementId` or `inventoryId` (for `INVENTORY_OBLIGATION`).
          example: rem_123
        status:
          type: string
          description: Target status, from the status enum of the resource.
          example: PROCESSING
        rejectedCode:
          allOf:
            - $ref: '#/components/schemas/RejectedCode'
          description: >-
            Required when `resourceType = REMITTANCE` and `status = REJECTED`;
            not accepted otherwise. `rejectedDescription` is filled by the
            system with the standard text of the code.
    SandboxSimulation:
      type: object
      required:
        - resourceType
        - resourceId
        - previousStatus
        - status
        - simulatedAt
      properties:
        resourceType:
          type: string
          description: Same as in the request.
        resourceId:
          type: string
          description: Same as in the request.
        previousStatus:
          type: string
          description: Status before the simulation.
        status:
          type: string
          description: >-
            Resulting status. It differs from the requested one in one case:
            `REMITTANCE` → `PROCESSING` runs the real validation and can result
            in `REJECTED`.
        rejectedCode:
          anyOf:
            - $ref: '#/components/schemas/RejectedCode'
            - type: 'null'
          description: Filled when the result is `REJECTED`.
        rejectedDescription:
          type:
            - string
            - 'null'
          description: Filled when the result is `REJECTED`.
        simulatedAt:
          type: string
          format: date-time
    ApiError:
      type: object
      required:
        - code
        - message
        - requestId
      properties:
        code:
          type: string
          description: >-
            Code from the catalog in `x-error-catalog`. Extensible: handle
            unknown codes by the HTTP status. Rejection reasons of a remittance
            are not errors: they are in `Remittance.rejectedCode`.
          example: VALIDATION_ERROR
        message:
          type: string
        requestId:
          type: string
        retryable:
          type: boolean
          description: >-
            Indica se a mesma requisição pode ser repetida (com a mesma
            Idempotency-Key).
        details:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              reason:
                type: string
    RejectedCode:
      type: string
      enum:
        - QUOTE_EXPIRED
        - QUOTE_ALREADY_USED
        - QUOTE_USAGE_MISMATCH
        - SENDER_NOT_ELIGIBLE
        - BENEFICIARY_NOT_ELIGIBLE
        - RELATIONSHIP_MISMATCH
        - PAYMENT_INSTRUCTION_INVALID
        - PIX_KEY_NOT_FOUND
        - FUNDING_MODE_NOT_ENABLED
        - CREDIT_LIMIT_EXCEEDED
        - INSUFFICIENT_PREFUNDED_BALANCE
        - AMOUNT_BELOW_MINIMUM
        - AMOUNT_ABOVE_LIMIT
        - ACCOUNT_DAILY_LIMIT_EXCEEDED
        - INVENTORY_NOT_FOUND
        - INVENTORY_SUSPENDED
        - INSUFFICIENT_INVENTORY_BALANCE
        - COMPLIANCE_REJECTED
      description: >-
        Rejection reason of a remittance, from the catalog in
        `components.x-rejection-catalog`. Validation codes reject from
        `RECEIVED`; `COMPLIANCE_REJECTED` rejects from `PROCESSING` or
        `ON_HOLD`. Extensible enum: new codes may be added without a version
        change, so tolerate unknown values.
  responses:
    BadRequest:
      description: Requisição inválida (VALIDATION_ERROR)
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    NotFound:
      description: Recurso não encontrado no tenant autenticado
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
    TooManyRequests:
      description: Limite de requisições excedido (RATE_LIMITED)
      headers:
        Retry-After:
          description: Segundos até nova tentativa
          schema:
            type: integer
            minimum: 1
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ApiError'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````

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