# POST /v2/webhooks/{id}/test

**Test fire a webhook**

Fires a real-shape `webhook.fired` payload to the webhook's `target_url` synchronously. The request body is **byte-identical** to a real fire — same field set, same signing, same `X-Tickerbot-Signature` HMAC — so tools that introspect payload shape (n8n, Zapier, custom field mappers) lock the right schema the first time. The test marker rides in an `X-Tickerbot-Test: true` HTTP header (not the body), so receivers that don't care get a payload indistinguishable from production, and those that do can filter on the header. Use this any time to validate endpoint reachability, payload parsing, and signature verification.

## Plan access

- **Plan access.** Paid plans (Hobby and above).
- **Cadence.** Real-time on every paid plan — evaluated on every data refresh (~1×/min), so a match is delivered within seconds of it landing. Optionally throttle a webhook to hourly or at-market-open.
- **Capacity.** Hobby 10 · Pro 100 · Scale 1,000 · Enterprise unlimited.

## Body parameters

| Name | In | Type | Required | Description |
|------|----|----|----------|-------------|
| `id` | path | string | yes | Webhook id. Example: `wh_smRsF3-z36o`. |

## Status codes

- **202** — The inline delivery outcome — `delivered` true/false, `http_status` from your endpoint, `elapsed_ms` for the round trip, and `error` (if any). One-shot: a failed test fire is recorded as `permanent_failure` and is NOT retried (test fires never enter the standard retry ladder, and never trigger auto-disable on the parent webhook). Call `/test` again to re-test after fixing your receiver.
- **400** — The webhook has no `target_url` (in-app deliveries have nothing to fire over the wire).
- **404** — Webhook not found.

## Sample response

```json
{
  "as_of": "2026-06-26T18:41:01.000Z",
  "id": "dlv_abc123def456ghi7",
  "webhook_id": "wh_smRsF3-z36o",
  "status": "delivered",
  "delivered": true,
  "http_status": 200,
  "elapsed_ms": 142,
  "error": null,
  "test": true,
  "created_at": 1782849661
}
```

## Examples

### Validate your endpoint

Request:

```shell
curl -X POST "https://api.tickerbot.io/v2/webhooks/wh_smRsF3-z36o/test" \
  -H "Authorization: Bearer YOUR_KEY"
```

Response (`202`):

```json
{
  "as_of": "2026-06-26T18:41:01.000Z",
  "id": "dlv_abc123def456ghi7",
  "webhook_id": "wh_smRsF3-z36o",
  "status": "delivered",
  "delivered": true,
  "http_status": 200,
  "elapsed_ms": 142,
  "error": null,
  "test": true,
  "created_at": 1782849661
}
```

## Notes

- The POSTed body uses the canonical `webhook.fired` shape (`event`, `webhook_id`, `name`, `q`, `as_of`, `matches`, `current_matches`, `matched_count`, `current_match_count`) with one synthetic match (`TBOT`) populated for every column the rule references. No `test` field on the body — the marker is in the `X-Tickerbot-Test: true` header.
- Test fires are ONE-SHOT: failed deliveries are recorded as `permanent_failure` and never retried. They also never trigger auto-disable on the parent webhook (only real-fire `permanent_failure` does that).
- Test deliveries are persisted with `test: true` on the delivery row and appear in /v2/webhooks/{id}/deliveries alongside real ones.

---

Interactive sandbox + parameter editor: https://tickerbot.io/docs/endpoints/webhooks/test
