> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.runpayments.io/docs/guides/webhooks/boarding-webhooks/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.runpayments.io/_mcp/server. # Boarding Webhooks Boarding webhooks notify you when a merchant's status changes in Run Partner, when a merchant is deleted, and when VAR details are available for a merchant's equipment. For the request format, signatures, and retries that apply to every webhook, see the [Webhooks Overview](/docs/guides/webhooks/overview). ## Merchant Status Events A merchant status event is sent each time a merchant's status changes, including when a merchant is created. Every status event has the same payload fields, described in [Payload Fields](#payload-fields). The event type is `merchant.` followed by the merchant's new status, using the same value as the `merchant_status` field in Boarding API responses. The payload's `merchant_status_id` field is the numeric ID for that status. It appears only in webhooks, not in the Boarding API. | **Event Type** | **Boarding API `merchant_status`** | **`merchant_status_id`** | | ----------------------------- | ---------------------------------- | ------------------------ | | `merchant.new` | `new` | 1 | | `merchant.sent_for_signature` | `sent_for_signature` | 2 | | `merchant.signed` | `signed` | 3 | | `merchant.in_underwriting` | `in_underwriting` | 4 | | `merchant.boarded` | `boarded` | 5 | | `merchant.live` | `live` | 6 | | `merchant.cancelled` | `cancelled` | 21 | | `merchant.declined` | `declined` | 41 | | `merchant.unknown` | `unknown` | 62 | Merchants don't always move through these statuses in order. For example, a merchant can move from `sent_for_signature` back to `new`. Don't assume a fixed sequence. Use the event with the latest `payload.timestamp` as the merchant's current status, because events can arrive out of order. ### Example: `merchant.sent_for_signature` For an example of every status event, see [Boarding Webhook Examples](/docs/guides/webhooks/boarding-webhooks/examples). ```json { "event_type": "merchant.sent_for_signature", "source_id": "133000", "timestamp": "2026-10-15T15:02:11.512Z", "payload": { "merchant_id": 133000, "mid": null, "rep_code_id": 5000, "customer_id": 128000, "dba_name": "Example Coffee Co", "merchant_status_id": 2, "external_crm_id": "CRM-0001", "custom_01": null, "trigger": "api", "reason": "sent_for_signature", "timestamp": "2026-10-15T15:02:11.498+00:00" }, "metadata": { "webhook_id": "wh_600001", "attempt": 1, "idempotency_key": "9b8a7c6d5e4f3a2b1c0d9e8f7a6b5c4d" } } ``` ### Payload Fields | **Field** | **Data Type** | **Comments** | | -------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `merchant_id` | Integer | Run Partner merchant ID. The top-level `source_id` contains the same ID as a string. | | `mid` | String or `null` | Merchant identification number (MID) assigned by the processor. Usually `null` until the merchant is boarded. | | `rep_code_id` | Integer | Numeric ID of the rep code the merchant is assigned to. This is not the `rep_code` string used in Boarding API requests. | | `customer_id` | Integer | Run Partner customer ID the merchant belongs to. Matches `customer_id` in Boarding API responses. | | `dba_name` | String | Merchant's DBA (doing business as) name. | | `merchant_status_id` | Integer | Numeric ID of the merchant's new status. See the table above. | | `external_crm_id` | String or `null` | External CRM identifier, if one was set through the Boarding API. | | `custom_01` | String or `null` | Custom merchant field, if one was set through the Boarding API. | | `trigger` | String | What made the change: `api`, `ui`, or `system`. See [Trigger and Reason](#trigger-and-reason). | | `reason` | String | The business action behind the change. See [Trigger and Reason](#trigger-and-reason). | | `timestamp` | String | When the change happened in Run Partner, in ISO 8601 format with a UTC offset. This can be earlier than the top-level `timestamp`, which is when the webhook was created. | ## Trigger and Reason Every `merchant.*` payload, including `merchant.deleted`, includes `trigger` and `reason`. The event type tells you what happened. These two fields tell you what caused it. `trigger` is one of: * `api` - a Boarding API call * `ui` - a user in Run Partner * `system` - an automated process `reason` is one of: | **`reason`** | **Sent with** | **Meaning** | | -------------------- | ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | | `created` | `merchant.new` | The merchant was created. | | `sent_for_signature` | `merchant.sent_for_signature` | The application was sent for signature. | | `resent` | `merchant.sent_for_signature` | An application already out for signature was resent through the Boarding API. See [Resending for Signature](#resending-for-signature). | | `retracted` | `merchant.new` | An application out for signature was recalled. | | `updated` | `merchant.new` | An application out for signature was changed through the Boarding API, which recalls it. | | `signed` | `merchant.signed` | The application was signed. | | `in_underwriting` | `merchant.in_underwriting` | The application moved to underwriting. | | `boarded` | `merchant.boarded` | The merchant was boarded. | | `live` | `merchant.live` | The merchant went live. | | `cancelled` | `merchant.cancelled` | The application was cancelled. | | `declined` | `merchant.declined` | The application was declined. | | `deleted` | `merchant.deleted` | The merchant was deleted. | | `status_changed` | Any `merchant.*` status event | The status changed and no more specific reason applies, such as a change to `unknown`. | > **Warning** > > New `reason` values may be added over time. If you receive a value you don't recognize, ignore the `reason` and process the event by its `event_type` instead of rejecting it. ### `merchant.new` Events A `merchant.new` event doesn't always mean a new application. It's also sent when an application that was out for signature moves back to `new`. If your integration acts on `merchant.new`, such as by creating a record or notifying a team, check `reason` first. Only `reason: created` means a new merchant. | **Action** | **`trigger`** | **`reason`** | | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | ------------ | | Merchant created | `api` or `ui` | `created` | | **Recall Signature Request** clicked in Run Partner | `ui` | `retracted` | | `PUT /merchants/{merchant_id}` sent with `merchant_status: "new"` | `api` | `retracted` | | `PUT /merchants/{merchant_id}` sent while the application is out for signature, without `merchant_status` or `auto_send_for_signature: true` | `api` | `updated` | ### Resending for Signature Resending an application that is already out for signature through the Boarding API (`PUT /merchants/{merchant_id}` with `merchant_status: "sent_for_signature"`, or with `auto_send_for_signature: true` and no `merchant_status`) replaces the outstanding signature link with a new one. This sends one `merchant.sent_for_signature` event with `reason: resent`. It doesn't send a `merchant.new` event first. Sending an application that is in `new` status sends one `merchant.sent_for_signature` event with `reason: sent_for_signature`. Check `reason` to tell a resend (`resent`) from a send (`sent_for_signature`). > **Note** > > Webhooks can't be turned off for an individual API request, because other subscribers would miss the change. Use `trigger` and `reason` to decide which events your integration acts on. ## Merchant Deleted Event ### `merchant.deleted` Sent when a merchant record is deleted from Run Partner. The payload has the same fields as the status events, plus `deleted_by`, the username of the person or integration that deleted the merchant. `merchant_status_id` is the status the merchant had when it was deleted, and `reason` is always `deleted`. ```json { "event_type": "merchant.deleted", "source_id": "133000", "timestamp": "2026-10-15T15:10:00.000Z", "payload": { "merchant_id": 133000, "mid": null, "rep_code_id": 5000, "customer_id": 128000, "dba_name": "Example Coffee Co", "merchant_status_id": 1, "external_crm_id": "CRM-0001", "custom_01": null, "deleted_by": "jane.example@example.com", "trigger": "ui", "reason": "deleted", "timestamp": "2026-10-15T15:10:00.000+00:00" }, "metadata": { "webhook_id": "wh_600002", "attempt": 1, "idempotency_key": "6e2d9c4b8a1f7035e4c2b9d8a6f1e3c7" } } ``` ## VAR Complete Event ### `boarding.varcomplete` Sent when VAR (configuration) details are available for a piece of a merchant's equipment, such as a terminal. One event is sent per piece of equipment. This payload has its own fields and doesn't include `merchant_status_id`, `trigger`, or `reason`. The fields can vary by processor and equipment type, so ignore fields you don't use and handle fields that aren't present. ```json { "event_type": "boarding.varcomplete", "source_id": "133000", "timestamp": "2026-10-15T15:30:00.000Z", "payload": { "merchant_id": 133000, "acquirer_bin": "400000", "agent_bank_number": "000001", "agent_chain_number": "111111", "city": "Commerce City", "zip_code": "90210", "contact_phone": "5551234567", "merchant_aba_number": "123456789", "merchant_category_code": "5812", "merchant_location_number": "00001", "dba_name": "Example Coffee Co", "mid": "800000000000", "merchant_settlement_agent_number": "A001", "state": "CA", "store_number": "0001", "terminal_id": "T001ABC", "terminal_number": "0001", "time_zone": "America/Los_Angeles" }, "metadata": { "webhook_id": "wh_600003", "attempt": 1, "idempotency_key": "5d4c3b2a1f0e9d8c7b6a5f4e3d2c1b0a" } } ``` ## Handling Boarding Webhooks * `mid`, `external_crm_id`, and `custom_01` can be `null`. Whether they're set depends on how far the merchant is in boarding and which fields were sent when the merchant was created or updated. * To confirm a merchant's current status, or to catch up after missed events, call [`GET /merchants/{merchant_id}`](/reference/reporting-boarding/boarding-api/get-merchant). Its `merchant_status` uses the same values as the status events. * For duplicates, ordering, retries, and signature verification, see [Delivery](/docs/guides/webhooks/overview#delivery) and [Verifying Signatures](/docs/guides/webhooks/overview#verifying-signatures). ## Docs - [Examples](https://docs.runpayments.io/docs/guides/webhooks/boarding-webhooks/examples.md)