> ## Documentation Index
> Fetch the complete documentation index at: https://docs.xquik.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Twitter webhook test & signed delivery check

> Send a signed test event to a webhook URL. Verify HTTPS reachability, response status, and signature handling. The test changes no webhook state and is free.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-webhooks-test-200">
      ```json theme={null}
      {
        "success": true,
        "statusCode": 200
      }
      ```
    </Tab>

    <Tab title="400" id="response-webhooks-test-400">
      ```json theme={null}
      {
        "error": "invalid_input",
        "message": "Invalid input. Check the request body."
      }
      ```
    </Tab>

    <Tab title="401" id="response-webhooks-test-401">
      ```json theme={null}
      {
        "error": "unauthenticated",
        "message": "Authentication required. Provide a valid API key or bearer token."
      }
      ```
    </Tab>

    <Tab title="404" id="response-webhooks-test-404">
      ```json theme={null}
      {
        "error": "not_found",
        "message": "Resource not found."
      }
      ```
    </Tab>

    <Tab title="429" id="response-webhooks-test-429">
      ```json theme={null}
      {
        "error": "rate_limit_exceeded",
        "message": "Too many requests. Try again later.",
        "retryAfter": 60
      }
      ```
    </Tab>
  </Tabs>
</Panel>

<blockquote className="agent-llms-directive">
  For the complete documentation index, see <a href="/llms.txt">llms.txt</a>.
</blockquote>

<Callout icon="circle-check" color="#16a34a">
  **Free.** This endpoint does not consume credits.
</Callout>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://xquik.com/api/v1/webhooks/15/test \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    | jq --arg webhook_id "15" '{
      webhook_id: $webhook_id,
      accepted: (.success == true),
      status_code: .statusCode,
      error: (.error // null)
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/webhooks/15/test", {
    method: "POST",
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
  const result = await response.json();
  const testOutcome = {
    webhook_id: "15",
    accepted: result.success === true,
    status_code: result.statusCode,
    error: result.error ?? null,
  };
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      "https://xquik.com/api/v1/webhooks/15/test",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
  )
  result = response.json()
  test_outcome = {
      "webhook_id": "15",
      "accepted": result["success"] is True,
      "status_code": result["statusCode"],
      "error": result.get("error"),
  }
  ```

  ```go Go theme={null}
  package main

  import (
    "encoding/json"
    "log"
    "net/http"
  )

  type TestOutcome struct {
    WebhookID  string  `json:"webhook_id"`
    Accepted   bool    `json:"accepted"`
    StatusCode int     `json:"status_code"`
    Error      *string `json:"error"`
  }

  func main() {
  	req, err := http.NewRequest("POST", "https://xquik.com/api/v1/webhooks/15/test", nil)
  	if err != nil {
  		log.Fatal(err)
  	}
  	req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")

  	resp, err := http.DefaultClient.Do(req)
  	if err != nil {
  		log.Fatal(err)
  	}
  	defer resp.Body.Close()

    var result struct {
      Error      *string `json:"error"`
      StatusCode int     `json:"statusCode"`
      Success    bool    `json:"success"`
    }
    if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
  		log.Fatal(err)
  	}
    outcome := TestOutcome{
      WebhookID:  "15",
      Accepted:   result.Success,
      StatusCode: result.StatusCode,
      Error:      result.Error,
    }
    _ = outcome
  }
  ```
</CodeGroup>

These snippets build a small deployment-check record. Store `accepted`,
`status_code`, and `error` with the webhook ID. Do not print the full
test response.

## Path parameters

<ParamField path="id" type="string" required>
  The webhook ID to test.
</ParamField>

## Headers

<ParamField header="x-api-key" type="string" required>
  Your API key. This endpoint also accepts session cookie authentication.
</ParamField>

## What happens

Xquik sends a `webhook.test` event to your endpoint, HMAC-signed with the webhook's secret:

```json Payload delivered to your endpoint theme={null}
{
  "eventType": "webhook.test",
  "data": {
    "message": "Test delivery from Xquik"
  },
  "timestamp": "2026-02-27T12:00:00.000Z"
}
```

The signed request includes the `X-Xquik-Signature`, `X-Xquik-Timestamp`, and
`X-Xquik-Nonce` headers. Verify the signature against the raw request body
before parsing JSON. Reject stale timestamps and reused nonces. Production
monitor deliveries need the same checks.

You can test active, paused, or needs-attention webhooks. This endpoint reports
whether the receiver accepted the signed test request. It does not change
`isActive`, `deliveryStatus`, or `consecutiveFailures`. Xquik keeps retrying
an active webhook. After a fix, call
[Resume Webhook](/api-reference/webhooks/resume). It runs the same test, then
starts sending waiting and rejected deliveries at once. It also reactivates a
paused webhook.

The test endpoint does not return or rotate the signing secret. Keep using the
secret returned by [Create Webhook](/api-reference/webhooks/create) for
signature verification. Keep raw request bodies, raw signatures, and full
headers out of deployment logs.

`webhook.test` payloads include `eventType`, `data`, and `timestamp`. They do
not include `deliveryId` or `streamEventId`. Use them for reachability and
signature checks. They cannot test receiver idempotency.

## Response

### 200 OK (success)

<ResponseField name="success" type="boolean">
  `true` when your endpoint responded with a 2xx status code.
</ResponseField>

<ResponseField name="statusCode" type="number">
  The HTTP status code returned by your endpoint.
</ResponseField>

```json theme={null}
{
  "success": true,
  "statusCode": 200
}
```

### 200 OK (delivery failed)

<ResponseField name="success" type="boolean">
  `false` when your endpoint returned a non-2xx status or was unreachable.
</ResponseField>

<ResponseField name="statusCode" type="number">
  The HTTP status code returned by your endpoint, or `0` if unreachable.
</ResponseField>

<ResponseField name="error" type="string">
  Error description (for example `"HTTP 500"` or a network error message).
</ResponseField>

```json theme={null}
{
  "success": false,
  "statusCode": 500,
  "error": "HTTP 500"
}
```

### 400 Invalid request

```json theme={null}
{ "error": "invalid_id", "message": "Invalid webhook ID format" }
```

The provided webhook ID is not a valid format.

### 401 Unauthenticated

```json theme={null}
{ "error": "unauthenticated", "message": "Missing or invalid API key" }
```

Missing or invalid API key or session cookie.

### 404 Not found

```json theme={null}
{ "error": "not_found", "message": "Webhook not found" }
```

No webhook exists with this ID, or it belongs to a different account.

### 429 Rate limited

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Too many requests. Try again later.",
  "retryAfter": 60
}
```

