PIX Transfer
Overview
The POST /api/dict/pix endpoint initiates a PIX transfer to the given key. The key can be a CPF, CNPJ, email, phone or EVP (random key).
The synchronous response confirms that the transfer was accepted for processing. The final result (LIQUIDATED or ERROR) arrives through the TRANSFER webhook.
Endpoint
POST https://api.fypay.me/api/dict/pixHeaders
stringobrigatorioBearer token obtained from POST https://api.fypay.me/api/auth/token. This route does not use a client certificate.
stringobrigatorioUnique transfer identifier generated by your system. Up to 50 characters and unique per account (a UUID is a good choice). It becomes the transaction's external identifier and comes back in the endToEndId field of the response and in idempotencyKey of the TRANSFER webhook.
Example: 550e8400-e29b-41d4-a716-446655440000
Request Body
stringobrigatorioDestination PIX key. The type is identified by the format:
- Email: contains
@ - EVP: UUID (random key)
- Phone: with country code, in the format
+55DDDNUMBER(e.g.+5511999999999) - CPF: 11 digits
- CNPJ: 14 digits
stringRecipient CPF or CNPJ. It is forwarded to the settlement provider, and some providers require this document. When omitted, the API uses the digits of the key itself.
stringMessage attached to the PIX transfer. Comes back in data.remittanceInformation in the TRANSFER webhook.
objectobrigatorioPayment data.
stringHIGH or NORM. Accepted for compatibility and validated, but does not change processing.
stringAccepted for compatibility, no effect.
numberBetween 1 and 10800. Accepted for compatibility and validated, but does not change processing.
arrayList of strings. Accepted for compatibility, no effect: the API does not block institutions by ISPB.
Request
curl -X POST https://api.fypay.me/api/dict/pix \
-H "Authorization: Bearer <token>" \
-H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{
"pixKey": "destino@email.com",
"creditorDocument": "12345678909",
"description": "Pagamento referente a NF 12345",
"payment": {
"currency": "BRL",
"amount": 100.50
}
}'const idempotencyKey = crypto.randomUUID();
const response = await fetch('https://api.fypay.me/api/dict/pix', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'x-idempotency-key': idempotencyKey,
'Content-Type': 'application/json',
},
body: JSON.stringify({
pixKey: 'destino@email.com',
creditorDocument: '12345678909',
description: 'Pagamento referente a NF 12345',
payment: {
currency: 'BRL',
amount: 100.50,
},
}),
});
const transfer = await response.json();import requests
import uuid
idempotency_key = str(uuid.uuid4())
response = requests.post(
'https://api.fypay.me/api/dict/pix',
headers={
'Authorization': f'Bearer {token}',
'x-idempotency-key': idempotency_key,
'Content-Type': 'application/json',
},
json={
'pixKey': 'destino@email.com',
'creditorDocument': '12345678909',
'description': 'Pagamento referente a NF 12345',
'payment': {
'currency': 'BRL',
'amount': 100.50,
},
}
)
transfer = response.json()Response
{
"endToEndId": "550e8400-e29b-41d4-a716-446655440000",
"eventDate": "2024-01-15T10:30:00.000Z",
"id": 12345,
"payment": {
"amount": 100.5
},
"type": "PENDING"
}{
"statusCode": 400,
"code": "PIX_INSUFFICIENT_BALANCE",
"userMessage": "Saldo insuficiente para realizar esta operação.",
"details": {
"availableReais": "50.00",
"requiredReais": "100.50"
},
"errorId": "c0a8012e-7b1f-4c55-9d1e-2f9a8c3b4d5e"
}{
"statusCode": 422,
"code": "PIX_KEY_NOT_FOUND",
"details": {
"cached": true,
"retryAfterSeconds": 300
},
"errorId": "c0a8012e-7b1f-4c55-9d1e-2f9a8c3b4d5e"
}Response Fields
endToEndIdstringThis is not the PIX End to End ID. This field returns the value of the x-idempotency-key header. The real End to End ID arrives in data.endToEndId in the TRANSFER webhook.
eventDatestringTransfer creation date and time (ISO 8601).
idnumberTransaction ID at FyPay. Same value as data.id in the TRANSFER webhook.
paymentobjecttypestringTransaction status at response time:
PENDING: transfer being processed (normal case)CONFIRMED: transfer already confirmedERROR: transfer failed
Idempotency
The x-idempotency-key is required and must be unique per account. It protects against double sending: if you reuse a key, no new transfer is created and the API responds 400 with the code PIX_DUPLICATE_EXTERNAL_ID. The details.existingTransactionId field carries the ID of the original transfer.
const key = '550e8400-e29b-41d4-a716-446655440000';
const res1 = await createTransfer(key, { amount: 100 });
const res2 = await createTransfer(key, { amount: 100 });The first call creates the transfer (201, type: "PENDING"). The second is rejected with 400 PIX_DUPLICATE_EXTERNAL_ID, with no debit. To track the result of the first, wait for the TRANSFER webhook or query GET https://api.fypay.me/api/pix/transaction/{id} with the numeric id or with the key itself.
After a 5xx error or a timeout, do not change the key to try again: the payment may have gone out. Wait for the TRANSFER webhook, correlating by data.idempotencyKey. See TRANSFER.
Transfer Webhook
When the transfer is processed, the URLs registered for the cash_out event with the PIX BACEN format receive a TRANSFER webhook (excerpt):
{
"data": {
"id": 12345,
"txId": "550e8400-e29b-41d4-a716-446655440000",
"pixKey": "destino@email.com",
"status": "LIQUIDATED",
"payment": {
"amount": "100.5",
"currency": "BRL"
},
"endToEndId": "E12345678202401151030abcdefghijk",
"creditDebitType": "DEBIT",
"idempotencyKey": "550e8400-e29b-41d4-a716-446655440000",
"creditorAccount": {
"ispb": "12345678",
"name": "João Silva",
"bankName": "Banco Exemplo S.A.",
"issuer": "000",
"number": "123456",
"document": "12345678909",
"accountType": null
},
"remittanceInformation": "Pagamento referente a NF 12345"
},
"type": "TRANSFER"
}TRANSFER Webhook
See the full TRANSFER webhook documentation
Common Errors
| HTTP code | code | Cause | What to do |
|---|---|---|---|
| 400 | PUB_REQUEST_BODY_INVALID | Invalid body (amount missing or below 0.01, priority other than HIGH/NORM etc.) | Check details.violations |
| 400 | PIX_DUPLICATE_EXTERNAL_ID | x-idempotency-key already used on this account | Nothing was created; see details.existingTransactionId |
| 400 | PIX_INSUFFICIENT_BALANCE | Insufficient balance | Check the balance and retry with a new key |
| 401 | Missing, invalid or expired token | Generate a new token | |
| 422 | PIX_KEY_NOT_FOUND | Key does not exist in DICT | Confirm the key with the recipient. With details.cached: true, wait details.retryAfterSeconds. See Non-existent key |
| 429 | TOO_MANY_PIX_KEYS_NOT_FOUND | Too many non-existent keys in key-based payouts | Wait for the time in the Retry-After header. See Provider blocking lookups |