Webhooks
Juno's webhooks provide real-time status updates for transactions on your account. By using them, you'll be notified automatically about events related to:
- Issuances
- Redemptions
- Crypto Deposits
- Crypto Withdrawals
To receive these updates, you must register a public callback URL with Juno. Whenever one of the supported events changes its status, Juno will send a notification to your URL using an HTTP POST method. This notification includes a payload with the relevant transaction data.
Important Considerations
Out-of-Order Events: Webhook events may not arrive in chronological order. Always use the
created_at
andupdated_at
timestamps to manage events correctly, rather than relying on the order of delivery.Transaction events: Juno sends webhooks for transaction events. This single event type delivers information for all four types of transactions listed above.
Timeouts: Your callback URL must respond within five seconds to avoid a timeout.
After the URL receives the update, you must store it and process it later. Callback URLs that take more than five seconds to respond will be considered as a time out.
Getting Started
Registering Your Callback URL
To register your callback URL, make an HTTP POST call to the endpoint below. Make sure your URL is publicly accessible so Juno's webhooks can reach it.
POST https://stage.buildwithjuno.com/v4/webhooks
Body Parameters
callback_url
(string): The public URL where you want to receive webhook notifications.events
(array[string]): A list of event types to subscribe to. The only accepted value isTRANSACTION
.
Example Request:
{
"callback_url": "https://example.com/juno-webhooks",
"events": ["TRANSACTION"]
}
Successful Response:
If successful, you will receive a response confirming the registration of your URL.
{
"message": "Webhook successfully created",
"webhooks": [
{
"id": 11330,
"callback_url": "https://example.com/juno-webhooks",
"event": "transaction"
}
]
}
Failure Response
If there's an error, you'll receive a response with a message in the error
field detailing the reason for the failure.
{
"success": false,
"error": "Duplicated subscription for event types: [transaction]"
}
Before you can register a webhook, Juno verifies your identity. Please refer to the Authentication guide for detailed instructions.
Understanding the Payloads
When a transaction event occurs, Juno sends a JSON object to your registered callback URL. This object contains two main fields: event
and payload
.
Common Transaction Fields
All transaction types share a set of common fields, which provide essential information about the event.
id
(UUID): A unique identifier for the transaction.type
(string): The type of transaction, which can beISSUANCE
,REDEMPTION
,CRYPTO_DEPOSIT
, orCRYPTO_WITHDRAWAL
.status
(string): The current status of the transaction. Possible values arePENDING
,IN_PROGRESS
, orCOMPLETE
.created_at
(ISO 8601): The timestamp of when the transaction was created.updated_at
(ISO 8601): The timestamp of the last update to the transaction.
Transaction-Specific Payloads
The payload's structure changes based on the transaction type. The following sections detail the unique fields for each type.
Issuance
For issuance transactions, the payload includes an issuance
object with additional details.
network
(string): The payment network used, such asARBITRUM
,ETHEREUM
.amount
(string): The amount of money credited to the Juno account. This is a positive number.method
(string): The method of transfer, eitherSPEI
orBITSO_TRANSFER
.asset
(string): The asset of the transaction.deposit_sender_clabe
(string): The sender's CLABE account number.deposit_sender_name
(string): The name of the sender.refunded
(boolean): Indicates if the transaction has been refunded.crypto_source_address
(string): The blockchain address from which the crypto was sent.crypto_destination_address
(string): The blockchain address the crypto was sent to. This field is only present for COMPLETE transactions.crypto_tx_hash
(string): The unique transaction ID on the blockchain. This field is only present for COMPLETE transactions.failure_reason
(string): The reason for a failed transaction.external_fiat_id
(string): External fiat id for the issuance. This field can benull
if the issuance is not initiated by a SPEI transfer.
Example Issuance Payload
{
"event": "TRANSACTION",
"payload": {
"type": "ISSUANCE",
"id": "d441f9db-e2df-4ca5-9dab-7526efdcea86",
"status": "COMPLETE",
"external_ref": "user-ref-12345",
"created_at": "2025-08-04T15:19:22.205597Z",
"updated_at": "2025-08-04T15:20:14.408753Z",
"issuance": {
"network": "ARBITRUM",
"amount": "100.000000",
"method": "SPEI",
"asset": "MXN",
"deposit_sender_clabe": "646180115400230775",
"deposit_sender_name": "Sender Name",
"refunded": false,
"crypto_source_address": "0xc0ffee254729296a45a3885639AC7E10F9d54979",
"crypto_destination_address": "0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E",
"crypto_tx_hash": "0xfb98c58faf63d17ce0fd5d41e82c3ae2f9b3721f2c1e369c17b379b4b59fe062",
"external_fiat_id": "TESTSPEI671271752263456670"
}
}
}
Redemption
For redemption transactions, the payload includes an redemption
object with additional details.
network
(string): The payment network used, such asARBITRUM
,ETHEREUM
.amount
(string): The amount of tokens to be redeemed. This is a positive number.method
(string): The method of transfer, eitherSPEI
orBITSO_TRANSFER
.asset
(string): The asset of the transaction.refunded
(boolean): Indicates if the transaction has been refunded.receiver_account.type
(string): The type of the receiver account, for example,MEXICAN_BANK_ACCOUNT
.receiver_account.mexican_bank_account.clabe
(string): The CLABE account where the redeemed tokens will be sent.failure_reason
(string): The reason for a failed transaction.external_fiat_id
(string): External fiat id for the redemption. This field can benull
if the redemption doesn't involve anSPEI
transfer.
Example Redemption Payload
{
"event": "TRANSACTION",
"payload": {
"type": "REDEMPTION",
"id": "d441f9db-e2df-4ca5-9dab-7526efdcea86",
"status": "COMPLETE",
"external_ref": "user-ref-12345",
"created_at": "2025-08-04T15:19:22.205597Z",
"updated_at": "2025-08-04T15:20:14.408753Z",
"redemption": {
"network": "ARBITRUM",
"amount": "100.000000",
"method": "SPEI",
"asset": "MXN",
"refunded": false,
"receiver_account": {
"type": "MEXICAN_BANK_ACCOUNT",
"mexican_bank_account": {
"clabe": "012180001234567890",
"external_fiat_id": "202508049071015060000005610295"
}
}
}
}
Crypto Deposit
For Crypto Deposit transactions, the payload includes a crypto_deposit
object with additional details.
network
(string): The payment network used, such asARBITRUM
,ETHEREUM
.amount
(string): The amount received in the specified asset. This is a positive number.asset
(string): The asset of the transaction.crypto_source_address
(string): The blockchain address from which the crypto was sent.crypto_destination_address
(string): The blockchain address the crypto was sent to.crypto_tx_hash
(string): The unique transaction ID on the blockchain. This field is only present for COMPLETE transactions.failure_reason
(string): The reason for a failed transaction.
Example Crypto Deposit Payload
{
"event": "TRANSACTION",
"payload": {
"type": "CRYPTO_DEPOSIT",
"id": "d441f9db-e2df-4ca5-9dab-7526efdcea86",
"status": "COMPLETE",
"external_ref": "user-ref-12345",
"created_at": "2025-08-04T15:19:22.205597Z",
"updated_at": "2025-08-04T15:20:14.408753Z",
"crypto_deposit": {
"network": "ARBITRUM",
"amount": "100.000000",
"asset": "MXNB",
"crypto_source_address": "0xc0ffee254729296a45a3885639AC7E10F9d54979",
"crypto_destination_address": "0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E",
"crypto_tx_hash": "0xfb98c58faf63d17ce0fd5d41e82c3ae2f9b3721f2c1e369c17b379b4b59fe062"
}
}
}
Crypto Withdrawal
For Crypto Withdrawal transactions, the payload includes an crypto_withdrawal
object with additional details.
network
(string): The payment network used, such asARBITRUM
,ETHEREUM
.amount
(string): The amount to be sent in the specified asset. This is a positive number.asset
(string): The asset of the transaction.crypto_source_address
(string): The blockchain address from which the crypto was sent.crypto_destination_address
(string): The blockchain address the crypto was sent to.crypto_tx_hash
(string): The unique transaction ID on the blockchain. This field is only present for COMPLETE transactions.failure_reason
(string): The reason for a failed transaction.
Example Crypto Withdrawal Payload
{
"event": "TRANSACTION",
"payload": {
"type": "CRYPTO_WITHDRAWAL",
"id": "d441f9db-e2df-4ca5-9dab-7526efdcea86",
"status": "COMPLETE",
"external_ref": "user-ref-12345",
"created_at": "2025-08-04T15:19:22.205597Z",
"updated_at": "2025-08-04T15:20:14.408753Z",
"crypto_withdrawal": {
"network": "ARBITRUM",
"amount": "100.000000",
"asset": "MXNB",
"crypto_source_address": "0xc0ffee254729296a45a3885639AC7E10F9d54979",
"crypto_destination_address": "0x999999cf1046e68e36E1aA2E0E07105eDDD1f08E",
"crypto_tx_hash": "0xfb98c58faf63d17ce0fd5d41e82c3ae2f9b3721f2c1e369c17b379b4b59fe062"
}
}
}
Transaction Statuses
Webhooks deliver real-time updates on the status of your transactions. To understand the possible states a transaction can be in, refer to the Transaction Status page. This document provides a complete breakdown of each status, including PENDING, IN_PROGRESS, COMPLETE, and FAILED.
Important Considerations
While some PENDING or IN_PROGRESS statuses may not be delivered via Webhook for certain transactions, you will always receive an event for the final COMPLETE or FAILED status.
Best Practices for Using Webhooks
Follow these best practices to ensure your webhook endpoint is secure and reliable:
- Handle Duplicate Events — Avoid Double Processing: Webhooks may send the same event multiple times, so managing potential duplicates is crucial. To prevent issues like double spending or duplicate credits, always verify both the transaction's final status and its unique transaction identifier. This verification ensures that each event is processed only once.
- Process Events Asynchronously: Use an asynchronous queue instead of handling events synchronously. This prevents scalability issues, especially during traffic spikes, and ensures your endpoint's hosting infrastructure remains stable.
- Acknowledge Events Quickly: Respond with a 2xx status code immediately upon receiving an event. Perform complex operations after acknowledging the event to avoid timeouts and lost events.
- Validate Events Using IPs: For added security, only allow webhook requests from trusted sources by adding Juno's IP addresses to an allowlist.
Environment | IP Addresses |
---|---|
Stage | 3.129.233.228 |
3.22.247.241 | |
3.134.133.168 | |
Production | 52.15.91.227 |
18.216.72.107 | |
18.219.140.132 |
Updated about 10 hours ago