> ## Documentation Index
> Fetch the complete documentation index at: https://rain-sandbox-trial.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Onramps

> Enable users to onramp fiat into crypto using payment routes with virtual accounts for ACH and wire transfers.

<Info>
  **Endpoint Migration**

  The `/v1/automations` endpoints have been renamed to `/v1/payment-routes`. The old `/v1/automations` paths remain available as deprecated aliases during migration. Update your integrations to use `/v1/payment-routes` as the deprecated endpoints will be removed in a future release.
</Info>

## Overview

Onramps let your users convert fiat to stablecoin through a persistent payment route. When you create an onramp payment route, Rain generates a virtual account with unique banking credentials. Any funds sent to that virtual account are automatically converted to the destination stablecoin and delivered to the destination onchain address.

<Info>
  If you're funding a Rain-Managed program's collateral contract specifically,
  Rain also offers a [dedicated onramp flow](/docs/onramps-rain-contract) built
  on the contracts API, which returns ACH, RTP, and wire details together
  instead of a single virtual account.
</Info>

## Before you begin

Make sure you have:

* **API access** to the payment routes endpoints.
* **A destination address:** an onchain wallet address where converted stablecoin is delivered. This can be a Rain smart contract or an external wallet.
* **A US bank account:** your end users need one to initiate fiat transfers.

## Restrictions

Onramp payment routes are subject to the same [restrictions &
availability](/docs/restrictions-and-availability) rules as any other payment
route, plus Rain's [Payments compliance](/docs/payments-compliance) checks.

## Key concepts

### Payment routes

A payment route creates a persistent pipe between a source and destination. For onramps:

* **Source:** fiat via ACH or wire transfer.
* **Destination:** an onchain address on a supported chain.

When you create an onramp payment route, Rain generates a `depositAddress` containing virtual account banking credentials. This virtual account acts as the named beneficiary for incoming fiat transfers. See [What a payment route is](/docs/payment-routes#what-a-payment-route-is) for how Rain determines direction for both onramps and offramps.

### Virtual accounts

Virtual accounts are dedicated banking credentials that Rain generates for receiving fiat transfers, not payment accounts you register yourself. Each onramp payment route generates its own virtual account, giving your users unique ACH and wire transfer details.

### First-party and third-party transfers

Virtual accounts support both first-party and third-party incoming transfers:

* **First-party:** the user who owns the payment route sends funds from their own bank account.
* **Third-party:** a different party sends funds to the virtual account on behalf of the user, for example an employer funding an employee's account.

## API flow

<div className="wf-diagram">
  <div className="legend">
    <span className="lg"><span className="swatch action" />Action / API call</span>
    <span className="lg"><span className="swatch ext" />External / user</span>
    <span className="lg"><span className="swatch send" />Webhook Rain sends you</span>
  </div>

  <div className="diagram-shell borderless">
    <svg id="onramp-api-flow" role="img" aria-label="Onramp: the user requests banking details, the partner creates a payment route and shares the virtual account, the user sends an ACH or wire transfer, Rain converts it to stablecoin and deposits it onchain, then sends a transactionTransfer webhook." viewBox="0 0 1080 976" width="1080" height="976" style={{width: "100%", height: "auto"}}><defs><marker id="arrow-onramp-api-flow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" className="marker-fill-default" /></marker><marker id="arrowSend-onramp-api-flow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="7" markerHeight="7" orient="auto-start-reverse"><path d="M0,0 L10,5 L0,10 z" className="marker-fill-send" /></marker></defs><path d="M 540 164 L 540 204" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow-onramp-api-flow)" opacity="0.92" /><path d="M 540 272 L 540 312" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow-onramp-api-flow)" opacity="0.92" /><path d="M 540 380 L 540 420" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow-onramp-api-flow)" opacity="0.92" /><path d="M 540 488 L 540 528" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow-onramp-api-flow)" opacity="0.92" /><path d="M 540 596 L 540 636" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow-onramp-api-flow)" opacity="0.92" /><path d="M 540 704 L 540 744" fill="none" className="conn-default" stroke-width="1.7" marker-end="url(#arrow-onramp-api-flow)" opacity="0.92" /><path d="M 540 812 L 540 852" fill="none" className="conn-send" stroke-width="1.7" marker-end="url(#arrowSend-onramp-api-flow)" opacity="0.92" /><foreignObject x="320" y="96" width="440" height="68"><div className="card action"><span className="ct"><span className="tag">User</span><span className="lab">Requests banking details</span></span></div></foreignObject><foreignObject x="320" y="204" width="440" height="68"><div className="card action"><span className="bn">1</span><span className="ct"><span className="tag">Partner</span><span className="lab mono">POST /payment-routes</span></span></div></foreignObject><foreignObject x="320" y="312" width="440" height="68"><div className="card action"><span className="bn">2</span><span className="ct"><span className="tag rain">Rain</span><span className="lab">Returns route with depositAddress</span></span></div></foreignObject><foreignObject x="320" y="420" width="440" height="68"><div className="card action"><span className="bn">3</span><span className="ct"><span className="tag">Partner</span><span className="lab">Provides virtual account details</span></span></div></foreignObject><foreignObject x="320" y="528" width="440" height="68"><div className="card ext"><span className="bn">4</span><span className="ct"><span className="tag">User</span><span className="lab">Sends ACH/wire transfer</span></span></div></foreignObject><foreignObject x="320" y="636" width="440" height="68"><div className="card action"><span className="bn">5</span><span className="ct"><span className="tag rain">Rain</span><span className="lab">Converts to stablecoin</span></span></div></foreignObject><foreignObject x="320" y="744" width="440" height="68"><div className="card ext"><span className="bn">6</span><span className="ct"><span className="tag">Destination</span><span className="lab">Receives stablecoin deposit</span></span></div></foreignObject><foreignObject x="320" y="852" width="440" height="68"><div className="card send"><span className="bn">7</span><span className="ct"><span className="tag">Webhook</span><span className="lab mono">transactionTransfer</span></span></div></foreignObject></svg>
  </div>
