# How to Withdraw Money from Atlas

Step-by-step guide to sending a bank transfer payout from Atlas, including fetching bank codes, resolving account names, and initiating the transfer via the API.

## Prerequisites

To follow this guide, you need the following:

- A verified Atlas account. If you don't have one, you can [sign up for free](https://atlas-app.tryduplo.com/auth/signup) and follow this guide to [verify your Atlas account](https://docs.tryduplo.com/atlas/guides/compliance).
- An Atlas API Key. You can fetch your API Key from your Atlas dashboard.
- Configured and setup webhooks on Atlas. See our guide on [Configuring and Verifying Atlas webhooks](https://docs.tryduplo.com/atlas/guides/webhooks).

## Initiating a payout

You can initiate a payout using the [Create a Bank Transfer Payout](https://docs.tryduplo.com/atlas/payouts/createPayoutBankTransfer) endpoint. However, this endpoint requires parameters that you need to fetch from other endpoints. The parameters required by the Create a Bank Transfer Payout endpoint are shown below:

### Payout Payload

```
{
  "account_number": string,
  "bank_code": string,
  "bank_name": string,
  "account_name": string,
  "amount": number,
  "narration": string,
  "type": enum,
  "currency": enum,
  "source_reference": string
}
```

The `bank_code` and `account_name` need to be provided by the [List Bank per Currency](https://docs.tryduplo.com/atlas/banking/bankList) endpoint and the [Account Name Enquiry](https://docs.tryduplo.com/atlas/banking/nameEnquiry) endpoint respectively. The `source_reference` is a unique identifier you assign to each payout so you can track it on your own system. You can also use it to fetch the transaction via the [Get Payout by Source Reference](https://docs.tryduplo.com/atlas/payouts/getPayoutTransactionBySourceReference) endpoint.

### Fetching account details

To fetch the account details of the recipient account, first make a GET request to `banking/banks/${currency}` to get the bank code. This endpoint will return all the available banks you can withdraw to. Then filter for your recipient's bank.

For example:

#### JavaScript

```
import axios from "axios";

const api = axios.create({
  baseURL: process.env.API_BASE_URL || "https://atlas.tryduplo.com/api/v1/",
  timeout: 10_000,
});

export async function findBankByName(currency, search) {
  try {
    const res = await api.get(`/banking/bank/${currency}`, {
      headers: {
        Authorization: `Bearer ${process.env.API_TOKEN}`,
      },
    });

const banks = res.data?.data ?? [];

return banks.filter((bank) =>
      bank.bankName.toLowerCase().includes(search.toLowerCase()),
    );
  } catch {
    throw new Error("Unable to fetch bank list");
  }
}
```

With the bank code, you can fetch a validated account name by making a POST request to `banking/name-enquiry` with the recipient's account number and the bank code you fetched.

For example:

#### JavaScript

```
async function resolveAccountName({ accountNumber, bankCode }) {
  try {
    const res = await api.post(
      "/banking/name-enquiry",
      {
        accountNumber,
        bankCode,
      },
      {
        headers: {
          Authorization: `Bearer ${process.env.API_TOKEN}`,
        },
      },
    );

const data = res.data?.data;

return {
      accountName: data.accountName,
      bankCode: data.bankCode,
    };
  } catch {
    throw new Error("Unable to resolve account name");
  }
}
```

With all the details, make a POST request to `payout/bank-transfer` to initiate the payout. For example:

#### JavaScript

```
async function initiateBankTransfer({
  accountNumber,
  bankName,
  amount,
  narration,
  currency = "NGN",
  sourceReference,
}) {
  try {
    // 1. Find bank code
    const banks = await findBankByName(currency, bankName);
    if (!banks.length) {
      throw new Error("Bank not found");
    }

const { bankCode, bankName: resolvedBankName } = banks[0];

// 2. Resolve account name
    const { accountName } = await resolveAccountName({
      accountNumber,
      bankCode,
    });

// 3. Initiate transfer
    const res = await api.post(
      "/payout/bank-transfer",
      {
        account_number: accountNumber,
        bank_code: bankCode,
        bank_name: resolvedBankName,
        account_name: accountName,
        amount,
        narration,
        type: "bank_transfer",
        currency,
        source_reference: sourceReference,
      },
      {
        headers: {
          Authorization: `Bearer ${process.env.API_TOKEN}`,
          "Content-Type": "application/json",
        },
      },
    );

return res.data;
  } catch {
    throw new Error("Unable to complete bank transfer");
  }
}
```

On a successful payout, you will receive a response similar to the one below:

### JSON

```
{
  "requestId": "96d34fbb-0589-492f-b621-f8fb8b649f8c",
  "requestTimestamp": "2026-03-21 11:13:56.980",
  "message": "Payout initiated successfully.",
  "statusCode": 200,
  "data": {
    "id": "019d1019-f9b3-70d2-be9f-cef3ec5b4566",
    "recipientAccountName": "Test user",
    "recipientAccountNumber": "2018054387",
    "recipientBankName": "Kuda Microfinance Bank",
    "sourceReference": "7f436fb1-f04e-43e7-b376-13f62d129805",
    "paymentChannel": "Bank Transfer",
    "sessionId": null,
    "parentTransactionReference": null,
    "reference": "TRN_QELKDOVYYCFV",
    "amount": {
      "value": 100,
      "currency": "NGN",
      "formatted": "NGN100"
    },
    "balance": {
      "value": 316,
      "currency": "NGN",
      "formatted": "NGN316"
    },
    "status": "Pending",
    "narration": "Test Payout",
    "createdAt": "2026-03-21 12:13:51",
    "fee": [
      {
        "id": "019d1019-ff2c-70fb-af1c-6004b6d67dcb",
        "recipientAccountName": "-",
        "recipientAccountNumber": "-",
        "recipientBankName": "Master Wallet",
        "sourceReference": "7f436fb1-f04e-43e7-b376-13f62d129805",
        "paymentChannel": "Fees",
        "sessionId": null,
        "parentTransactionReference": "TRN_QELKDOVYYCFV",
        "reference": "TRN_KLXCE8TGZ0QS",
        "amount": {
          "value": 10,
          "currency": "NGN",
          "formatted": "NGN10"
        },
        "balance": {
          "value": 306,
          "currency": "NGN",
          "formatted": "NGN306"
        },
        "status": "Pending",
        "narration": "Test Payout",
        "createdAt": "2026-03-21 12:13:53"
      }
    ]
  }
}
```

You will also receive a webhook with an [`OUT_FLOW_PENDING_EVENT`](https://docs.tryduplo.com/atlas/guides/webhooks#webhook-events) event type to confirm that the transaction has been initiated and on completion an `OUT_FLOW_SUCCESS_EVENT` event to confirm that the transaction has been completed on our end. If the payout fails due to unforeseen circumstances, you will receive an `OUT_FLOW_FAILED_EVENT` event.
