Execution Tracking
Broker operations are asynchronous: order execution, withdraw processing, deposit confirmation, and holding income all complete outside the request/response cycle. Persist operation IDs at creation time, consume webhooks idempotently, and reconcile periodically with GET endpoints.
Webhook configuration
Configure notifications on your company via PUT /broker/v1/api/company, in one of two modes:
generalWebhook— a single endpoint that receives every event.- Per-event webhooks — a distinct endpoint per event type.
A secret is configured in both cases; it is used to generate an HMAC SHA-256 signature so you can verify each message.
{
"notificationInfo": {
"type": "WEBHOOK",
"secret": "mysupersecret",
"generalWebhook": "https://your-domain.com/webhooks/manteca"
}
}Endpoint requirements: accepts POST, responds 2xx in under 10 seconds, HTTPS only, and idempotent (retries deliver the same payload).
Event catalog
| Event | Trigger |
|---|---|
user-status-update | User status changes (onboarding, KYC, etc.). |
documentation-status-update | A document changes status (DNI, selfie, etc.). |
deposit-status-update | A deposit changes status. |
order-status-update | An order changes status (includes FCI subscribe/redeem). |
synthetic-status-update | A synthetic (e.g. Dólar MEP) changes status. |
withdraw-status-update | A withdrawal changes status. |
holding-income-status-update | Dividend/holding income payment. |
user-balance-update | A user's balance changes. |
Payload examples
Every delivery is a JSON body with eventName and data. data.status carries the new status, alongside the full entity snapshot.
user-status-update
{
"eventName": "user-status-update",
"data": {
"status": "USER_DATA_COMPLETE",
"user": {
"id": "66b234d668e708c917d3c5ae",
"numberId": "10530",
"companyId": "658dd9502accccd05acc3ce9",
"externalId": "1a233b06-13be-43fb-b195-3c22e930a376",
"email": "[email protected]",
"legalId": "20123456786",
"type": "INDIVIDUAL",
"status": "USER_DATA_COMPLETE",
"banking": {
"accounts": [
{
"bank": { "code": "123", "name": "Banco Ejemplo" },
"cbu": "alias.alias",
"currency": "ARS",
"description": "Optional description",
"virtual": false
}
]
},
"creationTime": "2024-08-06T11:36:06.177-03:00",
"updatedAt": "2024-08-06T11:36:15.215-03:00"
}
}
}documentation-status-update
{
"eventName": "documentation-status-update",
"data": {
"status": "PENDING",
"documentation": {
"id": "66b2358c68e708c917d3c5d9",
"associatedId": "20123456786",
"associatedSubId": "10530",
"docType": "DNI_FRONT",
"status": "PENDING",
"valid": false,
"seen": false,
"details": {
"name": "Juan",
"surname": "PEREZ",
"dniNumber": "12345678",
"dniModel": "A",
"birthDate": "1982-11-06T15:00:00.000Z",
"isDead": false
},
"history": [
{ "date": "2024-08-06T11:39:08.012-03:00", "newStatus": "PENDING" }
],
"imgSrc": "https://s3.sa-east-1.amazonaws.com/.../front.jpg"
}
}
}deposit-status-update
{
"eventName": "deposit-status-update",
"data": {
"status": "ASSIGNED",
"deposit": {
"id": "66b2362f68e708c917d3c618",
"userId": "66b234d668e708c917d3c5ae",
"companyId": "658dd9502accccd05acc3ce9",
"legalId": "20123456786",
"numberId": "10530",
"amount": 1000000,
"coin": "ARS",
"status": "ASSIGNED",
"creationTime": "2024-08-06T11:41:51.418-03:00",
"updatedAt": "2024-08-06T11:41:51.418-03:00"
},
"payload": { "new": true }
}
}Deposits must come from a bank account owned by the same person (same CUIT/CUIL). The flow is: the bank notifies the deposit, it is matched against a user able to receive it, and on success the funds are credited to the user's balance. If the person has users at more than one company, a Manteca administrator assigns the deposit to the right company.
order-status-update
{
"eventName": "order-status-update",
"data": {
"status": "COMPLETED",
"order": {
"id": "66ede4018354e33f0f6b21da",
"userId": "66b234d668e708c917d3c5ae",
"companyId": "658dd9502accccd05acc3ce9",
"legalId": "20123456786",
"numberId": "10530",
"externalId": "693cacbe-da94-4adc-af41-056028f988ae",
"asset": "AL30",
"against": "ARS",
"side": "BUY",
"type": "MARKET",
"settlement": "INSTANT",
"amount": 5,
"filledAmount": 5,
"price": 62880,
"priceUsd": 24,
"fee": 0.00261,
"feeInfo": {
"companyProfit": "0.0000000000",
"earningsWithholding": "0",
"holdingIncomeFee": "0",
"marketRight": "0.0001",
"platformFee": "0.0025100000",
"totalFee": "0.0026100000",
"usesIva": false
},
"finalClaimInfo": {
"asset": "ARS",
"base": 3144,
"companyProfit": 0,
"earningsWithholding": 0,
"holdingIncomeFee": 0,
"iva": 0,
"marketRight": 0.31,
"platformFee": 7.89,
"totalFees": 8.2,
"total": 3152.2
},
"finalCreditInfo": {
"asset": "AL30",
"base": 5,
"companyProfit": 0,
"earningsWithholding": 0,
"holdingIncomeFee": 0,
"iva": 0,
"marketRight": 0,
"platformFee": 0,
"totalFees": 0,
"total": 5
},
"history": [
{
"newStatus": "PENDING",
"claimedAmount": 3152.22,
"price": 62880,
"stepAmount": 5,
"timestamp": "2024-09-20T18:07:13.233-03:00"
},
{
"newStatus": "SENT",
"price": 62880,
"stepAmount": 4,
"timestamp": "2024-09-20T18:07:16.449-03:00"
},
{
"newStatus": "COMPLETED",
"price": 62880,
"stepAmount": 1,
"timestamp": "2024-09-20T18:07:19.445-03:00"
},
{
"creditedAmount": 5,
"refundedAmount": 0.02,
"timestamp": "2024-09-20T18:07:19.634-03:00"
}
],
"status": "COMPLETED",
"creationTime": "2024-09-20T18:07:13.325-03:00",
"updatedAt": "2024-09-20T18:07:19.641-03:00"
}
}
}FCI subscriptions and redemptions arrive through this same event, with the fund as asset (e.g. "asset": "FSTPESA"), side BUY (subscribe) or SELL (redeem), and statuses like PENDING_EXECUTION plus an executionTime for the fund's cut-off.
synthetic-status-update
{
"eventName": "synthetic-status-update",
"data": {
"status": "ACTIVE",
"synthetic": {
"id": "66b236af68e708c917d3c661",
"userId": "66b234d668e708c917d3c5ae",
"companyId": "658dd9502accccd05acc3ce9",
"legalId": "20123456786",
"numberId": "10530",
"externalId": "15e897d8-0dc2-4f30-a0bc-daa66d7ebb37",
"type": "DOLAR_MEP",
"status": "ACTIVE",
"currentStage": 1,
"details": {
"side": "BUY",
"amount": 10000,
"operatedAmount": 9456.63,
"expectedAmount": 3.59,
"settlement": "INSTANT"
},
"fee": 0.00522,
"stages": {
"1": {
"asset": "AL30",
"against": "ARS",
"side": "BUY",
"type": "MARKET",
"amount": 15,
"settlement": "INSTANT",
"orderId": "66b236af68e708c917d3c66d",
"executionTime": "2024-08-06T11:43:59.644-03:00",
"feeInfo": {
"companyProfit": "0.0000000000",
"earningsWithholding": "0",
"holdingIncomeFee": "0",
"marketRight": "0.0001",
"platformFee": "0.0025100000",
"totalFee": "0.0026100000",
"usesIva": false
}
},
"2": {
"asset": "AL30",
"against": "USD",
"side": "SELL",
"type": "MARKET",
"amount": 15,
"settlement": "INSTANT",
"executionTime": "2024-08-07T11:10:00.000-03:00",
"feeInfo": {
"companyProfit": "0.0000000000",
"earningsWithholding": "0",
"holdingIncomeFee": "0",
"marketRight": "0.0001",
"platformFee": "0.0025100000",
"totalFee": "0.0026100000",
"usesIva": false
}
}
},
"creationTime": "2024-08-06T11:43:59.647-03:00",
"updatedAt": "2024-08-06T11:43:59.905-03:00"
}
}
}withdraw-status-update
{
"eventName": "withdraw-status-update",
"data": {
"status": "PENDING",
"withdraw": {
"id": "66b2370368e708c917d3c68d",
"withdrawNumberId": "113",
"userId": "66b234d668e708c917d3c5ae",
"companyId": "658dd9502accccd05acc3ce9",
"legalId": "20123456786",
"numberId": "10530",
"externalId": "b6ac7635-0167-4479-b5c5-62e4d24e05cf",
"amount": 1000,
"coin": "ARS",
"destAccount": {
"bank": { "code": "123", "name": "Banco Ejemplo" },
"cbu": "alias.alias",
"currency": "ARS",
"description": "Optional description",
"virtual": false
},
"history": [
{ "newStatus": "PENDING", "timestamp": "2024-08-06T11:45:23.626-03:00" }
],
"status": "PENDING",
"creationTime": "2024-08-06T11:45:23.626-03:00",
"updatedAt": "2024-08-06T11:45:23.626-03:00"
},
"payload": { "new": true }
}
}Withdrawal statuses:
| Status | Description |
|---|---|
PENDING | Transfer initiated with the bank. |
PENDING_ADMIN | Awaiting administrator approval. |
PENDING_EXECUTION | Scheduled to be processed at the defined time. |
PROCESSING | In flight at the bank; awaiting a response. |
FAILED | Failed at the bank; needs manual review by an administrator. |
RETRIED | Was failed and an administrator created a new one to be executed shortly. |
EXECUTED | Money sent successfully. |
CANCELLED | Cancelled by the user or an administrator. |
holding-income-status-update
{
"eventName": "holding-income-status-update",
"data": {
"status": "PAID",
"holdingIncome": {
"id": "670d520139fa58ae89294c1b",
"userId": "65cfadf9da953feea0e29400",
"companyId": "658dd9502accccd05acc3ce9",
"legalId": "20123456786",
"numberId": "10442",
"asset": "GD30",
"incomeAsset": "USD",
"type": "BOND",
"amount": 5,
"settlement": "INSTANT",
"finalClaimInfo": {
"asset": "ARS",
"base": 0,
"companyProfit": 0,
"earningsWithholding": 0,
"holdingIncomeFee": 99,
"iva": 20.79,
"marketRight": 4.58,
"platformFee": 0,
"totalFees": 124.37,
"total": 124.37
},
"finalCreditInfo": {
"asset": "USD",
"base": 5,
"companyProfit": 0,
"earningsWithholding": 0,
"holdingIncomeFee": 0,
"iva": 0,
"marketRight": 0,
"platformFee": 0,
"totalFees": 0,
"total": 5
},
"status": "PAID",
"creationTime": "2024-10-14T14:16:49.168-03:00",
"updatedAt": "2024-10-14T14:16:49.283-03:00"
}
}
}user-balance-update
{
"eventName": "user-balance-update",
"data": {
"userId": "65cfadf9da953feea0e29400",
"companyId": "658dd9502accccd05acc3ce9",
"balance": {
"AL30": "0",
"ARS": "2318066.35",
"USD": "1011.07"
},
"pendingBalance": {
"MGCHO": "1218"
},
"slips": [
{
"id": "6817cfde06aa5ccbb329a105",
"userId": "65cfadf9da953feea0e29400",
"asset": "MGCHO",
"amount": "1218",
"settlement": "DAY",
"settlementTime": "2025-05-06T11:00:00.000-03:00"
}
],
"nonManaged": [],
"creationTime": "2025-01-22T11:08:21.888-03:00",
"updatedAt": "2025-05-05T22:37:24.831-03:00"
}
}Signature verification
The signature travels in the md-webhook-signature header. It is an HMAC SHA-256 over the JSON body, using the configured secret.
import crypto from 'crypto';
export const verifyWebhookSignature = (body: any, header: string, secret: string): boolean => {
const dataString = JSON.stringify(body);
const hmac = crypto.createHmac('sha256', secret);
const signature = hmac.update(dataString, 'utf8').digest('hex');
return header === signature;
};Key order matters. The signed payload is serialized with object keys sorted alphabetically. If your re-serialization doesn't preserve that order, the signatures won't match — you can use a stable stringifier such as
fast-json-stable-stringify.
Source IPs. All webhooks originate from one of these IPs (same in sandbox and production). Whitelist all of them:
18.229.68.94·15.229.180.233·177.71.146.43·18.230.111.80
Retry policy
If your endpoint responds non-2xx or does not respond within 10 seconds, Manteca retries with exponential backoff. After 8 failed retries delivery is abandoned.
| Attempt | Delay vs. previous | Cumulative |
|---|---|---|
| 1 (initial) | — | 0 min |
| 2 | 2 min | 2 min |
| 3 | 4 min | 6 min |
| 4 | 8 min | 14 min |
| 5 | 16 min | 30 min |
| 6 | 32 min | 62 min |
| 7 | 64 min | ~2.1 h |
| 8 | 128 min | ~4.2 h |
| 9 | 256 min | ~8.5 h — then abandoned |
Idempotent processing
The same event may be delivered more than once. On receipt, check whether you have already processed this operation id + status; if so, acknowledge (2xx) and discard; otherwise apply the state transition and then acknowledge. Processing the same event twice must not change the final state.
Reconciliation
For periodic reconciliation outside the webhook stream, list endpoints are paginated with page (default 1) and limit (default 10):
| Action | Endpoint |
|---|---|
| List orders | GET /broker/v1/api/order |
| List withdrawals | GET /broker/v1/api/banking/withdraw |
| List deposits | GET /broker/v1/api/banking/deposit |
| List dividends | GET /broker/v1/api/holdingIncome |
| Get user balance | GET /broker/v1/api/balance/USERANYID |
| Get accounting summary | GET /broker/v1/api/accounting/summary |
Daily reconciliation files are also generated per company: a completed-operations report and a balance snapshot (per-user balances valued at the day's prices), both in CSV. Ask your Manteca contact about access to them.
For error handling, see Errors and controls.
Updated 1 day ago