---
title: Receive Inbound Direct Debits Webhook
slug: api/receive-inbound-direct-debits-webhook
docTags: 
createdAt: 2026-09-11T04:19:29.965Z
---

{
  "id": "dq-rvGkp5aRXtH1g-WRCG",
  "type": "api-oas-v2",
  "data": {
    "method": "POST",
    "url": "https://api.mpay.com.au/INBOUNDDIRECTDEBITEVENTWEBHOOK_TARGET_URL",
    "servers": [
      {
        "url": "https://api.mpay.com.au/INBOUNDDIRECTDEBITEVENTWEBHOOK_TARGET_URL",
        "description": "Production URL"
      },
      {
        "url": "https://api.m-pay.com.au/INBOUNDDIRECTDEBITEVENTWEBHOOK_TARGET_URL",
        "description": "Sandbox URL"
      }
    ],
    "name": "Receive Inbound Direct Debits Webhook",
    "description": "<p>Subscribing to the direct debit event webhook allows Monoova to notify you when an inbound direct debit is received on one of your accounts.</p>\n<p>Direct debits arrive in batches, so you receive the data as a JSON array of transactions, several times a day.</p>\n<p><strong>Event name:</strong> <code>InboundDirectDebit</code></p>\n<blockquote>\n<p><strong>Note.</strong> Source account details do not appear by default. Contact Monoova for further information.</p>\n</blockquote>",
    "contentType": "application/json",
    "request": {
      "pathParameters": [],
      "headerParameters": [
        {
          "kind": "optional",
          "name": "Authorisation",
          "type": "string",
          "example": "******",
          "description": "<p><strong>Optional</strong>. Shared secret that Monoova echoes back on every callback so your endpoint can authenticate the caller. The value is the one you registered on the subscription and is masked in this document. Omitted when no authorisation value was registered. Compare it in constant time and reject the notification with a 401 if it does not match.</p>",
          "default": "******",
          "pattern": "^[\\x20-\\x7E]{1,512}$"
        },
        {
          "kind": "optional",
          "name": "Verification-Signature",
          "type": "string",
          "example": "e+AFAj2W69rAwbsGn+rSSnFm2ISEblo0MXnx9Qtoh2k5mst1cEEpcrVSzGLjzOPlEL2Ea/iYLbFGzDdxVRTcNLINOhsXM/smimNjBt8sq30FbvSNMjlfDnrZ6FOIkl3E3cu9B+M4OVL8HafPohb67IRNDNyCnCvBM10qHrioiak=",
          "description": "<p><strong>Optional</strong> in the schema, but sent by Monoova on every notification. A base64 encoded cryptographic signature used to verify both the integrity of the message and that Monoova is its source. The hashing method is SHA256 and the public key can be retrieved from <code>/public/v1/certificate/public-key</code>. Verify it before you act on the payload, and reject the notification with a 401 if verification fails.</p>",
          "default": "e+AFAj2W69rAwbsGn+rSSnFm2ISEblo0MXnx9Qtoh2k5mst1cEEpcrVSzGLjzOPlEL2Ea/iYLbFGzDdxVRTcNLINOhsXM/smimNjBt8sq30FbvSNMjlfDnrZ6FOIkl3E3cu9B+M4OVL8HafPohb67IRNDNyCnCvBM10qHrioiak=",
          "pattern": "^[A-Za-z0-9+/]+={0,2}$"
        },
        {
          "kind": "optional",
          "name": "Webhookid",
          "type": "integer<int64>",
          "example": 1234567,
          "description": "<p><strong>Optional</strong>. Unique identifier for this webhook notification. Store it and treat a repeat of the same value as a redelivery of a notification you have already processed. Pattern: <code>^\\d{1,19}$</code>.</p>",
          "default": 1234567,
          "format": "int64"
        }
      ],
      "queryParameters": [],
      "bodyDataParameters": [
        {
          "kind": "required",
          "name": "body",
          "type": "object",
          "example": "{\"TotalCount\":3,\"TotalAmount\":452.75,\"DirectDebitDetails\":[{}]}",
          "description": "<p>Batch of inbound direct debit requests drawn against your AutoMatcher accounts. Sent for the <code>InboundDirectDebit</code> event. Source account details are not returned by default — contact Monoova to have them enabled.</p>",
          "customType": "WebhookInboundDirectDebitNotification",
          "schema": [
            {
              "name": "TotalCount",
              "kind": "optional",
              "type": "integer<int32>",
              "description": "<p><strong>Required</strong>. Number of direct debit transactions included in this notification. Use it to check you have processed every entry in the array. Pattern: <code>^\\d{1,10}$</code>.</p>",
              "example": 3,
              "default": 3,
              "format": "int32"
            },
            {
              "name": "TotalAmount",
              "kind": "optional",
              "type": "number<double>",
              "description": "<p><strong>Required</strong>. Sum of the amounts of every direct debit in this notification, in AUD to two decimal places for cents. Pattern: <code>^\\d{1,13}(\\.\\d{1,2})?$</code>.</p>",
              "example": 452.75,
              "default": 452.75,
              "format": "double"
            },
            {
              "name": "DirectDebitDetails",
              "kind": "optional",
              "type": "array",
              "description": "<p><strong>Required</strong>. One entry per direct debit received in this batch.</p>",
              "modelRef": "#/components/schemas/DirectDebitDetails",
              "customType": "DirectDebitDetails[]",
              "schema": []
            }
          ],
          "modelRef": "#/components/schemas/WebhookInboundDirectDebitNotification",
          "isExpanded": true
        }
      ],
      "formDataParameters": [],
      "oAuthParameters": [],
      "cookieParameters": []
    },
    "responses": [
      {
        "statusCode": "200",
        "description": "<p><strong>Success.</strong> The notification passed validation and your endpoint has accepted responsibility for it. Return this as soon as the payload is persisted — do not wait for downstream processing. Monoova treats any 2xx as a successful delivery and will not retry.</p>",
        "jsonExample": "",
        "isExpanded": true,
        "schema": [
          {
            "kind": "optional",
            "type": "object",
            "example": "{\"status\":\"Received\",\"webhookId\":1234567,\"receivedAt\":\"2026-09-10T14:32:12\"}",
            "description": "<p>Body your endpoint returns to acknowledge a notification. The body is optional — Monoova treats any 2xx status as a successful delivery — but returning it makes your acknowledgements easier to trace.</p>",
            "customType": "WebhookAcknowledgement",
            "schema": [
              {
                "name": "status",
                "kind": "optional",
                "type": "string<Received>",
                "description": "<p><strong>Required</strong>. Confirms the notification was accepted for processing. Return the literal value <code>Received</code>.</p>",
                "example": "Received",
                "default": "Received",
                "enum": [
                  "Received"
                ],
                "pattern": "^Received$"
              },
              {
                "name": "webhookId",
                "kind": "optional",
                "type": "integer<int64>",
                "description": "<p><strong>Optional</strong>. Echo of the <code>Webhookid</code> request header, so the acknowledgement can be matched to Monoova's delivery log. Pattern: <code>^\\d{1,19}$</code>.</p>",
                "example": 1234567,
                "default": 1234567,
                "format": "int64"
              },
              {
                "name": "receivedAt",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Optional</strong>. Date and time your endpoint accepted the notification, in ISO 8601 format.</p>",
                "example": "2026-09-10T14:32:12",
                "default": "2026-09-10T14:32:12",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}([T ]\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?)?$"
              }
            ],
            "modelRef": "#/components/schemas/WebhookAcknowledgement",
            "isExpanded": true
          }
        ]
      },
      {
        "statusCode": "400",
        "description": "<p><strong>Bad Request.</strong> The notification could not be parsed, or a field failed your validation. Monoova will not retry a notification that is rejected with a 400, so return it only for a genuinely malformed payload — never for a transient fault on your side.</p>",
        "jsonExample": "",
        "isExpanded": true,
        "schema": [
          {
            "kind": "optional",
            "type": "object",
            "example": "{\"status\":\"Rejected\",\"errorCode\":\"INVALID_PAYLOAD\",\"errorMessage\":\"Field 'Amount' is not a valid decimal value.\",\"webhookId\":1234567,\"receivedAt\":\"2026-09-10T14:32:12\"}",
            "description": "<p>Body your endpoint returns when a notification cannot be accepted. Returned with a 400, 401 or 500 status.</p>",
            "customType": "WebhookErrorResponse",
            "schema": [
              {
                "name": "status",
                "kind": "optional",
                "type": "string<Rejected | Unauthorised | Error>",
                "description": "<p><strong>Required</strong>. Processing outcome. Return <code>Rejected</code> with a 400, <code>Unauthorised</code> with a 401 and <code>Error</code> with a 500.</p>",
                "example": "Rejected",
                "default": "Rejected",
                "enum": [
                  "Rejected",
                  "Unauthorised",
                  "Error"
                ],
                "pattern": "^(Rejected|Unauthorised|Error)$"
              },
              {
                "name": "errorCode",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Required</strong>. Machine-readable code identifying the failure, in upper snake case. Keep the value stable so Monoova support can group repeated failures.</p>",
                "example": "INVALID_PAYLOAD",
                "default": "INVALID_PAYLOAD",
                "pattern": "^[A-Z][A-Z0-9_]{2,49}$"
              },
              {
                "name": "errorMessage",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Required</strong>. Human-readable explanation of the failure. Do not include payment data or credentials in this field.</p>",
                "example": "Field 'Amount' is not a valid decimal value.",
                "default": "Field 'Amount' is not a valid decimal value.",
                "pattern": "^.{1,500}$"
              },
              {
                "name": "webhookId",
                "kind": "optional",
                "type": "integer<int64>",
                "description": "<p><strong>Optional</strong>. Echo of the <code>Webhookid</code> request header, so the failure can be matched to Monoova's delivery log. Pattern: <code>^\\d{1,19}$</code>.</p>",
                "example": 1234567,
                "default": 1234567,
                "format": "int64"
              },
              {
                "name": "receivedAt",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Optional</strong>. Date and time your endpoint received the notification, in ISO 8601 format.</p>",
                "example": "2026-09-10T14:32:12",
                "default": "2026-09-10T14:32:12",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}([T ]\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?)?$"
              }
            ],
            "modelRef": "#/components/schemas/WebhookErrorResponse",
            "isExpanded": true
          }
        ]
      },
      {
        "statusCode": "401",
        "description": "<p><strong>Unauthorised.</strong> The <code>Authorisation</code> header was missing or did not match the value registered on the subscription, or the <code>Verification-Signature</code> header failed SHA256 verification against the Monoova public key. Return this without processing the payload.</p>",
        "jsonExample": "",
        "isExpanded": true,
        "schema": [
          {
            "kind": "optional",
            "type": "object",
            "example": "{\"status\":\"Unauthorised\",\"errorCode\":\"SIGNATURE_VERIFICATION_FAILED\",\"errorMessage\":\"Verification-Signature did not match the Monoova public key.\",\"webhookId\":1234567,\"receivedAt\":\"2026-09-10T14:32:12\"}",
            "description": "<p>Body your endpoint returns when a notification cannot be accepted. Returned with a 400, 401 or 500 status.</p>",
            "customType": "WebhookErrorResponse",
            "schema": [
              {
                "name": "status",
                "kind": "optional",
                "type": "string<Rejected | Unauthorised | Error>",
                "description": "<p><strong>Required</strong>. Processing outcome. Return <code>Rejected</code> with a 400, <code>Unauthorised</code> with a 401 and <code>Error</code> with a 500.</p>",
                "example": "Rejected",
                "default": "Rejected",
                "enum": [
                  "Rejected",
                  "Unauthorised",
                  "Error"
                ],
                "pattern": "^(Rejected|Unauthorised|Error)$"
              },
              {
                "name": "errorCode",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Required</strong>. Machine-readable code identifying the failure, in upper snake case. Keep the value stable so Monoova support can group repeated failures.</p>",
                "example": "INVALID_PAYLOAD",
                "default": "INVALID_PAYLOAD",
                "pattern": "^[A-Z][A-Z0-9_]{2,49}$"
              },
              {
                "name": "errorMessage",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Required</strong>. Human-readable explanation of the failure. Do not include payment data or credentials in this field.</p>",
                "example": "Field 'Amount' is not a valid decimal value.",
                "default": "Field 'Amount' is not a valid decimal value.",
                "pattern": "^.{1,500}$"
              },
              {
                "name": "webhookId",
                "kind": "optional",
                "type": "integer<int64>",
                "description": "<p><strong>Optional</strong>. Echo of the <code>Webhookid</code> request header, so the failure can be matched to Monoova's delivery log. Pattern: <code>^\\d{1,19}$</code>.</p>",
                "example": 1234567,
                "default": 1234567,
                "format": "int64"
              },
              {
                "name": "receivedAt",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Optional</strong>. Date and time your endpoint received the notification, in ISO 8601 format.</p>",
                "example": "2026-09-10T14:32:12",
                "default": "2026-09-10T14:32:12",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}([T ]\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?)?$"
              }
            ],
            "modelRef": "#/components/schemas/WebhookErrorResponse",
            "isExpanded": true
          }
        ]
      },
      {
        "statusCode": "500",
        "description": "<p><strong>Internal Server Error.</strong> Your endpoint accepted the notification but could not process it because of a fault on your side. Monoova retries a notification that fails with a 5xx, so return this — rather than a 400 — whenever the failure is transient and a redelivery could succeed.</p>",
        "jsonExample": "",
        "isExpanded": true,
        "schema": [
          {
            "kind": "optional",
            "type": "object",
            "example": "{\"status\":\"Error\",\"errorCode\":\"DOWNSTREAM_UNAVAILABLE\",\"errorMessage\":\"Ledger service unavailable; retry delivery.\",\"webhookId\":1234567,\"receivedAt\":\"2026-09-10T14:32:12\"}",
            "description": "<p>Body your endpoint returns when a notification cannot be accepted. Returned with a 400, 401 or 500 status.</p>",
            "customType": "WebhookErrorResponse",
            "schema": [
              {
                "name": "status",
                "kind": "optional",
                "type": "string<Rejected | Unauthorised | Error>",
                "description": "<p><strong>Required</strong>. Processing outcome. Return <code>Rejected</code> with a 400, <code>Unauthorised</code> with a 401 and <code>Error</code> with a 500.</p>",
                "example": "Rejected",
                "default": "Rejected",
                "enum": [
                  "Rejected",
                  "Unauthorised",
                  "Error"
                ],
                "pattern": "^(Rejected|Unauthorised|Error)$"
              },
              {
                "name": "errorCode",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Required</strong>. Machine-readable code identifying the failure, in upper snake case. Keep the value stable so Monoova support can group repeated failures.</p>",
                "example": "INVALID_PAYLOAD",
                "default": "INVALID_PAYLOAD",
                "pattern": "^[A-Z][A-Z0-9_]{2,49}$"
              },
              {
                "name": "errorMessage",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Required</strong>. Human-readable explanation of the failure. Do not include payment data or credentials in this field.</p>",
                "example": "Field 'Amount' is not a valid decimal value.",
                "default": "Field 'Amount' is not a valid decimal value.",
                "pattern": "^.{1,500}$"
              },
              {
                "name": "webhookId",
                "kind": "optional",
                "type": "integer<int64>",
                "description": "<p><strong>Optional</strong>. Echo of the <code>Webhookid</code> request header, so the failure can be matched to Monoova's delivery log. Pattern: <code>^\\d{1,19}$</code>.</p>",
                "example": 1234567,
                "default": 1234567,
                "format": "int64"
              },
              {
                "name": "receivedAt",
                "kind": "optional",
                "type": "string",
                "description": "<p><strong>Optional</strong>. Date and time your endpoint received the notification, in ISO 8601 format.</p>",
                "example": "2026-09-10T14:32:12",
                "default": "2026-09-10T14:32:12",
                "pattern": "^\\d{4}-\\d{2}-\\d{2}([T ]\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,7})?)?$"
              }
            ],
            "modelRef": "#/components/schemas/WebhookErrorResponse",
            "isExpanded": true
          }
        ]
      }
    ],
    "hasXCodeSamples": false,
    "examples": {
      "languages": [
        {
          "id": "sv31cXRgbpXDZRKw08z4d",
          "language": "curl",
          "label": "cURL",
          "code": "curl --request POST \\\n     --url https://api.mpay.com.au/INBOUNDDIRECTDEBITEVENTWEBHOOK_TARGET_URL \\\n     --header 'accept: application/json' \\\n     --header 'content-type: application/json' \\\n     --header 'authorisation: ******' \\\n     --header 'verification-signature: e+AFAj2W69rAwbsGn+rSSnFm2ISEblo0MXnx9Qtoh2k5mst1cEEpcrVSzGLjzOPlEL2Ea/iYLbFGzDdxVRTcNLINOhsXM/smimNjBt8sq30FbvSNMjlfDnrZ6FOIkl3E3cu9B+M4OVL8HafPohb67IRNDNyCnCvBM10qHrioiak=' \\\n     --header 'webhookid: 1234567' \\\n     --data '{\n     \"TotalCount\": 3,\n     \"TotalAmount\": 452.75\n     }'"
        },
        {
          "id": "f22tjfIF45sbvT1gDsIOg",
          "language": "javascript",
          "label": "javascript",
          "code": "var myHeaders = new Headers();\nmyHeaders.append(\"accept\", \"application/json\");\nmyHeaders.append(\"content-type\", \"application/json\");\nmyHeaders.append(\"authorisation\", \"******\");\nmyHeaders.append(\"verification-signature\", \"e+AFAj2W69rAwbsGn+rSSnFm2ISEblo0MXnx9Qtoh2k5mst1cEEpcrVSzGLjzOPlEL2Ea/iYLbFGzDdxVRTcNLINOhsXM/smimNjBt8sq30FbvSNMjlfDnrZ6FOIkl3E3cu9B+M4OVL8HafPohb67IRNDNyCnCvBM10qHrioiak=\");\nmyHeaders.append(\"webhookid\", \"1234567\");\n\nvar raw = JSON.stringify({\n   \"TotalCount\": 3,\n   \"TotalAmount\": 452.75\n});\n\nvar requestOptions = {\n   method: 'POST',\n   headers: myHeaders,\n   body: raw,\n   redirect: 'follow'\n};\n\nfetch(\"https://api.mpay.com.au/INBOUNDDIRECTDEBITEVENTWEBHOOK_TARGET_URL\", requestOptions)\n   .then(response => response.text())\n   .then(result => console.log(result))\n   .catch(error => console.log('error', error));"
        },
        {
          "id": "seabt8B7DqT_H4fR9Tw9A",
          "language": "ruby",
          "label": "Ruby",
          "code": "require \"uri\"\nrequire \"json\"\nrequire \"net/http\"\n\nurl = URI(\"https://api.mpay.com.au/INBOUNDDIRECTDEBITEVENTWEBHOOK_TARGET_URL\")\n\nhttps = Net::HTTP.new(url.host, url.port)\nhttps.use_ssl = true\n\nrequest = Net::HTTP::Post.new(url)\nrequest[\"accept\"] = \"application/json\"\nrequest[\"content-type\"] = \"application/json\"\nrequest[\"authorisation\"] = \"******\"\nrequest[\"verification-signature\"] = \"e+AFAj2W69rAwbsGn+rSSnFm2ISEblo0MXnx9Qtoh2k5mst1cEEpcrVSzGLjzOPlEL2Ea/iYLbFGzDdxVRTcNLINOhsXM/smimNjBt8sq30FbvSNMjlfDnrZ6FOIkl3E3cu9B+M4OVL8HafPohb67IRNDNyCnCvBM10qHrioiak=\"\nrequest[\"webhookid\"] = \"1234567\"\nrequest.body = JSON.dump({\n   \"TotalCount\": 3,\n   \"TotalAmount\": 452.75\n})\n\nresponse = https.request(request)\nputs response.read_body\n"
        },
        {
          "id": "ltyXmwp7mP17uhOZ0GiWl",
          "language": "python",
          "label": "Python",
          "code": "import requests\nimport json\n\nurl = \"https://api.mpay.com.au/INBOUNDDIRECTDEBITEVENTWEBHOOK_TARGET_URL\"\n\npayload = json.dumps({\n   \"TotalCount\": 3,\n   \"TotalAmount\": 452.75\n})\nheaders = {\n   'accept': 'application/json',\n   'content-type': 'application/json',\n   'authorisation': '******',\n   'verification-signature': 'e+AFAj2W69rAwbsGn+rSSnFm2ISEblo0MXnx9Qtoh2k5mst1cEEpcrVSzGLjzOPlEL2Ea/iYLbFGzDdxVRTcNLINOhsXM/smimNjBt8sq30FbvSNMjlfDnrZ6FOIkl3E3cu9B+M4OVL8HafPohb67IRNDNyCnCvBM10qHrioiak=',\n   'webhookid': '1234567'\n}\n\nresponse = requests.request(\"POST\", url, headers=headers, data=payload)\n\nprint(response.text)\n"
        }
      ],
      "selectedLanguageId": "sv31cXRgbpXDZRKw08z4d"
    },
    "results": {
      "languages": [
        {
          "id": "P6KcOFDGQauJYQl2GiHSL",
          "language": "200",
          "code": "// Success. The notification passed validation and your endpoint has accepted responsibility for it. Return this as soon as the payload is persisted — do not wait for downstream processing. Monoova treats any 2xx as a successful delivery and will not retry.\n{\n  \"status\": \"Received\",\n  \"webhookId\": 1234567,\n  \"receivedAt\": \"2026-09-10T14:32:12\"\n}"
        },
        {
          "id": "T5u4Pc8scBLNd77GZj3T_",
          "language": "400",
          "code": "// Bad Request. The notification could not be parsed, or a field failed your validation. Monoova will not retry a notification that is rejected with a 400, so return it only for a genuinely malformed payload — never for a transient fault on your side.\n{\n  \"status\": \"Rejected\",\n  \"errorCode\": \"INVALID_PAYLOAD\",\n  \"errorMessage\": \"Field 'Amount' is not a valid decimal value.\",\n  \"webhookId\": 1234567,\n  \"receivedAt\": \"2026-09-10T14:32:12\"\n}"
        },
        {
          "id": "mxwQnUJ2MphCc6Xbd0VZg",
          "language": "401",
          "code": "// Unauthorised. The Authorisation header was missing or did not match the value registered on the subscription, or the Verification-Signature header failed SHA256 verification against the Monoova public key. Return this without processing the payload.\n{\n  \"status\": \"Rejected\",\n  \"errorCode\": \"INVALID_PAYLOAD\",\n  \"errorMessage\": \"Field 'Amount' is not a valid decimal value.\",\n  \"webhookId\": 1234567,\n  \"receivedAt\": \"2026-09-10T14:32:12\"\n}"
        },
        {
          "id": "WTFjzLUrtmhGQT_7W3I6x",
          "language": "500",
          "code": "// Internal Server Error. Your endpoint accepted the notification but could not process it because of a fault on your side. Monoova retries a notification that fails with a 5xx, so return this — rather than a 400 — whenever the failure is transient and a redelivery could succeed.\n{\n  \"status\": \"Rejected\",\n  \"errorCode\": \"INVALID_PAYLOAD\",\n  \"errorMessage\": \"Field 'Amount' is not a valid decimal value.\",\n  \"webhookId\": 1234567,\n  \"receivedAt\": \"2026-09-10T14:32:12\"\n}"
        }
      ],
      "selectedLanguageId": "P6KcOFDGQauJYQl2GiHSL"
    }
  },
  "children": [
    {
      "text": ""
    }
  ]
}