> For the complete documentation index, see [llms.txt](https://docs.merchone.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.merchone.com/webhooks.md).

# Webhooks

## Introduction

Webhooks allow your application to receive real-time notifications about events in your merchOne orders. When specific events occur (order cancellation, shipment, tracking updates, etc.), merchOne sends a `POST` request to your configured webhook URL with event details in JSON format.

## Configuration

{% stepper %}
{% step %}

### Log in and open dashboard

Log in to your merchOne account and navigate to the dashboard.
{% endstep %}

{% step %}

### Open Stores settings

Navigate to the **Stores** page and access the **Settings** for the specific store where you wish to add a webhook.
{% endstep %}

{% step %}

### Find the Webhook section

Scroll to the **Webhook** section.
{% endstep %}

{% step %}

### Add your webhook URL

Add your webhook URL to the **Webhook URL** field.
{% endstep %}

{% step %}

### Save

Click **Save**.
{% endstep %}
{% endstepper %}

{% hint style="warning" %}
The webhook URL is stored with the order at creation time. If you change or remove the webhook URL after an order is created, the changes will **not** apply to existing orders. Make sure your webhook URL is correctly configured before placing orders.
{% endhint %}

## Webhook Delivery

### Request Format

* Method: `POST`
* Content-Type: `application/json`
* Timeout: 60 seconds

### Retry Policy

If your webhook endpoint fails to respond with a `2xx` status code, merchOne will automatically retry the delivery:

| Attempt   | Wait Time  |
| --------- | ---------- |
| 1st retry | 1 minute   |
| 2nd retry | 5 minutes  |
| 3rd retry | 10 minutes |
| 4th retry | 20 minutes |
| 5th retry | 30 minutes |

If your endpoint accumulates 10 or more failed webhook deliveries in a single day, you will receive a notification email.

### Expected Response

Your endpoint should return a `200 OK` (or any `2xx`) status code to acknowledge receipt. The response body is ignored.

```
HTTP/1.1 200 OK
```

## Webhook Events

merchOne supports the following webhook event types:

| Event Type                | Description                                         |
| ------------------------- | --------------------------------------------------- |
| `shipment_sent`           | Triggered when an order shipment is dispatched      |
| `shipment_tracking_event` | Triggered when a tracking status update is received |
| `order_canceled`          | Triggered when an order is canceled                 |
| `order_failed`            | Triggered when an order encounters an error         |
| `order_commented`         | Triggered when a comment is added to an order       |

### Event-Specific Data Fields

Each webhook event includes the full `order` object plus event-specific data:

| Event Type                | Extra Fields | Description                                        |
| ------------------------- | ------------ | -------------------------------------------------- |
| `shipment_sent`           | `shipment`   | Shipment details with tracking info and items      |
| `shipment_tracking_event` | `event`      | Tracking status, location, details, and date       |
| `order_canceled`          | `author`     | Who canceled the order (API, System, or user name) |
| `order_failed`            | `reason`     | Error message describing why the order failed      |
| `order_commented`         | `comment`    | The comment text added to the order                |

## Event Payloads

### Shipment Sent (`shipment_sent`)

Triggered when an order shipment is dispatched from the fulfillment center.

{% code title="shipment\_sent.json" %}

```json
{
  "type": "shipment_sent",
  "created": "2025-05-02T12:48:56.000000Z",
  "data": {
    "shipment": {
      "shipping_method": {
        "code": "DHL_STANDARD",
        "name": "DHL Standard"
      },
      "tracking_number": "00340434161094042557",
      "tracking_url": "https://www.dhl.com/global-en/home/tracking/tracking-parcel.html?submit=1&tracking-id=00340434161094042557",
      "shipped_at": "2025-05-02T12:48:56.000000Z",
      "items": [
        {
          "item_id": 12345,
          "item_external_id": "your-sku-123",
          "quantity": 3
        }
      ]
    },
    "order": {
      "id": "PPO12345678",
      "external_id": null,
      "is_test": false,
      "shipping_method": {
        "code": "DHL_STANDARD",
        "name": "DHL Standard"
      },
      "status": "FULFILLED",
      "status_label": "Fulfilled",
      "created_at": "2025-05-02T12:45:35.000000Z",
      "updated_at": "2025-05-02T12:48:56.000000Z",
      "shipments": [
        {
          "shipping_method": {
            "code": "DHL_STANDARD",
            "name": "DHL Standard"
          },
          "tracking_number": "00340434161094042557",
          "tracking_url": "https://www.dhl.com/global-en/home/tracking/tracking-parcel.html?submit=1&tracking-id=00340434161094042557",
          "shipped_at": "2025-05-02T12:48:56.000000Z",
          "items": [
            {
              "item_id": 12345,
              "item_external_id": "your-sku-123",
              "quantity": 3
            }
          ]
        }
      ],
      "items": [
        {
          "id": 12345,
          "external_id": "your-sku-123",
          "variant_id": 1,
          "name": "20x20 cm",
          "quantity": 3,
          "price": 5.33,
          "price_details": {
            "currency": "EUR",
            "formatted": "5.33 €",
            "in_subunit": 533
          },
          "tax_amount": 3.61,
          "tax_amount_details": {
            "currency": "EUR",
            "formatted": "3.61 €",
            "in_subunit": 361
          },
          "file": "https://api.merchone.com/files/orders/PPO12345678/image.png",
          "options": [
            {
              "id": 1,
              "name": "Canvas border",
              "value": {
                "id": 2,
                "name": "Folded"
              }
            },
            {
              "id": 2,
              "name": "Stretcher frame",
              "value": {
                "id": 6,
                "name": "2 cm"
              }
            }
          ],
          "retail_price": null,
          "retail_price_details": null
        }
      ],
      "totals": {
        "subtotal_amount": 15.99,
        "subtotal_amount_details": {
          "currency": "EUR",
          "formatted": "15.99 €",
          "in_subunit": 1599
        },
        "shipping_amount": 3.02,
        "shipping_amount_details": {
          "currency": "EUR",
          "formatted": "3.02 €",
          "in_subunit": 302
        },
        "total_amount": 19.01,
        "total_amount_details": {
          "currency": "EUR",
          "formatted": "19.01 €",
          "in_subunit": 1901
        },
        "customs_shipping_costs": 5.99,
        "customs_shipping_costs_details": {
          "currency": "EUR",
          "formatted": "5.99 €",
          "in_subunit": 599
        },
        "grand_total": 22.62,
        "grand_total_details": {
          "currency": "EUR",
          "formatted": "22.62 €",
          "in_subunit": 2262
        },
        "tax_amount": 3.61,
        "tax_amount_details": {
          "currency": "EUR",
          "formatted": "3.61 €",
          "in_subunit": 361
        }
      },
      "retail_costs": []
    }
  }
}
```

{% endcode %}

### Shipment Tracking Event (`shipment_tracking_event`)

Triggered when a tracking status update is received for a shipment.

{% code title="shipment\_tracking\_event.json" %}

```json
{
  "type": "shipment_tracking_event",
  "created": "2025-05-03T08:15:00.000000Z",
  "data": {
    "event": {
      "status": "in_transit",
      "location": "Berlin, Germany",
      "details": "Package is in transit to destination",
      "date": "2025-05-03T08:12:00.000000Z"
    },
    "order": {
      "id": "PPO12345678",
      "external_id": null,
      "is_test": false,
      "shipping_method": {
        "code": "DHL_STANDARD",
        "name": "DHL Standard"
      },
      "status": "FULFILLED",
      "status_label": "Fulfilled",
      "created_at": "2025-05-02T12:45:35.000000Z",
      "updated_at": "2025-05-03T08:15:00.000000Z",
      "shipments": [
        {
          "shipping_method": {
            "code": "DHL_STANDARD",
            "name": "DHL Standard"
          },
          "tracking_number": "00340434161094042557",
          "tracking_url": "https://www.dhl.com/global-en/home/tracking/tracking-parcel.html?submit=1&tracking-id=00340434161094042557",
          "shipped_at": "2025-05-02T12:48:56.000000Z",
          "items": [
            {
              "item_id": 12345,
              "item_external_id": "your-sku-123",
              "quantity": 3
            }
          ]
        }
      ],
      "items": [
        {
          "id": 12345,
          "external_id": "your-sku-123",
          "variant_id": 1,
          "name": "20x20 cm",
          "quantity": 3,
          "price": 5.33,
          "price_details": {
            "currency": "EUR",
            "formatted": "5.33 €",
            "in_subunit": 533
          },
          "tax_amount": 3.61,
          "tax_amount_details": {
            "currency": "EUR",
            "formatted": "3.61 €",
            "in_subunit": 361
          },
          "file": "https://api.merchone.com/files/orders/PPO12345678/image.png",
          "options": [
            {
              "id": 1,
              "name": "Canvas border",
              "value": {
                "id": 2,
                "name": "Folded"
              }
            },
            {
              "id": 2,
              "name": "Stretcher frame",
              "value": {
                "id": 6,
                "name": "2 cm"
              }
            }
          ],
          "retail_price": null,
          "retail_price_details": null
        }
      ],
      "totals": {
        "subtotal_amount": 15.99,
        "subtotal_amount_details": {
          "currency": "EUR",
          "formatted": "15.99 €",
          "in_subunit": 1599
        },
        "shipping_amount": 3.02,
        "shipping_amount_details": {
          "currency": "EUR",
          "formatted": "3.02 €",
          "in_subunit": 302
        },
        "total_amount": 19.01,
        "total_amount_details": {
          "currency": "EUR",
          "formatted": "19.01 €",
          "in_subunit": 1901
        },
        "customs_shipping_costs": 5.99,
        "customs_shipping_costs_details": {
          "currency": "EUR",
          "formatted": "5.99 €",
          "in_subunit": 599
        },
        "grand_total": 22.62,
        "grand_total_details": {
          "currency": "EUR",
          "formatted": "22.62 €",
          "in_subunit": 2262
        },
        "tax_amount": 3.61,
        "tax_amount_details": {
          "currency": "EUR",
          "formatted": "3.61 €",
          "in_subunit": 361
        }
      },
      "retail_costs": []
    }
  }
}
```

{% endcode %}

Possible tracking statuses:

* `in_transit` - Package is on the way
* `out_for_delivery` - Package is out for delivery
* `delivered` - Package has been delivered
* `exception` - Delivery exception occurred
* `returned` - Package returned to sender

### Order Canceled (`order_canceled`)

Triggered when an order is canceled.

{% code title="order\_canceled.json" %}

```json
{
  "type": "order_canceled",
  "created": "2025-11-27T10:26:09.000000Z",
  "data": {
    "author": "via API",
    "order": {
      "id": "PPO12345678",
      "external_id": null,
      "is_test": false,
      "shipping_method": {
        "code": "DHL_STANDARD",
        "name": "DHL Standard"
      },
      "status": "CANCELED",
      "status_label": "Canceled",
      "created_at": "2025-11-27T09:00:00.000000Z",
      "updated_at": "2025-11-27T10:26:09.000000Z",
      "shipments": [],
      "items": [
        {
          "id": 12345,
          "external_id": "your-sku-123",
          "variant_id": 1,
          "name": "20x20 cm",
          "quantity": 3,
          "price": 5.33,
          "price_details": {
            "currency": "EUR",
            "formatted": "5.33 €",
            "in_subunit": 533
          },
          "tax_amount": 3.61,
          "tax_amount_details": {
            "currency": "EUR",
            "formatted": "3.61 €",
            "in_subunit": 361
          },
          "file": "https://api.merchone.com/files/orders/PPO12345678/image.png",
          "options": [
            {
              "id": 1,
              "name": "Canvas border",
              "value": {
                "id": 2,
                "name": "Folded"
              }
            },
            {
              "id": 2,
              "name": "Stretcher frame",
              "value": {
                "id": 6,
                "name": "2 cm"
              }
            }
          ],
          "retail_price": null,
          "retail_price_details": null
        }
      ],
      "totals": {
        "subtotal_amount": 15.99,
        "subtotal_amount_details": {
          "currency": "EUR",
          "formatted": "15.99 €",
          "in_subunit": 1599
        },
        "shipping_amount": 3.02,
        "shipping_amount_details": {
          "currency": "EUR",
          "formatted": "3.02 €",
          "in_subunit": 302
        },
        "total_amount": 19.01,
        "total_amount_details": {
          "currency": "EUR",
          "formatted": "19.01 €",
          "in_subunit": 1901
        },
        "customs_shipping_costs": 5.99,
        "customs_shipping_costs_details": {
          "currency": "EUR",
          "formatted": "5.99 €",
          "in_subunit": 599
        },
        "grand_total": 22.62,
        "grand_total_details": {
          "currency": "EUR",
          "formatted": "22.62 €",
          "in_subunit": 2262
        },
        "tax_amount": 3.61,
        "tax_amount_details": {
          "currency": "EUR",
          "formatted": "3.61 €",
          "in_subunit": 361
        }
      },
      "retail_costs": []
    }
  }
}
```

{% endcode %}

Possible `author` values:

* `"via API"` - Canceled via API request
* `"by System (Automatic)"` - Automatically canceled by the system
* `"by John Doe"` - Canceled by a user
* `"by our administrator, John Doe"` - Canceled by an admin

### Order Failed (`order_failed`)

Triggered when an order encounters an error during processing.

{% code title="order\_failed.json" %}

```json
{
  "type": "order_failed",
  "created": "2025-11-27T10:26:19.000000Z",
  "data": {
    "reason": "Invalid image file: minimum resolution requirement not met",
    "order": {
      "id": "PPO12345678",
      "external_id": null,
      "is_test": false,
      "shipping_method": {
        "code": "DHL_STANDARD",
        "name": "DHL Standard"
      },
      "status": "FAILED",
      "status_label": "Failed",
      "created_at": "2025-11-27T09:00:00.000000Z",
      "updated_at": "2025-11-27T10:26:19.000000Z",
      "shipments": [],
      "items": [
        {
          "id": 12345,
          "external_id": "your-sku-123",
          "variant_id": 1,
          "name": "20x20 cm",
          "quantity": 3,
          "price": 5.33,
          "price_details": {
            "currency": "EUR",
            "formatted": "5.33 €",
            "in_subunit": 533
          },
          "tax_amount": 3.61,
          "tax_amount_details": {
            "currency": "EUR",
            "formatted": "3.61 €",
            "in_subunit": 361
          },
          "file": "https://api.merchone.com/files/orders/PPO12345678/image.png",
          "options": [
            {
              "id": 1,
              "name": "Canvas border",
              "value": {
                "id": 2,
                "name": "Folded"
              }
            },
            {
              "id": 2,
              "name": "Stretcher frame",
              "value": {
                "id": 6,
                "name": "2 cm"
              }
            }
          ],
          "retail_price": null,
          "retail_price_details": null
        }
      ],
      "totals": {
        "subtotal_amount": 15.99,
        "subtotal_amount_details": {
          "currency": "EUR",
          "formatted": "15.99 €",
          "in_subunit": 1599
        },
        "shipping_amount": 3.02,
        "shipping_amount_details": {
          "currency": "EUR",
          "formatted": "3.02 €",
          "in_subunit": 302
        },
        "total_amount": 19.01,
        "total_amount_details": {
          "currency": "EUR",
          "formatted": "19.01 €",
          "in_subunit": 1901
        },
        "customs_shipping_costs": 5.99,
        "customs_shipping_costs_details": {
          "currency": "EUR",
          "formatted": "5.99 €",
          "in_subunit": 599
        },
        "grand_total": 22.62,
        "grand_total_details": {
          "currency": "EUR",
          "formatted": "22.62 €",
          "in_subunit": 2262
        },
        "tax_amount": 3.61,
        "tax_amount_details": {
          "currency": "EUR",
          "formatted": "3.61 €",
          "in_subunit": 361
        }
      },
      "retail_costs": []
    }
  }
}
```

{% endcode %}

### Order Commented (`order_commented`)

Triggered when a comment is added to an order by merchOne staff.

{% code title="order\_commented.json" %}

```json
{
  "type": "order_commented",
  "created": "2025-11-27T10:26:28.000000Z",
  "data": {
    "comment": "Your order is being prepared with special care.",
    "order": {
      "id": "PPO12345678",
      "external_id": null,
      "is_test": false,
      "shipping_method": {
        "code": "DHL_STANDARD",
        "name": "DHL Standard"
      },
      "status": "IN_PRODUCTION",
      "status_label": "In Production",
      "created_at": "2025-11-27T09:00:00.000000Z",
      "updated_at": "2025-11-27T10:26:28.000000Z",
      "shipments": [],
      "items": [
        {
          "id": 12345,
          "external_id": "your-sku-123",
          "variant_id": 1,
          "name": "20x20 cm",
          "quantity": 3,
          "price": 5.33,
          "price_details": {
            "currency": "EUR",
            "formatted": "5.33 €",
            "in_subunit": 533
          },
          "tax_amount": 3.61,
          "tax_amount_details": {
            "currency": "EUR",
            "formatted": "3.61 €",
            "in_subunit": 361
          },
          "file": "https://api.merchone.com/files/orders/PPO12345678/image.png",
          "options": [
            {
              "id": 1,
              "name": "Canvas border",
              "value": {
                "id": 2,
                "name": "Folded"
              }
            },
            {
              "id": 2,
              "name": "Stretcher frame",
              "value": {
                "id": 6,
                "name": "2 cm"
              }
            }
          ],
          "retail_price": null,
          "retail_price_details": null
        }
      ],
      "totals": {
        "subtotal_amount": 15.99,
        "subtotal_amount_details": {
          "currency": "EUR",
          "formatted": "15.99 €",
          "in_subunit": 1599
        },
        "shipping_amount": 3.02,
        "shipping_amount_details": {
          "currency": "EUR",
          "formatted": "3.02 €",
          "in_subunit": 302
        },
        "total_amount": 19.01,
        "total_amount_details": {
          "currency": "EUR",
          "formatted": "19.01 €",
          "in_subunit": 1901
        },
        "customs_shipping_costs": 5.99,
        "customs_shipping_costs_details": {
          "currency": "EUR",
          "formatted": "5.99 €",
          "in_subunit": 599
        },
        "grand_total": 22.62,
        "grand_total_details": {
          "currency": "EUR",
          "formatted": "22.62 €",
          "in_subunit": 2262
        },
        "tax_amount": 3.61,
        "tax_amount_details": {
          "currency": "EUR",
          "formatted": "3.61 €",
          "in_subunit": 361
        }
      },
      "retail_costs": []
    }
  }
}
```

{% endcode %}

## Troubleshooting

### Not receiving webhooks?

{% stepper %}
{% step %}

### Verify webhook URL

Verify your webhook URL is correctly configured in Store Settings.
{% endstep %}

{% step %}

### Check endpoint accessibility

Ensure your endpoint is publicly accessible (not behind a firewall).
{% endstep %}

{% step %}

### Return correct status

Check that your endpoint returns a `200 OK` response.
{% endstep %}

{% step %}

### Verify SSL

Verify your SSL certificate is valid (HTTPS required).
{% endstep %}
{% endstepper %}
