This guide explains how to receive notifications every time you get a Money In transaction into your Monato accounts.
Money In notifications are sent as webhooks with msg_name = "MONEY_IN" and a common payload format for:
- External credits (SPEI) coming from other banks.
- Internal credits generated by
POST /v1/transactions/internal_transaction(book-to-book transfers between Monato accounts).
You can distinguish between these cases using fields such as sub_category and payer_institution.
In order to get a notification, first, you have to register the endpoint where you expect the webhook.
Endpoint POST /v1/webhooks
Request
Path parameters: none Query Parameters: none
Request Body:
{
"client_id":"{{clientId}}",
"url":"https://example.com/money-in-webhook",
"token": "secretToken0123",
"webhook_type": "MONEY_IN",
"auth_type": "AUTH"
}Response
Status Code: 200 OK
Response Body:
{
"id": "0c2d358f-0626-4c4e-b40b-9ab7c9dffe71",
"clientId": "c2d1d1e3-3340-4170-980e-e9269bbbc551",
"url": "https://example.com/webhook2",
"token": "secretToken0123",
"webhookType": "MONEY_IN",
"webhookStatus": "ACTIVE",
"createdAt": "2025-05-19 15:52:51.593012-06:00",
"updatedAt": "2025-05-19 15:52:51.593012-06:00",
"deletedAt": "None",
"blockedAt": "None",
"deletedBy": "None",
"blockedBy": "None"
}Once you register your endpoint for our webhook, you will get a POST request every time a Money In arrives.
Common envelope
We always send a JSON object with the following envelope:
{
"id_msg": "a7a126e8-fa74-411c-ad2b-b000f277bb0d",
"msg_name": "MONEY_IN",
"msg_date": "2025-04-02",
"body": {
"...": "..."
}
}id_msg: unique identifier of the message.msg_name: for Money In notifications it is always"MONEY_IN".msg_date: message date (YYYY-MM-DD).body: contains the Money In details.
Example – External Money In (SPEI)
{
"id_msg": "a7a126e8-fa74-411c-ad2b-b000f277bb0d",
"msg_name": "MONEY_IN",
"msg_date": "2025-04-02",
"body": {
"id": "0196da9a-8947-703e-9a3b-bf8c7d9f6059",
"beneficiary_account": "734180123045603216",
"beneficiary_name": "John Smith",
"beneficiary_rfc": "XYZ123456789",
"payer_account": "137180210044008609",
"payer_name": "Juan Perez",
"payer_rfc": "XYZ987654321",
"payer_institution": "40002",
"amount": "123.00",
"transaction_date": "2025-04-02 10:14:05",
"tracking_key": "50118609TBRNZ00I07219647",
"payment_concept": "Payment for invoice 4567",
"numeric_reference": "2504021",
"sub_category": "SPEI_CREDIT",
"registered_at": "2025-04-02T10:14:05.915184-06:00",
"owner_id": "24f1e5d5-4045-4b1a-a0c4-5e6c6b1d44ef"
}
}Example – Internal Money In (book-to-book)
This is the type of Money In you will receive when funds are moved via POST /v1/transactions/internal_transaction towards one of your Monato instruments.
{
"id_msg": "6daea2d2-ccb0-48f3-917c-f387dc8e99b0",
"msg_name": "MONEY_IN",
"msg_date": "2025-11-20",
"body": {
"id": "a0037594-5064-4dda-896b-f9b5dd4988dd",
"beneficiary_account": "734185000000001177",
"beneficiary_name": "MERCHANT TEST",
"beneficiary_rfc": "FTR230125Q00",
"payer_account": "734185000000000822",
"payer_name": "Customer Test-1 Legal",
"payer_rfc": "ND",
"payer_institution": "90734",
"amount": "1.00",
"transaction_date": "2025-11-20 15:05:59",
"tracking_key": "20251120FINCHESDHI7FVTU",
"payment_concept": "CUST - SPEI",
"numeric_reference": "1100003",
"sub_category": "INT_CREDIT",
"registered_at": "2025-11-20T15:05:59.915184-06:00",
"owner_id": "24f1e5d5-4045-4b1a-a0c4-5e6c6b1d44ef"
}
}Another example between customers of the same merchant:
{
"id_msg": "2293f8fd-2fc5-4f4c-8985-e97466341b61",
"msg_name": "MONEY_IN",
"msg_date": "2025-11-20",
"body": {
"id": "ba964d20-c9dc-4bf1-8ffb-f0f9d5238485",
"beneficiary_account": "734185000000000819",
"beneficiary_name": "Customer Test-2 Legal",
"beneficiary_rfc": "ND",
"payer_account": "734185000000000822",
"payer_name": "Customer Test-1 Legal",
"payer_rfc": "ND",
"payer_institution": "90734",
"amount": "1.00",
"transaction_date": "2025-11-20 14:59:56",
"tracking_key": "20251120FINCHUSE4PV5VNY",
"payment_concept": "CUST - CUST",
"numeric_reference": "1100001",
"sub_category": "INT_CREDIT",
"registered_at": "2025-11-20T14:59:56.705283-06:00",
"owner_id": "fd140e3c-29d8-4e39-bdd8-6e82c94ecad3"
}
}Money In body fields
Main fields you will see in the body:
id– Internal transaction identifier in Monato.beneficiary_account– Beneficiary CLABE (or Monato CLABE for internal credits).beneficiary_name– Beneficiary account holder name.beneficiary_rfc– Beneficiary RFC.payer_account– Payer account number (CLABE or internal account).payer_name– Payer name.payer_rfc– Payer RFC, or"ND"when not provided.payer_institution- For SPEI credits: Banxico institution code of the originating bank (e.g.
40002). - For internal credits: Monato internal institution code (e.g.
90734).
- For SPEI credits: Banxico institution code of the originating bank (e.g.
amount– Amount credited, as a string with 2 decimal places (e.g."123.00").transaction_date- Date and time when the transaction was registered in the rail.
- Format:
YYYY-MM-DD HH:MM:SS.
tracking_key– SPEI tracking key or internal tracking id.payment_concept– Payment description / concept.numeric_reference– Numeric reference used by the payer.sub_category- Internal classification of the credit.
- Typical values:
SPEI_CREDIT– external SPEI credit.INT_CREDIT– internal credit frominternal_transaction.
registered_at– Timestamp in Monato when the transaction was created / persisted (ISO-8601 with timezone).owner_id– Identifier of the owner of the destination instrument (e.g. the customer that owns the receiving account).
You can use sub_category and payer_institution together to identify if a Money In comes from an external SPEI transfer or from an internal transaction.
There are two behaviors depending on the type of Money In:
For SPEI Money In, you can accept or reject the transaction directly from the webhook response:
Accept a Money In
Respond to the Money In webhook with HTTP
201 Created. We will consider that you accepted the Money In.Reject a Money In
Respond to the Money In webhook with HTTP
422 Unprocessable Entityand the Money In will be automatically refunded. Additionally, you can send a JSON body with the reason:
{
"refundReason": "Invalid Amount"
}For internal credits (sub_category = "INT_CREDIT"), the funds have already been moved book-to-book by the time you receive the webhook. In this case:
- The Money In webhook is informational only.
- HTTP status codes on your response do not trigger an automatic refund.
- If you need to reverse an internal movement, you must create a new
internal_transactionin the opposite direction (see Internal Transactions API).
Sometimes you accept a Money In but later you need to refund it. For external SPEI credits, you can do this with the refund endpoint.
Endpoint
POST /v1/clients/{{clientId}}/transactions/{{transactionId}}/refund
Request
Path parameters:
clientId:
c2d1d1e3-3340-4170-980e-e9269bbbc551transactionId:
e43171ad-af3b-40e3-913c-24cc386bf5ffThis is sent in the Money In webhook or can be retrieved via the Transactions API.
Query Parameters: none
Request Body:
{
"description": "Lorem ipsum",
"amount": "9.99"
}Response
Status Code: 200 OK
Response Body:
{
"id": "e43171ad-af3b-40e3-913c-24cc386bf5ff",
"bankId": "1953a92c-11e5-4315-b406-b89dd6b699b4",
"clientId": "c2d1d1e3-3340-4170-980e-e9269bbbc551",
"externalReference": "2505201",
"trackingId": "20250520FINCHARNJK5NHQG",
"description": "Lorem ipsum",
"amount": "9.99",
"currency": "MXN",
"category": "DEBIT_TRANS",
"subCategory": "SPEI_DEBIT",
"transactionStatus": "LIQUIDATED",
"audit": {
"createdAt": "2025-05-20 10:57:44.220281-06:00",
"updatedAt": "2025-05-20 10:57:44.220281-06:00",
"deletedAt": "None",
"blockedAt": "None"
},
"originalTransactionId": "a1392ef1-75f2-457a-8203-d4fd4b435559"
}This endpoint applies to external SPEI transactions.
To “reverse” an internal transaction, you must create a new
internal_transactionin the opposite direction.
Take note that the /refund endpoint return a transaction data, this is because we need to create a new SPEI transaction to return the money to the original sourcing account.
In this case, you will have two transactions:
- The original, with
transactionStatus = "REFUNDED". - The refund transaction, with
transactionStatus = "LIQUIDATED".
You can retrieve the details of a transaction with a call to:
EndpointGET /v1/clients/{{clientId}}/transactions/{{transactionId}}
Request
Path parameters:
- clientId:
c2d1d1e3-3340-4170-980e-e9269bbbc551 - transactionId:
e43171ad-af3b-40e3-913c-24cc386bf5ff
This is sent in the Money In webhook or known from your own records.
If you don’t send query parameters, the transaction is retrieved by transactionId only.
Query parameters (optional):
transaction_status – Filter by transaction status.
Example:LIQUIDATEDtracking_id – Filter by the SPEI tracking key associated with the transaction.
Example:20250520FINCHARNJK5NHQGtransaction_category – Filter by transaction category.
Example:DEBIT_TRANSbank_id – Filter by bank identifier.
Example:1953a92c-11e5-4315-b406-b89dd6b699b4
Example using tracking_id
GET /v1/clients/c2d1d1e3-3340-4170-980e-e9269bbbc551/transactions/e43171ad-af3b-40e3-913c-24cc386bf5ff?tracking_id=20250520FINCHARNJK5NHQG
Response
Status Code: 200 OK
Response Body:
{
"id": "e43171ad-af3b-40e3-913c-24cc386bf5ff",
"bankId": "1953a92c-11e5-4315-b406-b89dd6b699b4",
"clientId": "c2d1d1e3-3340-4170-980e-e9269bbbc551",
"externalReference": "2505201",
"trackingId": "20250520FINCHARNJK5NHQG",
"description": "Lorem ipsum",
"amount": "9.99",
"currency": "MXN",
"category": "DEBIT_TRANS",
"subCategory": "SPEI_DEBIT",
"transactionStatus": "LIQUIDATED",
"audit": {
"createdAt": "2025-05-20 10:57:44.220281-06:00",
"updatedAt": "2025-05-20 10:57:44.220281-06:00",
"deletedAt": "None",
"blockedAt": "None"
},
"jsonReference": "{'transaction_date': '2025-05-20 10:14:05', ...}",
"sourceInstrument": { ... },
"destinationInstrument": { ... }
}