Webhook
Listen for events from your n1co business account at your webhook connection point so your integration can trigger automatic reactions as events occur in your account.
Why use webhooks
When creating integrations with n1co Business, you may want your applications to receive events as they occur in your account, so that your back-end systems can execute the necessary actions.
To enable webhook events, you must register webhook connection points. After registering them, n1co Business can send real-time event data to your application's connection point when events occur. n1co Business uses HTTPS to send webhook events to your application as a JSON payload that includes an event object.
Receiving webhook events is particularly useful for listening to asynchronous events, for example, when an order is created, paid or cancelled, when the shipping status of an order is updated, etc.
Webhook configuration
To set up a webhook hotspot, you must provide a hotspot URL and generate a secret key. The connection point URL is the URL to which n1co Business will send webhook events. The secret key is a string used to sign webhook events that are sent to your application. You can use the secret key to verify that the events you receive are coming from n1co Business.
Creating a webhook connection point
To create a webhook connection point, follow these steps:
- Log in to your n1co business account
- In the menu on the top right, click Settings
- In the Options for developers section, click Webhook
- Add your webhook hotspot URL and generate a secret key, then click Save Changes.
- You are done! Your webhook hotspot is ready to receive events from n1co business
Webhook events
n1co Business sends webhook events to your connection point in real time. Each webhook event includes an event object that contains information about the event that occurred in your n1co Business account. Webhook events events are sent as JSON payloads in an HTTPS POST request to your connection point.
Request headers
Every delivery reaches your connection point with these headers:
| Header | Description |
|---|---|
X-H4B-Hmac-Sha256 | Base64 HMAC-SHA256 of the raw request body, signed with your secret key. See Verification of webhook events |
X-H4B-Event-Id | Numeric identifier of the event. It does not change across resends of the same event: deduplicate on it |
X-H4B-Event-Created | UTC timestamp (ISO 8601) of when the event was originated. It does not change across resends either |
The body and the signature are unchanged from previous versions; X-H4B-Event-Id and X-H4B-Event-Created
are additional headers.
- When your store has several URLs configured (separated by
;), each URL receives its ownX-H4B-Event-Idfor the same event. X-H4B-Event-Idcan also be used to look the event up through the API:GET /api/v3/WebhookEvents/{eventId}returns the first delivery of the event. See Recovering events you failed to process.- If a new delivery cannot be logged on our side (for example, during an outage), the event is still sent,
but without
X-H4B-Event-IdandX-H4B-Event-Created, and it will not appear in the delivery history nor can it be resent. Deduplicate those deliveries by their payload.
Delivery and retries
- At least once, best effort. A delivery is retried 3 times within a few seconds on connection errors,
5xxresponses and408. After that it is not retried automatically. The same event can arrive more than once, and events can arrive out of order. - Deduplicate on
X-H4B-Event-Id. Keep the identifiers you already processed and discard repeats; it is the only reliable way of not processing the same event twice. - Acknowledge fast. Reply
2xxas soon as the payload is stored on your side and process it asynchronously. Any other status marks the delivery as not delivered. - The API is the source of truth. Use the webhook as a signal and confirm the state with
GET /api/v3/Orders/{id}when it matters, for example before releasing goods. - Verify the signature over the raw bytes of the body, before parsing it, with a constant-time comparison.
- Anything that falls through the automatic retries can be recovered with the webhook events API.
Event object
The contract for webhook events is as follows:
{
"orderId": "String!",
"orderReference": "String",
"orderType": "String!",
"description": "String!",
"level": "String!",
"type": "String!",
"metadata": "Object"
}
The definition of the fields of the event object is as follows:
orderId: String! -> internal identifier of the order generated by the n1co system
orderReference: String -> order reference provided by the integrator
orderType: String! -> type of order that originated the event
description: String! -> event description message
level: String! -> severity level of the event
type: String! -> event type
metadata: Object -> key-value object containing additional information about event
Severity Levels level
- Info: Indicates general information or events that do not require immediate attention.
- Warning: Indicates situations that may require attention or investigation, but do not represent a critical error or system failure.
- Error: Indicates a system error that requires attention.
Order types orderType
Tells you what kind of order originated the event. It is present on every event, and lets you separate a coupon or giftcard purchase from a regular sale without calling back into the API.
| Value | Order |
|---|---|
COUPON_APP | Coupon purchase |
GIFTCARDS | Giftcard purchase |
FASTLINK_CHARGE | Payment link |
FULL | Full order |
STOREFRONT | Storefront |
SUBSCRIPTION | Subscription |
MENU_APP | Menu app |
EPAY | EPay |
SUPER_APP | SuperApp |
COURIER | Courier delivery |
MARKETPLACE | n1co plaza |
type and orderType are not the same thingtype is the event type (Created, SuccessPayment, …). orderType is the type
of order that originated it. One order emits several events with different type
values, but all of them carry the same orderType.
Note as well that orders created from a payment link arrive as FASTLINK_CHARGE, not as
FULL.
Event types type
Created
This event indicates that a new order has been created in n1co business.
Example:
{
"orderId": "1057",
"orderReference": "test-3",
"orderType": "FASTLINK_CHARGE",
"description": "La orden fue creada",
"metadata": null,
"level": "Info",
"type": "Created"
}
SuccessPayment
This event indicates that the payment of an order has been successful.
Example:
{
"orderId": "52544",
"orderReference": null,
"orderType": "COUPON_APP",
"description": "La orden fue pagada exitosamente autorización: 831000",
"metadata": {
"PaymentId": "3aaf6eaf-f32f-4857-8312-e63f4e497822",
"ChargeId": "af543e17-18d9-4512-b1ba-2991b6c31613",
"Status": "SUCCEEDED",
"AuthorizationCode": "831000",
"SequentialNumber": "7744791861156741504807",
"AccountId": "hugoapp.h4b",
"PaymentProcessor": "cybersource",
"PaymentProcessorReference": "7744791861156741504807",
"TransactionDate": "2026-03-25T22:53:06.6475595Z",
"PaidAmount": "8.00",
"BuyerName": "Juan Pérez",
"BuyerPhone": "+50370000000",
"BuyerEmail": "[email protected]",
"BuyerExternalId": "6x1ekkKH1a",
"CheckoutNote": "N/A",
"OrderReference": "",
"OrderTotalDetails": {
"subtotal": "8.0000",
"shippingAmount": "0",
"discountAmount": "0",
"surchargeAmount": "0",
"total": "8.00"
},
"IsManagedPaymentMethod": false,
"InvoiceName": "",
"InvoiceAddress": "",
"InvoiceTaxCode": "",
"orderDetail": [
{
"orderItemId": "13188",
"itemId": "30666",
"name": "Coconut Shrimp",
"price": "8.0000",
"promoId": null,
"promoPrice": null,
"promoName": null,
"quantity": "1",
"modifiersTotal": "0.0000",
"sku": "DL100",
"productImageUrl": "https://cdn.h4b.dev/images/.../Image1.webp",
"modifiers": [],
"note": null,
"description": "8 Camarones empanizados con coco rallado...",
"quantityAvailable": "75",
"requiresShipping": false,
"productMetadata": null,
"coupon": {
"code": "U6FWUW",
"qrCodeUrl": "https://qr.n1co.shop/?chl=U6FWUW",
"startDate": "2026-01-06T18:00:00",
"endDate": "2026-03-31T18:00:00",
"redemptionLimit": "1",
"redemptionCount": "0",
"status": "Unredeemed"
}
}
]
},
"level": "Info",
"type": "SuccessPayment"
}
metadata fields in SuccessPayment
| Field | Type | Description |
|---|---|---|
PaymentId | String | Unique payment identifier |
ChargeId | String | Unique charge identifier |
Status | String | Payment status (SUCCEEDED) |
AuthorizationCode | String | Transaction authorization code |
SequentialNumber | String | Transaction sequential number |
AccountId | String | Merchant account identifier |
PaymentProcessor | String | Payment processor used |
PaymentProcessorReference | String | Payment processor reference |
TransactionDate | String | Transaction date and time (ISO 8601) |
PaidAmount | String | Amount paid |
BuyerName | String | Buyer's name |
BuyerPhone | String | Buyer's phone number |
BuyerEmail | String | Buyer's email |
BuyerExternalId | String | Buyer's external identifier |
CheckoutNote | String | Checkout note |
OrderReference | String | Order reference provided by the integrator |
OrderTotalDetails | Object | Order totals breakdown (subtotal, shippingAmount, discountAmount, surchargeAmount, total) |
IsManagedPaymentMethod | Boolean | Indicates if the payment method is managed by n1co |
InvoiceName | String | Billing name |
InvoiceAddress | String | Billing address |
InvoiceTaxCode | String | Tax code for billing |
orderDetail | Array | Order product details (see table below) |
Product details orderDetail
| Field | Type | Description |
|---|---|---|
orderItemId | String | Order item identifier |
itemId | String | Product identifier |
name | String | Product name |
price | String | Product unit price |
promoId | String | null | Applied promotion identifier |
promoPrice | String | null | Promotional price |
promoName | String | null | Promotion name |
quantity | String | Product quantity |
modifiersTotal | String | Total of applied modifiers |
sku | String | Product SKU |
productImageUrl | String | Product image URL |
modifiers | Array | List of modifiers applied to the product |
note | String | null | Product note |
description | String | Product description |
quantityAvailable | String | Available inventory quantity |
requiresShipping | Boolean | Indicates if the product requires shipping |
productMetadata | Object | null | Additional product metadata |
coupon | Object | null | Coupon associated with the product (see table below). Is null if the product has no coupon |
coupon object
When a product has an associated coupon, the coupon field contains the coupon information generated for that purchase.
| Field | Type | Description |
|---|---|---|
code | String | Coupon code |
qrCodeUrl | String | QR code URL for the coupon |
startDate | String | Coupon validity start date (ISO 8601) |
endDate | String | Coupon expiration date (ISO 8601) |
redemptionLimit | String | Maximum number of times the coupon can be redeemed |
redemptionCount | String | Number of times the coupon has been redeemed |
status | String | Current coupon status |
Possible coupon statuses (status):
Unredeemed: The coupon is active and available for redemptionRedeemed: The coupon has reached its redemption limitExpired: The coupon has expired (current date is pastendDate)Scheduled: The coupon is not yet active (current date is beforestartDate)
Cancelled
This event indicates that an order has been cancelled.
Example:
{
"orderId": "32395",
"orderReference": null,
"description": "La orden fue cancelada, motivo: some reason",
"metadata": null,
"level": "Info",
"type": "Cancelled"
}
Finalized
This event indicates that an order has been finalized.
Ejemplo:
{
"orderId": "32395",
"orderReference": null,
"description": "Se finalizó la orden.",
"metadata": null,
"level": "Info",
"type": "Finalized"
}
Updated
This event indicates that the shipping status of an order in n1co business has been updated.
List of shipping statuses:
PENDING: Order pendingACCEPTED: Order acceptedREADY: Order readyDISPATCHED: Order dispatchedON_ITS_WAY: Order on the wayDELIVERED: Order deliveredSCHEDULED: Scheduled orderREJECTED: Order rejected
Examples:
For status change from PENDING to ACCEPTED:
{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de Pendiente a Aceptado",
"metadata": {
"PreparationEtaMinutes": "15",
"PreviousStatus": "PENDING",
"NewStatus": "ACCEPTED"
},
"level": "Info",
"type": "Updated"
}
For the change of status from ACCEPTED to READY:
{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de Aceptado a Preparado",
"metadata": {
"PreviousStatus": "ACCEPTED",
"NewStatus": "READY"
},
"level": "Info",
"type": "Updated"
}
For the status change from READY to DISPATCHED:
{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de Preparado a Despachado",
"metadata": {
"PreviousStatus": "READY",
"NewStatus": "DISPATCHED"
},
"level": "Info",
"type": "Updated"
}
For the status change from DISPATCHED to ON_ITS_WAY:
{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de Despachado a En Camino",
"metadata": {
"PreviousStatus": "DISPATCHED",
"NewStatus": "ON_ITS_WAY"
},
"level": "Info",
"type": "Updated"
}
For the change of status from ON_ITS_WAY to DELIVERED:
{
"orderId": "13766",
"orderReference": null,
"description": "Se cambió el estado del envío de En Camino a Entregado",
"metadata": {
"PreviousStatus": "ON_ITS_WAY",
"NewStatus": "DELIVERED"
},
"level": "Info",
"type": "Updated"
}
Deleted
This event indicates that an order has been deleted.
Example:
{
"orderId": "32395",
"orderReference": null,
"description": "Se eliminó la orden",
"metadata": null,
"level": "Info",
"type": "Deleted"
}
SuccessReverse
This event indicates that a payment reversal was successful.
Example:
{
"orderId": "1056",
"orderReference": null,
"description": "El pago de la orden fue revertido",
"metadata": null,
"level": "Info",
"type": "SuccessReverse"
}
ReverseError
This event indicates that an error occurred while attempting to reverse a payment.
Example:
{
"orderId": "1056",
"orderReference": null,
"description": "La orden no pudo ser cancelada, no se pudo revertir el pago",
"metadata": null,
"level": "Error",
"type": "ReverseError"
}
PaymentError
This event indicates that an error occurred while attempting to make a payment.
Example:
{
"orderId": "1056",
"orderReference": null,
"description": "El pago no fue realizado: some error",
"metadata": null,
"level": "Error",
"type": "PaymentError"
}
ThreeDSecureAuthSucceeded
This event indicates that the 3DS authentication was successfully completed for a specific collection and therefore you can proceed with the transaction confirmation using the authenticationId provided in the metadata of the event.
Example:
{
"orderId": "31833",
"orderReference": "order-integration-id",
"description": "La autenticación 3DS ha sido completada con éxito",
"metadata": {
"authenticationId": "fdedee2f-5942-47ff-83a5-cb473d0e8764"
},
"level": "Info",
"type": "ThreeDSecureAuthSucceeded"
}
ThreeDSecureAuthError
This event indicates that an error occurred during 3DS authentication for a specific charge. The error may be due to several reasons, such as incorrect cardholder information, technical problems with the 3DS authentication provider, or connectivity issues. Further details can be found in the reason and description attributes included in the metadata of the event.
Example:
{
"orderId": "31833",
"orderReference": "order-integration-id",
"description": "Ocurrió un error en la autenticación 3DS",
"metadata": {
"authenticationId": "fdedee2f-5942-47ff-83a5-cb473d0e8764",
"reason" : "Some reason",
"description" : "Some description",
},
"level": "Error",
"type": "ThreeDSecureAuthError"
}
ThreeDSecureAuthExpired
This event is an indicator that the 3DS authentication was not completed on time and the transaction cannot be completed at this time. The transaction can be reattempted later once the cardholder initiates a new authentication request.
Example:
{
"orderId": "31833",
"orderReference": "order-integration-id",
"description": "La autenticación 3DS ha expirado",
"metadata": {
"authenticationId": "fdedee2f-5942-47ff-83a5-cb473d0e8764"
},
"level": "Info",
"type": "ThreeDSecureAuthExpired"
}
ThreeDSecureAuthFailed
This event indicates that there was a technical failure that prevented 3DS authentication from completing successfully for a specific request. The failure may be due to problems with the 3DS authentication provider, integration issues, or server-side issues. Further details can be found in the reason and description attributes included in the metadata of the event.
Example:
{
"orderId": "31833",
"orderReference": "order-integration-id",
"description": "Ocurrió un fallo en la autenticación 3DS",
"metadata": {
"authenticationId": "fdedee2f-5942-47ff-83a5-cb473d0e8764",
"reason" : "Some reason",
"description" : "Some description",
},
"level": "Error",
"type": "ThreeDSecureAuthFailed"
}
Verification of webhook events
To verify that the webhook events you receive are coming from n1co buiness, you can use the secret key that you generated when you set up your webhook connection point. To verify a webhook event, follow these steps:
- Extract the value of the
X-H4B-Hmac-Sha256header from the HTTP POST request containing the webhook event. - Calculate the HMAC SHA-256 of the raw bytes of the HTTP POST request body, before parsing it, using the secret key generated when you set up your webhook.
- Compare the Base64 result with the header value using a constant-time comparison.
Example of webhook event verification
Node.js
const crypto = require("crypto");
const express = require("express");
const app = express();
// Use the raw body exactly as received; do not re-serialize it
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
// Secret key configured in the n1co Business portal (Settings → Webhook)
const API_SECRET = process.env.API_SECRET;
// Signature sent by n1co (Base64)
const hmacHeader = req.get("X-H4B-Hmac-Sha256") || "";
// Compute the HMAC SHA-256 of the raw body and encode it as Base64
const hash = crypto.createHmac("sha256", API_SECRET).update(req.body).digest("base64");
// Constant-time comparison
const expected = Buffer.from(hash);
const received = Buffer.from(hmacHeader);
if (expected.length !== received.length || !crypto.timingSafeEqual(expected, received)) {
console.log("Invalid signature");
return res.sendStatus(401);
}
const event = JSON.parse(req.body.toString("utf8"));
console.log("Valid signature", event.type);
res.sendStatus(200);
});
Python
import base64
import hashlib
import hmac
import os
from flask import Flask, request, abort
app = Flask(__name__)
@app.route("/webhook", methods=["POST"])
def webhook():
# Secret key configured in the n1co Business portal (Settings → Webhook)
api_secret = os.environ["API_SECRET"]
# Signature sent by n1co (Base64)
hmac_header = request.headers.get("X-H4B-Hmac-Sha256", "")
# Use the raw body exactly as received; do not re-serialize it
raw_body = request.get_data()
# Compute the HMAC SHA-256 of the raw body and encode it as Base64
digest = hmac.new(api_secret.encode("utf-8"), raw_body, hashlib.sha256).digest()
expected = base64.b64encode(digest).decode("ascii")
# Constant-time comparison
if not hmac.compare_digest(expected, hmac_header):
print("Invalid signature")
abort(401)
event = request.get_json()
print("Valid signature", event.get("type"))
return "", 200
if __name__ == "__main__":
app.run()
PHP
<?php
// Secret key configured in the n1co Business portal (Settings → Webhook)
$apiSecret = getenv("API_SECRET");
// Signature sent by n1co (Base64)
$hmacHeader = $_SERVER["HTTP_X_H4B_HMAC_SHA256"] ?? "";
// Use the raw body exactly as received; do not re-serialize it
$rawBody = file_get_contents("php://input");
// Compute the HMAC SHA-256 of the raw body and encode it as Base64
$expected = base64_encode(hash_hmac("sha256", $rawBody, $apiSecret, true));
// Constant-time comparison
if (!hash_equals($expected, $hmacHeader)) {
echo "Invalid signature";
http_response_code(401);
exit;
}
$event = json_decode($rawBody, true);
echo "Valid signature";
http_response_code(200);
Recovering events you failed to process
If your connection point was down or answered with an error, you do not need to ask the store for anything: the integration API exposes the delivery history of your webhook and lets you resend deliveries.
| Base URL | https://api.n1co.com/api/v3 |
| Authentication | The same Bearer token as the rest of the API, obtained with your client credentials (clientId / clientSecret) |
| Scope | Every call only sees the deliveries of the store bound to your credentials |
| Method | Path | Purpose |
|---|---|---|
GET | /WebhookEvents | List deliveries, newest first, paginated |
GET | /WebhookEvents/{id} | Get one delivery |
POST | /WebhookEvents/{id}/Resend | Send a delivery's payload again, synchronously |
Deliveries and events
- Delivery: one HTTP
POSTof a webhook to one URL. Every delivery is logged and has anid. Ids only grow over time. - Event: the thing that happened, such as a payment. An event has one or more deliveries: the first
one, plus one per resend. Its
eventIdis theidof its first delivery, soGET /api/v3/WebhookEvents/{eventId}returns that first delivery.
The delivery object
{
"id": 1201,
"eventId": 1201,
"eventType": "SuccessPayment",
"eventCreated": "2026-09-02T15:04:05Z",
"url": "https://example.com/n1co/webhook",
"payload": "{\"orderId\":\"123\",\"type\":\"SuccessPayment\"}",
"responseStatusCode": 503,
"delivered": false,
"created": "2026-09-02T15:04:05"
}
| Field | Type | Description | Filter / sort |
|---|---|---|---|
id | Integer | Identifier of this delivery | Yes |
eventId | Integer | Identifier of the event, shared by the original delivery and its resends. Equals id on a first delivery, and is the value sent in X-H4B-Event-Id | No |
eventType | String | Event type, the same type of the event object | Yes |
eventCreated | String | UTC timestamp of the original event. Unchanged across resends | No |
url | String | URL this delivery was sent to | No |
payload | String | The exact body that was sent, as a JSON string | No |
responseStatusCode | Integer | HTTP status your connection point answered with. 0 means the delivery has not completed. 500 also covers connection failures and timeouts | Yes |
delivered | Boolean | true when your connection point answered 2xx | Yes |
created | String | UTC timestamp of when this delivery was logged | Yes |
All timestamps are UTC. The signing key and the request and response headers are never returned.
List deliveries
GET /api/v3/WebhookEvents lists the deliveries of your store.
| Default | |
|---|---|
| Filter | None: every delivery of the store, delivered, failed, in progress and resends |
| Order | Newest first, by id descending |
page | 1 when omitted. Values below 1 are rejected with 400 |
pageSize | 50 when omitted. Values above 100 become 100. Values of 0 or below are rejected with 400 |
Query parameters, the same filtering, sorting and paging parameters as the rest of the v3 API:
| Parameter | Example | Notes |
|---|---|---|
filters | delivered==false,id%3E1150 | A comma means AND. Operators: ==, !=, >, <, >=, <=, @= (contains) and _= (starts with). URL-encode the value: a raw < or > in the query string is rejected with 404, so id>1150 is sent as id%3E1150 |
sorts | id or -id | Replaces the default order. A - prefix sorts descending |
page | 1 | 1-based |
pageSize | 100 | Max 100 |
Response:
{
"webhookEvents": [ { "...": "delivery object" } ],
"totalCount": 1
}
totalCount counts every delivery that matches filters, across all pages.
Recommended usage: poll with an id cursor
Use the delivery id as a cursor instead of page numbers: page numbers shift as new deliveries arrive,
and the cursor does not.
- Keep the last delivery
idyou processed. - Request what comes after it, oldest first:
Always send
GET /api/v3/WebhookEvents?filters=id%3E1150&sorts=id&pageSize=100sorts=idwhen polling. Without it the list is newest first, and a page after your cursor skips the older deliveries in between. - Process the page, set the cursor to the last
idin it, and repeat on page 1 until a page comes back empty. - To recover an event, feed its
payloadto the same handler that serves your webhook connection point. You only need to resend when you want an actual HTTP delivery again.
To look only at failures, add delivered==false:
GET /api/v3/WebhookEvents?filters=delivered==false,id%3E1150&sorts=id&pageSize=100
payload is the exact body that was sent to your URL, so the simplest recovery is usually to feed it to
the same handler that serves your webhook connection point.
Pitfalls
- A failed delivery stays failed after a successful resend. The resend is a new delivery with the same
eventId, and the original keepsdelivered: false. Sodelivered==falsecan list events that have been delivered since. Group byeventId: an event is pending only while none of its deliveries hasdelivered: true. - Deduplicate on
eventId. It equals theX-H4B-Event-Idheader, so you can skip events you already processed from the live webhook. - A
responseStatusCodeof0means the delivery was still in flight or was cut short. Check it again before treating it as failed. - Filter on
id>whenever you can. Filters ondelivered,createdoreventTypewithout anid>cursor are slower for stores with a long history, and so is thetotalCountthat comes with every page. - Deliveries that could not be logged are missing. They arrived without
X-H4B-Event-IdandX-H4B-Event-Created(see Request headers); deduplicate those by payload.
Get one delivery
GET /api/v3/WebhookEvents/{id} returns one delivery object.
| Status | When |
|---|---|
200 | The delivery exists for your store |
404 | Unknown id, or it belongs to another store |
Resend a delivery
POST /api/v3/WebhookEvents/{id}/Resend sends the stored payload of delivery {id} again, synchronously,
and returns the new delivery.
- It is signed with the store's current webhook key and goes to its current configuration.
- It carries the original
X-H4B-Event-IdandX-H4B-Event-Created, so a consumer that deduplicates will recognize it. - It is logged as a new delivery with a new
idand the sameeventId. - Resending a resend keeps the original event id.
Which URL receives it:
| Store configuration | Target |
|---|---|
| The delivery's URL is still configured | That URL only. The match ignores surrounding spaces and letter case |
| The delivery's URL is no longer configured | Every configured URL. The response is a failed delivery if any failed, otherwise the last one |
The response is the new delivery object: its delivered field tells you right away whether your connection
point accepted it.
| Status | When |
|---|---|
200 | Sent. Check delivered in the body, since a 200 here does not mean your connection point accepted it |
400 | The store has no webhook configured, or its URL setting holds no URL |
404 | Unknown id, or it belongs to another store |
500 | The resend could not be logged. Retrying is safe, because every delivery carries the same X-H4B-Event-Id |
A resend arrives with the X-H4B-Event-Id of the original event. If you already processed that event,
your handler must discard it.
Known limitations
eventIdandeventCreatedcannot be used infiltersorsorts.- Automatic retries still stop after a few seconds. This API is the recovery path for anything that falls through.