Too many requests. Wait for the `Retry-After` header before retrying.

## Test result handoff

Use this endpoint before routing production monitor events to a new receiver or
after changing webhook code, secrets, firewall rules, or queue routing.

<CardGroup cols={2}>
  <Card title="Receiver accepted" icon="circle-check">
    Treat `success: true` and a `2xx` `statusCode` as proof that the receiver
    accepted the signed `webhook.test` request.
  </Card>

  <Card title="Receiver rejected" icon="triangle-alert">
    Treat `success: false` with a non-`2xx` `statusCode` as a receiver error.
    Fix the endpoint before waiting for the next production monitor event.
  </Card>

  <Card title="Endpoint unreachable" icon="wifi-off">
    Treat `statusCode: 0` as a network or reachability failure. Check DNS,
    TLS, firewall rules, and the public HTTPS URL.
  </Card>

  <Card title="Error string" icon="triangle-alert">
    Store `error` with your deployment logs so support, queue, or incident
    workers can see the latest test failure reason.
  </Card>

  <Card title="Paused or needs attention" icon="toggle-left">
    Xquik still sends tests to paused and needs-attention webhooks. A passing test
    proves reachability only. Use [Resume Webhook](/api-reference/webhooks/resume)
    to reactivate a paused webhook. It also starts sending waiting deliveries at
    once.
  </Card>

  <Card title="Signature path" icon="shield-check">
    Validate `X-Xquik-Signature`, `X-Xquik-Timestamp`, and
    `X-Xquik-Nonce` on the raw request body before accepting test or production
    events.
  </Card>

  <Card title="Test payload" icon="braces">
    `webhook.test` payloads include `eventType`, `data`, and `timestamp`.
    They do not include `deliveryId` or `streamEventId`.
  </Card>

  <Card title="Production triage" icon="activity">
    After the receiver accepts this signed test, use
    [List Deliveries](/api-reference/webhooks/deliveries) to debug real monitor
    events. Delivery rows contain `id`, `streamEventId`, `status`, `attempts`,
    `lastStatusCode`, `lastError`, `createdAt`, and `deliveredAt`.
  </Card>

  <Card title="Event join" icon="link">
    For failed production deliveries, use delivery `streamEventId`
    as the `{id}` for [Get Event](/api-reference/events/get). Store the event
    `monitorId`, `monitorType`, `type`, `occurredAt`, and `data` with the
    receiver incident.
  </Card>
</CardGroup>

<Note>
  This endpoint accepts 2 auth methods. Send an API key in the `x-api-key` header or a session cookie from the dashboard.

  **Related.** [List Webhooks](/api-reference/webhooks/list) · [Resume Webhook](/api-reference/webhooks/resume) · [List Deliveries](/api-reference/webhooks/deliveries) · [Get Event](/api-reference/events/get) · [Webhook Verification](/webhooks/verification)
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.