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

EventTrigger
user-status-updateUser status changes (onboarding, KYC, etc.).
documentation-status-updateA document changes status (DNI, selfie, etc.).
deposit-status-updateA deposit changes status.
order-status-updateAn order changes status (includes FCI subscribe/redeem).
synthetic-status-updateA synthetic (e.g. Dólar MEP) changes status.
withdraw-status-updateA withdrawal changes status.
holding-income-status-updateDividend/holding income payment.
user-balance-updateA 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:

StatusDescription
PENDINGTransfer initiated with the bank.
PENDING_ADMINAwaiting administrator approval.
PENDING_EXECUTIONScheduled to be processed at the defined time.
PROCESSINGIn flight at the bank; awaiting a response.
FAILEDFailed at the bank; needs manual review by an administrator.
RETRIEDWas failed and an administrator created a new one to be executed shortly.
EXECUTEDMoney sent successfully.
CANCELLEDCancelled 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.

AttemptDelay vs. previousCumulative
1 (initial)0 min
22 min2 min
34 min6 min
48 min14 min
516 min30 min
632 min62 min
764 min~2.1 h
8128 min~4.2 h
9256 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):

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.


Did this page help you?