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

# Send your first transfer

> Send your first Fintoc test transfer end to end, from generating API keys to subscribing to webhook events, using the Business Accounts API sandbox environment.

By the end, you will have signed your requests with a JSON Web Signature (JWS), funded a test `Account`, and sent your first `Transfer`.

## Step 1: Get your test API keys

In the [dashboard](https://dashboard.fintoc.com/), go to **Developers → API Keys**. You'll see keys for `test` (`sk_test_...`) and `live` (`sk_live_...`) modes. Copy the `test` secret key.

## Step 2: Register JWS keys

Money-moving endpoints require signed requests. These endpoints create transfers, return transfers, or verify a standardized Mexican bank account number. Follow [Generate JWS keys](/guides/business-accounts/setup/setting-up-jws-keys) to create a key pair and upload the public key. Return to this page when you're done.

## Step 3: List your accounts

Every organization starts with a root `Account`. Fetch it with a `GET` request to `/v2/accounts`:

```bash cURL theme={null}
curl --request GET \
     --url https://api.fintoc.com/v2/accounts \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json'
```

The response looks like this:

```json JSON theme={null}
[
  {
    "id": "acc_23JlasHas241",
    "object": "account",
    "mode": "test",
    "description": "My root account",
    "root_account_number": "000000000000000000",
    "root_account_number_id": "acno_Kasf91034gj1AD",
    "available_balance": 0,
    "currency": "MXN",
    "entity": {
      "id": "ent_4324qwkalsds",
      "holder_name": "Test Entity 1",
      "holder_id": "ND"
    }
  }
]
```

### Use an SDK

If you're using Node or Python, install the [Node SDK](https://github.com/fintoc-com/fintoc-node) or [Python SDK](https://github.com/fintoc-com/fintoc-python) to call the API. The SDK signs each request with [JWS](/guides/business-accounts/setup/setting-up-jws-keys) and handles pagination.

Install an SDK:

<CodeGroup>
  ```bash Install Node SDK theme={null}
  npm install fintoc
  ```

  ```bash Install Python SDK theme={null}
  pip install fintoc
  ```
</CodeGroup>

List your accounts:

<CodeGroup>
  ```javascript Node theme={null}
  const { Fintoc } = require('fintoc');

  // You can provide a path to your PEM file or pass the PEM key directly as a string.
  // const privateKey = process.env.JWS_PRIVATE_KEY;
  const privateKey = './private_key.pem';

  const fintoc = new Fintoc('YOUR_TEST_SECRET_KEY', privateKey);

  const accounts = await fintoc.v2.accounts.list();
  for await (const account of accounts) {
    console.log(account.id, account.description, account.root_account_number, account.available_balance);
  }
  ```

  ```python Python theme={null}
  from fintoc import Fintoc

  # You can provide a path to your PEM file or pass the PEM key directly as a string.
  # jws_private_key = os.environ.get('JWS_PRIVATE_KEY')
  jws_private_key = "./private_key.pem"

  client = Fintoc("YOUR_TEST_SECRET_KEY", jws_private_key=jws_private_key)

  for account in client.v2.accounts.list():
      print(account.id, account.description, account.root_account_number, account.available_balance)
  ```
</CodeGroup>

Keep the `id` (`acc_...`) and `root_account_number_id` (`acno_...`) from the response. Use `root_account_number_id` to fund the test `Account`. Use `id` to create the outbound `Transfer`.

## Step 4: Fund your test account

Your test Account starts empty. Simulate an inbound transfer so you have money to send:

```bash cURL theme={null}
curl --request POST \
     --url https://api.fintoc.com/v2/simulate/receive_transfer \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "account_number_id": "acno_Kasf91034gj1AD",
  "amount": 59013,
  "currency": "MXN"
}
'
```

The response is the simulated inbound `Transfer` that funds your `Account`:

```json JSON theme={null}
{
  "id": "tr_7HbN2kPq9wZ4xR1s",
  "object": "transfer",
  "amount": 59013,
  "currency": "MXN",
  "status": "succeeded",
  "direction": "inbound",
  "account_number_id": "acno_Kasf91034gj1AD",
  "comment": "Simulated inbound transfer"
}
```

<Warning>
  **Currencies are represented as integers**

  The Fintoc API represents money in the smallest currency unit as an integer with no decimals. An amount of \$590.13 MXN is `59013`. CLP has no minor unit, so an amount of \$59,013 CLP is also `59013`.

  See [Currencies](/guides/home/currencies).
</Warning>

See [Test your integration](/guides/business-accounts/setup/test-your-integration) for simulations of failures, returns, and rejected payouts.

## Step 5: Send your first transfer

Create an outbound `Transfer` from the test `Account` you funded.

```bash cURL theme={null}
curl --request POST \
     --url https://api.fintoc.com/v2/transfers \
     --header 'Authorization: YOUR_TEST_SECRET_KEY' \
     --header 'Fintoc-JWS-Signature: YOUR_JWS_SIGNATURE' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
{
  "amount": 59013,
  "currency": "MXN",
  "account_id": "acc_23JlasHas241",
  "comment": "Pago de credito 10451",
  "reference_id": "150195",
  "counterparty": {
    "account_number": "012000000000000001"
  }
}'
```

The response is the outbound `Transfer` you created:

```json JSON theme={null}
{
  "id": "tr_5pQ8rXcViBnM3kL2",
  "object": "transfer",
  "amount": 59013,
  "currency": "MXN",
  "status": "succeeded",
  "direction": "outbound",
  "comment": "Pago de credito 10451",
  "reference_id": "150195",
  "counterparty": {
    "account_number": "012000000000000001"
  }
}
```

## Step 6: Create a webhook endpoint

Webhooks notify your server when a transfer settles, so you don't need to poll for status. Go to **Developers → Webhooks** in the dashboard. Add your URL, then subscribe to `transfer.inbound.succeeded` and `transfer.outbound.succeeded`.

## Test the integration

Confirm the full flow worked end to end:

1. After Step 4, list your accounts again and confirm `available_balance` increased by `59013`.
2. Confirm the Step 5 transfer returns `"status": "succeeded"`.
3. After Step 6, repeat Steps 4 and 5. Confirm your endpoint receives a `transfer.outbound.succeeded` webhook for the new outbound transfer.
