Queues one event's sample payload for this endpoint: the payload the dashboard's webhook tester sends, built by the same code as the real event and marked test_mode: true, so a handler can tell a rehearsal from a real event. It is delivered like any other event, signed with the endpoint's signing secrets, on the retry ladder and into the delivery log (GET /webhooks/deliveries), on the dispatcher's next pass; an endpoint that is a hosted test inbox keeps it as it keeps any delivery. Only this endpoint receives it, and nothing is added to the event feed (GET /events): a rehearsal about an order that does not exist is not an event of the account's. Test keys only, since a sample is test traffic. Refused with 409 invalid_state, and details.reason, when the endpoint is paused or disabled (endpoint_inactive), takes live traffic only (live_only), or is not subscribed to the event (not_subscribed): each a case where the queue would hold or skip it. An order's event may go to an endpoint that takes both test and live traffic, where a test order's real events already arrive; an account event (one about the account rather than an order, such as product.updated), whose real counterpart carries no test_mode, goes only to an endpoint that takes test traffic alone, and is otherwise refused with takes_live_traffic. An integration-health alert (alert.opened, alert.resolved) is refused on every endpoint with alert_events_not_readable_by_test_key: a test key is shown no alert delivery in the delivery log, so it could never read the sample back; the dashboard's webhook tester sends it. An account sends at most 10 test events a minute, through this operation and the dashboard's webhook tester together, on top of the plan's own limit: one budget, spent by a send that has passed every check above, so a refusal spends none of it.
- Credential
- An API key in
x-api-key - Scopes
webhooks:manage
Parameters
idpath · stringrequiredIdempotency-Keyheader · string (uuid)Unique key for idempotent requests. If you retry a request with the same key within 24 hours, you receive the original response. The key is bound to the request payload: reusing it for a different payload returns 422
idempotency_key_reuserather than the original response, so a changed request is never silently dropped. The binding is over the JSON's content, not its bytes — keys in another order or other whitespace are the same request. Generate a new key for each new request. On an operation that moves money (an order, a batch, an item, a shipping or address change, a cancellation's refund), a key that cannot be checked because the idempotency ledger is unreachable is answered 503idempotency_unavailablewithRetry-After, and nothing runs or is charged: retry with the same key.
Request body application/json, required
eventstringrequiredThe event to rehearse, such as
order.shipped. Every event a subscription can name on this deployment (see /docs/webhooks#event-types) has a sample. One that is not offered here is 400 event_not_available; a name that is not an event, 400 validation_error withdetails.available.One of
order.createdorder.paidorder.in_productionorder.shippedorder.deliveredorder.cancelledorder.failedorder.updatedorder.quality_checkorder.issueorder.approval_requestedorder.approval_approvedorder.approval_declinedorder.approval_expiredproduct.updatedcatalog.syncedwebhook.disabledalert.openedalert.resolvednon-empty · at most 64 characters
Request
POST /api/v1/webhooks/{id}/test
curl -X POST "https://portal.printedsimply.com/api/v1/webhooks/whk_SV8d5wGm2kUnSwx_RhZfY9OE/test" \
-H "x-api-key: ps_test_YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: send-webhook-test-event-$(date +%s)" \
-d '{
"event": "order.shipped"
}'Response 202
Queued for this endpoint, not yet sent: the delivery log shows the attempt once the dispatcher makes it.
data
webhook_idstringrequiredThe endpoint the sample was queued for.
eventstringrequiredThe event whose sample was queued, as sent.
One of
order.createdorder.paidorder.in_productionorder.shippedorder.deliveredorder.cancelledorder.failedorder.updatedorder.reroutedorder.quality_checkorder.issueorder.approval_requestedorder.approval_approvedorder.approval_declinedorder.approval_expiredcampaign.openedcampaign.order_addedcampaign.closedcampaign.batch_in_productioncampaign.completeddesign.proof_sentdesign.changes_requesteddesign.approvedreturn.requestedreturn.approvedreturn.remake_createdreturn.resolvedreturn.rejecteddrop.openeddrop.saledrop.closeddrop.sold_outcheckout_link.salegift.claimedgift.expiredproduct.updatedcatalog.syncedwebhook.disabledalert.openedalert.resolvedautopilot.run.createdautopilot.run.awaiting_approvalautopilot.run.completedautopilot.run.failedautopilot.run.cancelleddesign_run.item_readydesign_run.completedguarantee.issuedguarantee.honoredguarantee.breachedguarantee.remediedqueuedintegerrequiredQueue rows written: one, for this endpoint.
at least 1
test_modebooleanrequiredAlways true: the sample's payload carries
test_mode: truetoo.Always
true
meta
pageintegertotalintegerlimitintegerThe page size actually applied, which is not necessarily the one asked for — the operation's own ceiling wins.
pagesintegertotaloverlimit, rounded up.next_cursorstring | nullOn a cursor-paged operation: send this back as
cursorfor the next page. Null on the last page. Absent on operations that do not page by cursor.has_morebooleanOn a list operation whose
metaisListMeta: whether another page follows this one.
{
"status": "success",
"data": {
"webhook_id": "whk_SV8d5wGm2kUnSwx_RhZfY9OE",
"event": "order.shipped",
"queued": 1,
"test_mode": true
},
"request_id": "4e3753e1-48dd-4313-bfd8-48e4af4e116a"
}Errors
test_mode_only — sent with a live key; validation_error — no
event, or one that is not an event (details.availablelists the ones that are); event_not_available — an event of a family this deployment does not offer; invalid_json.Missing, invalid or expired API key:
missing_api_key(none sent),invalid_api_key(unknown or revoked),key_expired(past the expiry set when it was created; create a new key).404Resource not found
invalid_state — nothing was queued, and
details.reasonsays why:endpoint_inactive(re-enable the endpoint),live_only(let it take test traffic) ornot_subscribed(add the event to its subscription), where a real event would not reach it either;takes_live_traffic, an account event for an endpoint that takes live traffic too (send it to a test-only endpoint or the hosted test inbox); oralert_events_not_readable_by_test_key, alert.opened or alert.resolved, which a test key is shown in no delivery log (send it from the dashboard's webhook tester).payload_too_large — the request body exceeded this route's byte cap (256 KB unless the route raises it with a written reason). It is refused before it is parsed, so nothing was created. Send fewer rows, or use the endpoint's own asynchronous door where it has one.
rate_limit_exceeded — more than 10 test events a minute from this account, counting the dashboard's webhook tester, which spends the same budget (only a send that passed the endpoint's checks spends it); nothing was queued. Or the plan's own per-minute or daily limit, as on every operation (see RateLimitError).
Retry-Aftersays when to send again.queue_unavailable — the event could not be queued just now, so nothing was sent; retry after
Retry-After.