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 and updated_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 is TRANSACTION.

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 be ISSUANCE, REDEMPTION, CRYPTO_DEPOSIT, or CRYPTO_WITHDRAWAL.
  • status (string): The current status of the transaction. Possible values are PENDING, IN_PROGRESS, or COMPLETE.
  • 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 as ARBITRUM, ETHEREUM.
  • amount (string): The amount of money credited to the Juno account. This is a positive number.
  • method (string): The method of transfer, either SPEI or BITSO_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 be null 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 as ARBITRUM, ETHEREUM.
  • amount (string): The amount of tokens to be redeemed. This is a positive number.
  • method (string): The method of transfer, either SPEI or BITSO_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 be null if the redemption doesn't involve an SPEI 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 as ARBITRUM, 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 as ARBITRUM, 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.
EnvironmentIP Addresses
Stage3.129.233.228
3.22.247.241
3.134.133.168
Production52.15.91.227
18.216.72.107
18.219.140.132