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

# Simulate an Automation deposit

> Simulate an inbound ACH, wire, or FedNow deposit into a testnet Automation and run the normal Transfer, mint, and webhook flow without moving real fiat.

Testnet Automations return placeholder banking coordinates that cannot receive real deposits. Use this endpoint to simulate an inbound ACH, wire, or FedNow deposit instead. Brale creates a simulated inbound payment, runs the normal Automation mint path, and returns the resulting Transfer. Brale does not contact a bank, and no real fiat moves.

**POST** `https://api.brale.xyz/accounts/{account_id}/automations/{automation_id}/simulations/deposits`

Required scopes: `automations:write` and `network:testnet`

> [!NOTE]
>
> This endpoint is available only with testnet credentials. The Automation must belong to the account in the path, have `status: "active"`, and have a destination on a testnet chain, such as `base_sepolia` or `solana_devnet`.

## Path parameters

| Parameter | Type | Required | Description |
| :- | :- | :- | :- |
| `account_id` | string (KSUID) | Yes | The account that owns the Automation. |
| `automation_id` | string (KSUID) | Yes | The testnet Automation to fund. |

## Headers

| Header | Required | Description |
| :- | :- | :- |
| `Authorization` | Yes | `Bearer <token>` from testnet API credentials. |
| `Idempotency-Key` | Yes | A unique key for this simulated deposit. See [Idempotency](#idempotency). |

## Request body

The request body accepts only the fields below. Brale rejects additional properties.

| Field | Type | Required | Description |
| :- | :- | :- | :- |
| `amount.value` | string | Yes | Positive decimal amount greater than zero, such as `"10.00"`. |
| `amount.currency` | string | Yes | Must be a reserve currency accepted by the API, such as `USD`. |
| `transfer_type` | string | Yes | Inbound rail to simulate. Accepted values: `ach`, `wire`, `fednow`. These are simulator inputs, not Transfer rail identifiers. `fednow` produces a Transfer with `source.transfer_type: "fednow_credit"`. Do not send `fednow_credit` here. |

## Examples

```bash FedNow theme={null}
curl --request POST \
  --url "https://api.brale.xyz/accounts/${ACCOUNT_ID}/automations/${AUTOMATION_ID}/simulations/deposits" \
  --header "Authorization: Bearer ${AUTH_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $(uuidgen)" \
  --data '{
    "amount": { "value": "1.00", "currency": "USD" },
    "transfer_type": "fednow"
  }'
```

```bash Wire theme={null}
curl --request POST \
  --url "https://api.brale.xyz/accounts/${ACCOUNT_ID}/automations/${AUTOMATION_ID}/simulations/deposits" \
  --header "Authorization: Bearer ${AUTH_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $(uuidgen)" \
  --data '{
    "amount": { "value": "10.00", "currency": "USD" },
    "transfer_type": "wire"
  }'
```

```bash ACH theme={null}
curl --request POST \
  --url "https://api.brale.xyz/accounts/${ACCOUNT_ID}/automations/${AUTOMATION_ID}/simulations/deposits" \
  --header "Authorization: Bearer ${AUTH_TOKEN}" \
  --header "Content-Type: application/json" \
  --header "Idempotency-Key: $(uuidgen)" \
  --data '{
    "amount": { "value": "10.00", "currency": "USD" },
    "transfer_type": "ach"
  }'
```

## Response

### 202 Accepted

Returns the standard [Transfer](https://docs.brale.xyz/key-concepts/transfers.md) representation. There is no separate simulation resource. The Transfer includes `automation_id`, and `source.transfer_type` records the simulated rail. For a `fednow` simulation, `source.transfer_type` is `fednow_credit`. `202 Accepted` means Brale accepted the simulated deposit. It does not mean the mint is complete.

```json Response theme={null}
{
  "id": "3F1kP8vQ2mZrT6yN0bXcW4hJd7s",
  "status": "pending",
  "failure": null,
  "amount": {
    "value": "10.00",
    "currency": "USD"
  },
  "source": {
    "value_type": "USD",
    "transfer_type": "wire"
  },
  "destination": {
    "address_id": "3ARaM0I93ObWOIFDIztsTx4TAsp",
    "value_type": "SBC",
    "transfer_type": "base_sepolia"
  },
  "note": null,
  "automation_id": "3AjRnDClEzwuCKlRioG3OXMS4pH",
  "created_at": "2026-09-29T17:00:00.000000Z",
  "updated_at": "2026-09-29T17:00:00.000000Z"
}
```

```json Response (FedNow simulation) theme={null}
{
  "id": "36JqT2nF4kW8xYbR1sLmPz9cVdA",
  "status": "pending",
  "failure": null,
  "amount": {
    "value": "1.00",
    "currency": "USD"
  },
  "source": {
    "value_type": "USD",
    "transfer_type": "fednow_credit"
  },
  "destination": {
    "address_id": "3ARaM0I93ObWOIFDIztsTx4TAsp",
    "value_type": "SBC",
    "transfer_type": "base_sepolia"
  },
  "note": null,
  "automation_id": "3AjRnDClEzwuCKlRioG3OXMS4pH",
  "created_at": "2026-10-15T17:00:00.000000Z",
  "updated_at": "2026-10-15T17:00:00.000000Z"
}
```

Fetch the Transfer with [Get a transfer](https://docs.brale.xyz/api-reference/brale/get-transfer.md) to follow it to `complete` and read `destination.transaction_id` for the testnet mint.

## Errors

| Status | `type` | When |
| :- | :- | :- |
| `400` | Schema validation error | `transfer_type` is not `ach`, `wire`, or `fednow` (for example, `rtp` or `fednow_credit`), a required field is missing, or the body includes an unknown field. |
| `400` | `invalid_currency` | `amount.currency` is not a reserve currency accepted by the API (for example, `EUR`). |
| `400` | `invalid_amount` | `amount.value` is malformed, zero, or negative. For zero, `detail` is `Amount must be greater than zero`. |
| `401` | | Missing or invalid bearer token. |
| `403` | | The credentials do not include `network:testnet` or another required scope. Mainnet API keys receive this response. |
| `404` | | The account or Automation was not found, or the Automation does not belong to the account in the path. |
| `422` | `mainnet_destination` | The Automation destination is on a mainnet chain. `detail` is `Deposit simulation is only available for testnet automations`. |
| `422` | `automation_not_active` | The Automation is pending, disabled, archived, or otherwise inactive. `detail` is `Automation must be active to simulate a deposit`. |
| `422` | | The `Idempotency-Key` was already used with a different request body or URI. |

## Idempotency

`Idempotency-Key` is required, as on every `POST` request. See [Idempotency](https://docs.brale.xyz/key-concepts/idempotency.md).

* Send a new key to create a new simulated deposit.
* Retry with the same key and the same body to get the cached `202` response. The retry does not create a second payment, Transfer, transaction, or mint.
* Reusing a key with a different body or URI returns `422` and does not create another mint.

## Webhooks

Brale emits the normal `payment.completed` [webhook event](https://docs.brale.xyz/webhooks/webhook-events.md) for the simulated inbound payment, followed by the normal `transfer.*` events as the Transfer progresses. There is no simulation-specific webhook type. Simulation creates simulated fiat funding only. It does not test a real bank or the FedNow network. See [Receive FedNow deposits](https://docs.brale.xyz/guides/fednow-inbound.md#test-on-testnet).


## OpenAPI

````yaml api-reference/brale-openapi.yaml POST /accounts/{account_id}/automations/{automation_id}/simulations/deposits
openapi: 3.0.3
info:
  title: Brale Issuance and Orchestration API
  version: 2.3.1
  description: >
    Brale supports stablecoin issuance and orchestration, enabling businesses
    and

    ecosystems to create their own stablecoins and convert between fiat and
    stablecoins

    seamlessly. From stablecoin onramps, offramps, and swaps to custody and
    payouts, the

    Brale API makes it easy to build stablecoin-enabled products.


    NOTE: All resource IDs (including account_id, address_id,
    financial_institution_id,

    and automation_id) are KSUIDs—27-character alphanumeric strings that are
    sortable

    by time. Examples showing UUIDs are incorrect.



    **What's new in 2.3.1**

    - Unified **Addresses** model for on-chain and off-chain endpoints
      - `Transfers` now accepts **address_id only** (no financial_institution_id)
      - Optional `brand` object to control bank statement presentation (`branding` still accepted as legacy alias)
    - Added off-chain rails: `ach_credit`, `same_day_ach_credit`, `ach_debit`,
    `same_day_ach_debit`, `rtp-credit`

    - Plaid endpoints moved to `/accounts/{account_id}/plaid/*`

    - `Financial Institutions` marked **deprecated** (migration path to
    **Addresses**)

    - Create Account now uses `CreateManagedAccountRequest` with
    `beneficial_owners`, `business_controller`, and `EndUserTosAttestation`.

    - Transfers now accept `brand` (replaces `branding`, still aliased in docs).

    - Plaid endpoints updated to return `address_id` and accept
    `transfer_types`.

    - Off-chain Address creation uses `CreateExternalAddressRequest` oneOf with
    bank + blockchain variants.

    - FI endpoints kept but marked deprecated; use Addresses instead.

    - `rtp_credit` is the canonical RTP rail name.



    **FedNow**

    - Added the `fednow_credit` rail. Outbound: create a Transfer with
      `destination.transfer_type: fednow_credit` to a bank Address that lists
      `fednow_credit` in `transfer_types`. Inbound: payers send FedNow credits to an
      active Automation's `source.funding_instructions`; Brale creates the Transfer
      automatically with `source.transfer_type: fednow_credit`.
    - Simulate a testnet FedNow deposit with `transfer_type: fednow` on
      `POST /accounts/{account_id}/automations/{automation_id}/simulations/deposits`.
    - `bank_address` and `beneficiary_address` are required only when an
    external
      bank Address requests `wire`.
    - FedNow availability depends on account enablement.
servers:
  - url: https://api.brale.xyz
    description: Production server
security:
  - BearerAuth: []
tags:
  - name: Accounts
    description: Endpoints related to managing customer accounts (KYB, details, etc.)
  - name: Transfers
    description: >-
      Endpoints for creating and retrieving transfers (fiat to stablecoins,
      etc.)
  - name: Addresses
    description: >-
      On-chain and off-chain endpoints (custodial or external) represented by a
      single Addresses resource
  - name: Financial Institutions
    description: Legacy (deprecated) bank endpoints. Use Addresses instead.
  - name: Automations
    description: Automated deposit addresses or onramps
  - name: Plaid
    description: Bank linking and ACH debit via Plaid.
  - name: Orders
    description: Legacy tag used for transfers in older specs.
paths:
  /accounts/{account_id}/automations/{automation_id}/simulations/deposits:
    post:
      tags:
        - Automations
      summary: Simulate Automation Deposit
      description: >
        Simulates an inbound ACH, wire, or FedNow deposit into a testnet
        Automation and runs the normal Automation mint path. Returns the
        resulting Transfer. The request `transfer_type` is a simulator input
        (`ach`, `wire`, or `fednow`). A `fednow` simulation produces a Transfer
        with `source.transfer_type: fednow_credit`.


        Available only with testnet credentials. Required scopes:
        `automations:write` and `network:testnet`.


        The Automation must belong to the account in the path, be `active`, and
        have a testnet destination chain. Brale does not contact a bank and no
        real fiat moves.


        Retrying with the same `Idempotency-Key` and body returns the original
        `202` response without creating another payment, Transfer, or mint.
      operationId: simulate_automation_deposit
      parameters:
        - name: account_id
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/Ksuid'
          description: The ID of the account that owns the Automation
        - name: automation_id
          in: path
          required: true
          schema:
            $ref: '#/components/schemas/Ksuid'
          description: The ID of the testnet Automation to fund
        - in: header
          name: Idempotency-Key
          required: true
          schema:
            type: string
          example: idemp-123e4567-e89b-12d3-a456-426614174000
          description: >
            A unique string used to prevent duplicate operations. Use a new key
            for each new simulated deposit. Reuse the same key only to retry the
            same request. Reusing a key with a different body or URI returns
            `422`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimulateAutomationDepositRequest'
            examples:
              fednow:
                summary: Simulate a FedNow deposit
                value:
                  amount:
                    value: '1.00'
                    currency: USD
                  transfer_type: fednow
              wire:
                summary: Simulate a wire deposit
                value:
                  amount:
                    value: '10.00'
                    currency: USD
                  transfer_type: wire
              ach:
                summary: Simulate an ACH deposit
                value:
                  amount:
                    value: '10.00'
                    currency: USD
                  transfer_type: ach
      responses:
        '202':
          description: >-
            Accepted. Returns the Transfer created by the Automation. The
            Transfer includes `automation_id`, and `source.transfer_type`
            identifies the simulated rail. For `fednow`, `source.transfer_type`
            is `fednow_credit`. `202` means the simulated deposit was accepted.
            It does not mean the mint is complete.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transfer'
        '400':
          description: |
            Invalid request or schema. Known cases:

            - `transfer_type` is not `ach`, `wire`, or `fednow` (for example,
              `rtp` or `fednow_credit`) — schema validation error.

            - `invalid_currency` — the currency is not a supported reserve
              currency (for example, `EUR`).

            - `invalid_amount` — the amount is malformed, zero, or negative. For
              zero, `detail` is `Amount must be greater than zero`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorV2'
        '401':
          description: Unauthorized. Missing or invalid bearer token.
        '403':
          description: >-
            Forbidden. The credentials do not include `network:testnet` or
            another required scope. Mainnet API keys receive this response.
        '404':
          description: >-
            The account or Automation was not found, or the Automation does not
            belong to the account in the path.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorV2'
        '422':
          description: >
            The request is valid but cannot be processed. Known cases:


            - `mainnet_destination` — `Deposit simulation is only available for
              testnet automations`.

            - `automation_not_active` — `Automation must be active to simulate a
              deposit`. Returned for pending, disabled, archived, or otherwise
              inactive Automations.

            - The `Idempotency-Key` was already used with a different request
            body
              or URI.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorV2'
components:
  schemas:
    Ksuid:
      title: Kusid
      type: string
      format: ksuid
      pattern: ^[a-zA-Z0-9]{27}$
      example: 2VcUIIsgARwVbEGlIYbhg6fGG57
    SimulateAutomationDepositRequest:
      title: SimulateAutomationDepositRequest
      type: object
      description: >-
        Request body for simulating an inbound fiat deposit into a testnet
        Automation.
      additionalProperties: false
      properties:
        amount:
          allOf:
            - $ref: '#/components/schemas/Amount'
          description: >-
            Deposit amount. `value` must be a positive decimal string greater
            than zero. `currency` must be a reserve currency accepted by the
            API.
          example:
            value: '10.00'
            currency: USD
        transfer_type:
          type: string
          description: >-
            Inbound rail to simulate. This is a simulator input, not a Transfer
            rail identifier. `fednow` produces a Transfer with
            `source.transfer_type: fednow_credit`.
          enum:
            - ach
            - wire
            - fednow
          example: fednow
      required:
        - amount
        - transfer_type
    Transfer:
      title: Transfer
      type: object
      description: >-
        A money movement between a source and a destination. Returned by the
        create, get, and list transfer endpoints. The same shape is used
        everywhere a Transfer is exposed to API consumers.
      properties:
        id:
          $ref: '#/components/schemas/Ksuid'
        status:
          type: string
          description: Lifecycle stage of the transfer
          enum:
            - pending
            - processing
            - complete
            - canceled
            - failed
            - refunding
            - refunded
          example: pending
        failure:
          allOf:
            - $ref: '#/components/schemas/TransferFailure'
          nullable: true
          description: >-
            Structured failure details for a failed transfer. Usually `null`.
            Populated when `status` is `failed` and Brale has structured failure
            details for the transfer — most commonly for ACH returns, outbound
            wire returns, and other rail/provider failures. Clients should not
            assume `failure` is always present for every failed transfer; check
            for `null` before reading nested fields.
          example: null
        source:
          $ref: '#/components/schemas/TransferEndpoint'
        destination:
          $ref: '#/components/schemas/TransferEndpoint'
        amount:
          $ref: '#/components/schemas/Amount'
        note:
          type: string
          nullable: true
          description: Optional free-form note attached to the transfer.
          example: null
        automation_id:
          allOf:
            - $ref: '#/components/schemas/Ksuid'
          description: >-
            ID of the Automation that created this transfer, when applicable.
            Omitted for transfers created directly via the API.
          nullable: true
        funding_simulated:
          type: boolean
          description: >-
            Optional. When returned with a value of `true`, the source funding
            for this transfer was simulated in testnet rather than coming from a
            real payment. Not every simulated transfer is guaranteed to include
            this field. Not present for production-funded transfers.
        created_at:
          type: string
          format: date-time
          example: '2026-01-01T00:00:00Z'
        updated_at:
          type: string
          format: date-time
          example: '2026-01-01T00:00:00Z'
    ApiErrorV2:
      title: ApiErrorV2
      type: object
      description: Error envelope returned by newer Brale endpoints.
      required:
        - type
      properties:
        type:
          type: string
          description: Machine-readable error type identifier.
          example: automation_not_active
        detail:
          type: string
          description: Human-readable explanation of the error.
          example: Automation must be active to simulate a deposit
        code:
          type: string
          example: ValidationError
        status:
          type: integer
          example: 422
        values:
          type: array
          items:
            type: string
    Amount:
      title: Amount
      type: object
      description: Monetary value with explicit currency
      additionalProperties: false
      properties:
        value:
          type: string
          example: '11234.88'
        currency:
          type: string
          example: USD
      required:
        - value
        - currency
    TransferFailure:
      title: TransferFailure
      type: object
      description: >-
        Structured failure details for a failed transfer. Populated by Brale
        when `status` is `failed` and the underlying rail/provider has supplied
        structured failure details. Field availability varies by rail — for
        example, `ach_return` is only present for ACH returns and `wire_return`
        is only present for outbound wire returns. Do not require rail-specific
        fields for other failure types.
      properties:
        type:
          type: string
          description: >-
            Error classification for the failure, for example `ach_return` or
            `wire_return`.
          example: ach_return
        occurred_at:
          type: string
          format: date-time
          description: >-
            When Brale recorded the failure. This is not necessarily the exact
            time the bank returned the payment.
          example: '2026-04-07T00:05:12.102000Z'
        retriable:
          type: boolean
          description: >-
            Whether the failure is considered retriable. When `true`, Brale may
            automatically retry the underlying operation; when `false`, the
            failure is permanent.
          example: false
        ach_return:
          type: object
          nullable: true
          description: >-
            ACH-only return details. Present for ACH return failures; `null` or
            not set for wire returns, on-chain failures, and other rail
            failures.
          properties:
            code:
              type: string
              description: ACH return code (e.g. `R01` — Insufficient Funds).
              example: R01
            reason:
              type: string
              description: Human-readable description of the ACH return reason.
              example: Insufficient Funds
            category:
              type: string
              description: >-
                Simplified taxonomy of the ACH return. `administrative` covers
                bank issues that may be retriable. `unauthorized` covers
                customer disputes. `general` covers everything else.
              enum:
                - administrative
                - unauthorized
                - general
              example: administrative
        wire_return:
          type: object
          nullable: true
          description: >-
            Wire-only return details. Present when `type` is `wire_return` for a
            returned outbound wire; `null` or not set for other failures. Has no
            `category` field; the ACH return taxonomy does not apply.
          properties:
            code:
              type: string
              description: >-
                The provider's wire return reason code when available (for
                example, `AC04`). When the provider supplies no code, Brale sets
                `WIRE_RETURN`, a Brale fallback marker that is not an ISO 20022
                bank reason code.
              example: AC04
            reason:
              type: string
              nullable: true
              description: Human-readable return reason, when available.
              example: Account closed
    TransferEndpoint:
      title: TransferEndpoint
      description: >-
        One side (source or destination) of a Transfer. The same shape is used
        in create requests and in responses. Response-only fields like
        `transaction_id` and `payment_details` are populated by Brale as the
        underlying leg settles.
      type: object
      properties:
        value_type:
          type: string
          example: USD
        transfer_type:
          type: string
          example: wire
        address_id:
          $ref: '#/components/schemas/Ksuid'
        financial_institution_id:
          type: string
          deprecated: true
          description: Legacy — use `address_id`.
        wire_memo:
          type: string
          description: >-
            Optional memo or payment reference text sent with outbound wire
            transfers. Only applies when `transfer_type` is `wire` on the
            destination leg.
        transaction_id:
          type: string
          description: >-
            On-chain transaction hash or off-chain payment reference. Present in
            responses once the leg has been submitted to the network. Not
            included in create requests.
          example: 0xdd5646ea…
        payment_details:
          $ref: '#/components/schemas/PaymentDetails'
      required:
        - value_type
        - transfer_type
    PaymentDetails:
      title: PaymentDetails
      type: object
      description: >-
        Underlying payment metadata for a transfer leg. Response-only. Appears
        on `source.payment_details` for inbound fiat-funded transfers (wire,
        ACH, and FedNow) and on `destination.payment_details` for outbound wire
        and ACH transfers. Optional and may be absent depending on the rail and
        on whether the underlying bank metadata is available yet. Fields are
        rail-specific. For example, `imad` applies only to wires and
        `trace_number` only to ACH. Do not expect wire or ACH identifiers on
        `fednow_credit` legs.
      properties:
        received_at:
          type: string
          format: date-time
          nullable: true
          description: When the underlying payment was received or posted.
          example: '2026-04-07T00:01:24.514000Z'
        sender_name:
          type: string
          nullable: true
          description: Name of the originating sender, when available.
          example: Originator Name
        sender_bank_name:
          type: string
          nullable: true
          description: Originating bank name, when available.
          example: JPMorgan Chase Bank
        sender_bank_routing_number:
          type: string
          nullable: true
          description: Originating bank routing number, when available.
          example: '000000123'
        payment_reference:
          type: string
          nullable: true
          description: >-
            Sender-provided payment reference or memo, when available. For
            inbound wires, Brale may also populate this field from "Instruction
            for Creditor Agent," which some banks label "Message to receiving
            bank." This fallback is used only when no existing memo,
            Originator-to-Beneficiary Information (OBI), or remittance reference
            is available. Existing reference precedence is preserved.
          example: Simulated Wire
        imad:
          type: string
          nullable: true
          description: Wire IMAD / tracking identifier, when available.
          example: 20260406XOIZJDPP953495
        trace_number:
          type: string
          nullable: true
          description: >-
            ACH trace identifier for the underlying payment, when available.
            Appears on `source.payment_details` for inbound ACH-funded transfers
            and on `destination.payment_details` for outbound ACH transfers
            (`ach_credit` and `same_day_ach_credit`) once the trace number is
            assigned.
          example: '021000029876543'
        sent_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            When the outbound payment was sent, when available. Appears on
            `destination.payment_details` for outbound wire and ACH transfers.
          example: '2026-04-07T00:04:58.000000Z'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >
        Use the Bearer token returned from the Auth endpoint via OAuth2
        client_credentials flow. Include the token in the "Authorization: Bearer
        <token>" header.

````