Send your first transfer
Send your first test transfer, from API keys to a webhook subscription.
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, go to Developers → API Keys. You'll see two key pairs: test (sk_test_...) and live (sk_live_...). Copy the test secret key.
Step 2: Register JWS keys
Money-moving endpoints (create transfer, return transfer, or verify a standardized Mexican bank account number (CLABE)) require each request to be signed. Follow Generate JWS keys to create a keypair and upload the public key. Come back here 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:
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 should look like this:
[
{
"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": "ACME Inc.",
"holder_id": "ND"
}
}
]Using our SDK
If you're using Python or Node, install the Python SDK or Node SDK to call the API. The SDK signs each request with JWS and handles pagination.
First install our SDK:
npm install fintocpip install fintocNow list your accounts:
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);
}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)Keep the id (acc_...) and root_account_number_id (acno_...) from the response. You use root_account_number_id to fund the test Account, and 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:
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:
{
"id": "tr_7HbN2kPq9wZ4xR1s",
"object": "transfer",
"amount": 59013,
"currency": "mxn",
"status": "succeeded",
"direction": "inbound",
"account_number_id": "acno_Kasf91034gj1AD",
"comment": "Simulated inbound transfer"
}
Currencies are represented as integersThe Fintoc API represents money in the smallest currency unit as an integer with no decimals. MXN $590.13 is
59013. CLP has no minor unit, so a transfer of $59,013 CLP is also59013.See Currencies.
More simulation recipes (failures, returns, rejected payouts) live in Test your integration.
Step 5: Send your first Transfer
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": "000000000000000000"
}
}'The response is the outbound Transfer you created:
{
"id": "tr_5pQ8rXcViBnM3kL2",
"object": "transfer",
"amount": 59013,
"currency": "mxn",
"status": "succeeded",
"direction": "outbound",
"comment": "Pago de credito 10451",
"reference_id": "150195",
"counterparty": {
"account_number": "000000000000000000"
}
}Step 6: Create a webhook endpoint
Webhooks notify your server when a transfer settles, so you do not poll for status. Go to Developers → Webhooks in the Dashboard, add your URL, and subscribe to transfer.inbound.succeeded and transfer.outbound.succeeded.
Test the integration
Confirm the full flow worked end to end:
- After Step 4, list your Accounts again and confirm
available_balanceincreased by59013. - Confirm the Step 5 transfer returns
"status": "succeeded". - Confirm your endpoint receives a
transfer.outbound.succeededwebhook for the transfer.