> ## 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 or wire 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 or wire 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`.
</Note>

## 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`. |

## Examples

<CodeGroup>
  ```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"
    }'
  ```
</CodeGroup>

## Response

### 202 Accepted

Returns the standard [Transfer](/key-concepts/transfers) representation. There is no separate simulation resource. The Transfer includes `automation_id`, and `source.transfer_type` matches the requested rail.

```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"
}
```

Fetch the Transfer with [Get a transfer](/api-reference/brale/get-transfer) 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` or `wire` (for example, `rtp`), 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](/key-concepts/idempotency).

* 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](/webhooks/webhook-events) for the simulated inbound payment. There is no simulation-specific webhook type.


## 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—26-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.
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 or wire deposit into a testnet Automation and
        runs the normal Automation mint path. Returns the resulting Transfer.


        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:
              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`
            matches the requested rail.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transfer'
        '400':
          description: |
            Invalid request or schema. Known cases:

            - `transfer_type` is not `ach` or `wire` (for example, `rtp`) —
              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]{26}$
      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.
          enum:
            - ach
            - wire
          example: wire
      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
          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 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 transfers.
      properties:
        type:
          type: string
          description: Error classification for the failure.
          example: ach_return
        occurred_at:
          type: string
          format: date-time
          description: When the failure occurred.
          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; not set
            for on-chain or 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
    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 on `destination.payment_details` for outbound wire transfers.
        Optional and may be absent depending on the rail and on whether the
        underlying bank metadata is available yet.
      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.
          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.
            Primarily relevant for inbound ACH-funded transfers.
          example: '021000029876543'
  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.

````