</div>

The steps above, in text:

| # | Actor       | Step                                                                                     |
| - | ----------- | ---------------------------------------------------------------------------------------- |
| – | User        | Requests banking details from the partner                                                |
| 1 | Partner     | Calls `POST /payment-routes`                                                             |
| 2 | Rain        | Returns the route with a `depositAddress`                                                |
| 3 | Partner     | Provides the virtual account details to the user                                         |
| 4 | User        | Sends an ACH or wire transfer to the virtual account                                     |
| 5 | Rain        | Converts the fiat to stablecoin                                                          |
| 6 | Destination | Receives the stablecoin deposit onchain                                                  |
| 7 | Rain        | Sends a [`transactionTransfer`](/docs/transaction#transactiontransfer-completed) webhook |

## Create an onramp payment route

To create an onramp payment route, call `POST /payment-routes` with a fiat
`source` and an onchain `destination`. See [Create an onramp payment
route](/docs/payment-routes#create-an-onramp-payment-route) for the full
request, response, and field reference; the shape is identical for onramps
created from this page.

<Info>
  **Destination address format**

  The destination address must match the expected format for the destination rail:

  * **EVM chains** (Ethereum, Base, Polygon, Arbitrum, Optimism, Avalanche, Celo): must be a valid EVM address starting with `0x` followed by 40 hexadecimal characters (for example, `0x1234567890abcdef1234567890abcdef12345678`).
  * **Solana:** must be a valid Solana address in base58 format (32-44 characters).

  If the address doesn't match the destination rail format, the request fails.
</Info>

## Manage payment routes

Use `GET /payment-routes`, `GET /payment-routes/{paymentRouteId}`, and
`DELETE /payment-routes/{paymentRouteId}` to list, retrieve, and remove
onramp payment routes. See [Manage payment
routes](/docs/payment-routes#manage-payment-routes) for the full request
and response examples.

<Warning>
  Deleting a payment route invalidates the associated virtual account. Any
  subsequent transfers to those banking credentials fail. Notify your users
  before deleting a payment route.
</Warning>

## What happens when funds are received

When a user sends funds to the virtual account:

1. **Funds received:** Rain receives the fiat transfer at the virtual account. Deposits under \$2.00 don't create a transfer.
2. **Transfer created:** Rain creates a transaction of type `transfer` and sends a `transactionTransfer` webhook with action `created`.
3. **Conversion:** Rain automatically converts funds to the destination stablecoin.
4. **Transfer:** Rain sends stablecoin to the destination onchain address.
5. **Transfer completed:** the transfer reaches a final state, and Rain sends a `transactionTransfer` webhook with action `completed`.

### Webhooks

Rain sends webhooks through the transfer lifecycle:

| Resource              | Action      | Description                                                  |
| --------------------- | ----------- | ------------------------------------------------------------ |
| `transactionTransfer` | `created`   | Sent when the transfer is initiated after funds are received |
| `transactionTransfer` | `updated`   | Sent when the transfer's status changes during processing    |
| `transactionTransfer` | `completed` | Sent when the transfer settles and crypto is delivered       |

See the [transfer object reference](/docs/transaction#transfer-object-reference) for the full webhook payload schema.

### Transfer transaction

Each successful onramp creates a `transfer` transaction that you can query via
the [Transactions API](/reference/transactions/get-all-transactions). Filter
by `type=transfer` to see all transfer transactions:

```bash theme={null}
curl -X GET "https://api.rain.xyz/v1/issuing/transactions?type=transfer" \
  -H "Api-Key: YOUR_API_KEY"
```

Example transfer transaction response:

```json theme={null}
{
  "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
  "type": "transfer",
  "transfer": {
    "source": {
      "amount": "100.00",
      "currency": "usd",
      "rail": "ach"
    },
    "destination": {
      "amount": "99.50",
      "currency": "usdc",
      "rail": "base",
      "address": {
        "type": "onchain",
        "address": "0x1234567890abcdef1234567890abcdef12345678"
      }
    },
    "depositAddress": {
      "type": "fiat",
      "beneficiaryName": "JOHN DOE",
      "beneficiaryAddress": "123 Main St, Austin, TX 78701, US",
      "beneficiaryBankName": "Partner Bank, N.A.",
      "beneficiaryBankAddress": "456 Bank Ave, New York, NY 10002, US",
      "accountNumber": "9876543210",
      "routingNumber": "021000021"
    },
    "exchangeRate": 1.0,
    "status": "settled",
    "createdAt": "2025-01-15T10:30:00Z",
    "updatedAt": "2025-01-15T10:45:00Z"
  }
}
```

To list the transfer transactions for a specific user, see [Viewing Transactions](/docs/viewing-transactions).

### Settlement times

Transfer times vary by rail:

| Rail | Typical settlement |
| ---- | ------------------ |
| ACH  | 1-3 business days  |
| Wire | Same business day  |

After fiat settlement, the conversion and onchain transfer typically complete within minutes.

### Cutoff times

Fiat transfer processing is subject to banking cutoff times. Transfers received after the cutoff are processed on the next business day.

| Rail           | Cutoff Time | Notes                                                                     |
| -------------- | ----------- | ------------------------------------------------------------------------- |
| ACH (Same-Day) | 4:00 PM ET  | Transfers submitted after this cutoff are processed the next business day |
| Wire (Fedwire) | 5:45 PM ET  | Transfers submitted after this cutoff are processed the next business day |

<Info>
  Cutoff times apply on US business days only. Transfers initiated on weekends
  or US federal holidays are processed on the next business day.
</Info>

## Supported configurations

### Source (fiat)

| Currency | Rails     |
| -------- | --------- |
| USD      | ACH, Wire |

### Destination (crypto)

| Currency | Rails (Chains)                                                       |
| -------- | -------------------------------------------------------------------- |
| USDC     | Ethereum, Base, Polygon, Arbitrum, Optimism, Avalanche, Celo, Solana |
| RUSD     | Ethereum, Base, Polygon, Arbitrum, Optimism, Avalanche, Celo, Solana |

<Info>
  Rain regularly adds additional currencies and chains. Contact your Rain
  representative for the latest supported configurations.
</Info>

## Error handling

Common error scenarios when creating a payment route:

| Error                         | Description                                                  | Resolution                                            |
| ----------------------------- | ------------------------------------------------------------ | ----------------------------------------------------- |
| `invalid_destination_address` | The destination address format doesn't match the rail        | Use an EVM address for EVM rails or Solana for Solana |
| `unsupported_currency_pair`   | The source/destination currency combination is not supported | Check supported configurations above                  |
| `unsupported_rail`            | The specified rail is not available                          | Use a supported rail for the currency                 |

## Best practices

1. **Monitor webhooks:** set up webhook handlers to track transfer status in real time instead of polling.
2. **Handle failures gracefully:** fiat transfers can fail due to bank issues on the sender's side. Implement retry logic and user notifications.
3. **Validate destination addresses client-side:** catch malformed onchain addresses before calling `POST /payment-routes` to avoid a round trip on an avoidable error.

## What's next

<Columns cols={2}>
  <Card title="Payment routes" icon="route" href="/docs/payment-routes">
    See the full request, response, and field reference shared by onramps and offramps.
  </Card>

  <Card title="Set up offramps" icon="arrow-up-from-line" href="/docs/offramps">
    Enable fiat withdrawals from crypto.
  </Card>

  <Card title="Onramp to Rain Contract" icon="file-contract" href="/docs/onramps-rain-contract">
    Fund a Rain-Managed program's collateral contract directly instead.
  </Card>

  <Card title="Set up webhooks" icon="bell" href="/docs/webhooks">
    Receive transfer notifications as they happen.
  </Card>
</Columns>
