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

# Quick Start

> This quick start guide walks you through creating a recipient and completing your first transfer request.

## Prerequisites

Before you begin, make sure you have:

* An active Hashrails account with API credentials
* A valid **Bearer token**, see [Authentication](/getting-started/authentication) for how to obtain one

This guide walks you through completing your first on-ramp request, from creating a recipient to reconciling the transaction.

<Steps>
  <Step title="Create a recipient">
    Create a recipient to specify where funds should be delivered.

    <CodeGroup>
      ```bash On-ramp (Crypto Recipient) theme={null}
      curl -X POST "https://api.railsfromthecrypt.com/v1/recipients" \
        -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
        -H "Content-Type: application/json" \
        -H "X-Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
        -d '{
          "type": "crypto",
          "name": "My USDT Wallet",
          "wallet_address": "<WALLET_ADDRESS>",
          "network": "Ethereum",
          "symbol": "USDT"
        }'
      ```

      ```bash Off-ramp (Fiat Recipient) theme={null}
      curl -X POST "https://api.railsfromthecrypt.com/v1/recipients" \
        -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
        -H "Content-Type: application/json" \
        -H "X-Idempotency-Key: 660f9511-f30c-52e5-c827-557766551111" \
        -d '{
          "type": "fiat",
          "name": "Acme Ltd",
          "account_number": "0123456789",
          "bank_code": "035",
          "currency": "NGN"
        }'
      ```
    </CodeGroup>

    <Note>
      Include an `X-Idempotency-Key` header with a unique UUID to safely retry requests without creating duplicates. Learn more about [idempotency](/getting-started/rules#idempotency).
    </Note>
  </Step>

  <Step title="Create a transfer request">
    Submit a transfer request to move funds. Specify the source and destination currencies, amount, and the recipient created in the previous step.

    **Request Example**

    <CodeGroup>
      ```bash On-ramp (Fiat → Crypto) theme={null}
      curl -X POST "https://api.railsfromthecrypt.com/v1/transfer-requests" \
        -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
        -H "Content-Type: application/json" \
        -H "X-Idempotency-Key: 7b1f0a2f-2c38-4b67-8ec8-1f9f3d5dd2a1" \
        -d '{
          "type": "onramp",
          "amount": 10000,
          "from_currency": "NGN",
          "to_currency": "USDC",
          "recipient_id": "rec_01J8V9ZP3A7"
        }'
      ```

      ```bash Off-ramp (Crypto → Fiat) theme={null}
      curl -X POST "https://api.railsfromthecrypt.com/v1/transfer-requests" \
        -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
        -H "Content-Type: application/json" \
        -H "X-Idempotency-Key: 8c2g1b3g-3d49-5c78-9fd9-2g0g4e6ee3b2" \
        -d '{
          "type": "offramp",
          "amount": 100,
          "from_currency": "USDC",
          "to_currency": "NGN",
          "recipient_id": "rec_02K9W0AQ4B8",
          "network": "Ethereum"
        }'
      ```
    </CodeGroup>

    **Response Example**

    ```json theme={null}
    {
      "success": true,
      "data": {
        "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
        "reference": "TXN-2Z82FVYO6BW22RC7",
        "type": "onramp",
        "status": "fetching_rates",
        "source": {
          "amount": 10000,
          "currency": "NGN"
        },
        "destination": {
          "amount": 0,
          "currency": "USDC"
        },
        "rate": {
          "value": 0,
          "expires_at": null
        },
        "payment_instructions": {},
        "events": [
          {
            "status": "pending",
            "timestamp": "2025-12-18T08:27:15.056854Z"
          },
          {
            "status": "fetching_rates",
            "timestamp": "2025-12-18T08:27:15.056869Z"
          }
        ],
        "payments": [],
        "created_at": "2025-10-10T09:15:21Z"
      }
    }
    ```
  </Step>

  <Step title="Listen for the rate">
    After creating a transfer request, Hashrails will provide you with our best exchange rate. You'll receive the rate via a webhook event:

    * `transfer_request.rate.received`

    This event contains the updated transfer with the rate and destination amount populated.

    <Warning>
      Alternatively, you can poll `GET /transfer-requests/{id}` to check for the rate, but this is **not recommended**. Webhooks provide real-time updates and reduce unnecessary API calls.
    </Warning>

    For a complete guide on setting up and handling webhooks, see [Webhooks](/getting-started/webhooks).
  </Step>

  <Step title="Confirm or cancel the rate">
    The rate provided is typically valid for up to 30 minutes, though this may vary. The exact expiry time is included in the `rate.expires_at` field of the webhook payload.

    To proceed with the transfer, send a request to the [Confirm Rate](/api-reference/transfer-request/confirm-rate) endpoint and specify the amount you'd like to transfer. The response will include `payment_instructions` with the details needed to complete the payment:

    <CodeGroup>
      ```json On-ramp theme={null}
      {
        "success": true,
        "data": {
          "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
          "status": "awaiting_payment",
          ...
          "payment_instructions": {
            "type": "bank_transfer",
            "bank_transfer": {
              "account_number": "1234567890",
              "account_name": "HashRails Ltd",
              "bank_name": "Wema Bank"
            }
          }
        }
      }
      ```

      ```json Off-ramp theme={null}
      {
        "success": true,
        "data": {
          "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
          "status": "awaiting_payment",
          ...
          "payment_instructions": {
            "type": "crypto_deposit",
            "crypto_deposit": {
              "address": "0xABC123DEF456...",
              "network": "Ethereum",
              "asset": "USDC"
            }
          }
        }
      }
      ```
    </CodeGroup>

    If you'd prefer not to proceed, use the [Cancel Transfer](/api-reference/transfer-request/cancel) endpoint to cancel the request.

    <Note>
      If the rate has expired, you can request a new one by using the [Refresh Quote](/api-reference/transfer-request/refresh-quote) endpoint.
    </Note>
  </Step>

  <Step title="Confirm payment">
    Once payment has been made using the payment instructions, send a request to the [Confirm Payment](/api-reference/transfer-request/confirm) endpoint to acknowledge that the payment has been sent.

    Specify the `payment_type` as either `full` or `split`, along with the `amount` paid.

    <CodeGroup>
      ```bash Full Payment theme={null}
      curl -X POST "https://api.railsfromthecrypt.com/v1/transfer-requests/<TRANSFER_ID>/confirm" \
        -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
        -H "Content-Type: application/json" \
        -H "X-Idempotency-Key: 9d3h2c4h-4e5a-6d89-ae0a-3h1h5f7ff4c3" \
        -d '{
          "payment_type": "full"
        }'
      ```

      ```bash Split Payment theme={null}
      curl -X POST "https://api.railsfromthecrypt.com/v1/transfer-requests/<TRANSFER_ID>/confirm" \
        -H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \
        -H "Content-Type: application/json" \
        -H "X-Idempotency-Key: 0e4i3d5i-5f6b-7e9a-bf1b-4i2i6g8gg5d4" \
        -d '{
          "payment_type": "split",
          "amount": 5000
        }'
      ```
    </CodeGroup>

    Hashrails will verify the payment and notify you via webhook:

    * `transfer_request.payment.received` - payment has been received (for split payments)
    * `transfer_request.payment.completed` - full payment has been confirmed and the transfer is being processed
  </Step>

  <Step title="Track settlement">
    Once payment is confirmed, Hashrails will process the transfer and send the funds to the recipient. You'll be notified of the outcome via webhook:

    * `transfer_request.completed` - the transfer has been settled successfully
    * `transfer_request.cancelled` - the transfer was cancelled

    For full details on all webhook events and how to set them up, see the [Webhooks](/getting-started/webhooks) section.
  </Step>

  <Step title="Reconcile">
    Once the transfer is complete, you can verify the final state and settlement details using the [Get Transactions](/api-reference/transaction/get) endpoint.
  </Step>
</Steps>

## What's next?

You've completed your first transfer request. From here, you can:

* Configure [Webhooks](/getting-started/webhooks) to receive real-time status updates
* Review [API Rules](/getting-started/rules) for rate limits, idempotency, and error handling

## Explore the API

Browse the full [API Reference](/api-reference) to see all available endpoints, request schemas, and response formats.

## Need help?

If you run into any issues or have questions, reach out to our team at [support@hashrails.com](mailto:support@hashrails.com).
