> ## 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.

# Update Twitter webhook endpoint & event filters

> Change a webhook's HTTPS URL, its tweet and profile event filters, or its active delivery state. The signing secret stays the same. The call costs no credits.

<Panel>
  <Tabs defaultTabIndex={0} sync={false}>
    <Tab title="200" id="response-webhooks-update-200">
      ```json theme={null}
      {
        "id": "42",
        "url": "https://example.com/webhook",
        "eventTypes": [
          "tweet.new"
        ],
        "isActive": true,
        "consecutiveFailures": 0,
        "deliveryStatus": "active",
        "failureHardCap": 200,
        "createdAt": "2025-01-15T12:00:00Z"
      }
      ```
    </Tab>

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

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

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

    <Tab title="429" id="response-webhooks-update-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 PATCH https://xquik.com/api/v1/webhooks/15 \
    -H "x-api-key: xq_YOUR_KEY_HERE" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://new-server.com/webhook",
      "eventTypes": ["tweet.new"],
      "isActive": false
    }' | jq '{
      webhook_id: .id,
      url,
      event_types: .eventTypes,
      is_active: .isActive,
      delivery_status: .deliveryStatus,
      consecutive_failures: .consecutiveFailures,
      failure_hard_cap: .failureHardCap,
      test_endpoint: ("/api/v1/webhooks/" + .id + "/test"),
      resume_endpoint: ("/api/v1/webhooks/" + .id + "/resume"),
      deliveries_endpoint: ("/api/v1/webhooks/" + .id + "/deliveries")
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch("https://xquik.com/api/v1/webhooks/15", {
    method: "PATCH",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://new-server.com/webhook",
      eventTypes: ["tweet.new"],
      isActive: false,
    }),
  });
  const webhook = await response.json();
  const updateHandoff = {
    webhook_id: webhook.id,
    url: webhook.url,
    event_types: webhook.eventTypes,
    is_active: webhook.isActive,
    delivery_status: webhook.deliveryStatus,
    consecutive_failures: webhook.consecutiveFailures,
    failure_hard_cap: webhook.failureHardCap,
    test_endpoint: `/api/v1/webhooks/${webhook.id}/test`,
    resume_endpoint: `/api/v1/webhooks/${webhook.id}/resume`,
    deliveries_endpoint: `/api/v1/webhooks/${webhook.id}/deliveries`,
  };
  ```

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

  response = requests.patch(
      "https://xquik.com/api/v1/webhooks/15",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
      json={
          "url": "https://new-server.com/webhook",
          "eventTypes": ["tweet.new"],
          "isActive": False,
      },
  )
  webhook = response.json()
  update_handoff = {
      "webhook_id": webhook["id"],
      "url": webhook["url"],
      "event_types": webhook["eventTypes"],
      "is_active": webhook["isActive"],
      "delivery_status": webhook["deliveryStatus"],
      "consecutive_failures": webhook["consecutiveFailures"],
      "failure_hard_cap": webhook["failureHardCap"],
      "test_endpoint": f"/api/v1/webhooks/{webhook['id']}/test",
      "resume_endpoint": f"/api/v1/webhooks/{webhook['id']}/resume",
      "deliveries_endpoint": f"/api/v1/webhooks/{webhook['id']}/deliveries",
  }
  ```

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

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

  type Webhook struct {
    ConsecutiveFailures int      `json:"consecutiveFailures"`
    DeliveryStatus      string   `json:"deliveryStatus"`
    EventTypes          []string `json:"eventTypes"`
    FailureHardCap      int      `json:"failureHardCap"`
    ID                  string   `json:"id"`
    IsActive            bool     `json:"isActive"`
    URL                 string   `json:"url"`
  }

  type UpdateHandoff struct {
    ConsecutiveFailures int      `json:"consecutive_failures"`
    DeliveriesEndpoint string   `json:"deliveries_endpoint"`
    DeliveryStatus     string   `json:"delivery_status"`
    EventTypes         []string `json:"event_types"`
    FailureHardCap     int      `json:"failure_hard_cap"`
    IsActive           bool     `json:"is_active"`
    ResumeEndpoint     string   `json:"resume_endpoint"`
    TestEndpoint       string   `json:"test_endpoint"`
    URL                string   `json:"url"`
    WebhookID          string   `json:"webhook_id"`
  }

  func main() {
    payload := map[string]interface{}{
      "url":        "https://new-server.com/webhook",
      "eventTypes": []string{"tweet.new"},
      "isActive":   false,
    }
    body, err := json.Marshal(payload)
    if err != nil {
      log.Fatal(err)
    }

    req, err := http.NewRequest("PATCH", "https://xquik.com/api/v1/webhooks/15", bytes.NewReader(body))
    if err != nil {
      log.Fatal(err)
    }
    req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")
    req.Header.Set("Content-Type", "application/json")

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

    var webhook Webhook
    if err := json.NewDecoder(resp.Body).Decode(&webhook); err != nil {
      log.Fatal(err)
    }
    handoff := UpdateHandoff{
      ConsecutiveFailures: webhook.ConsecutiveFailures,
      DeliveriesEndpoint: "/api/v1/webhooks/" + webhook.ID + "/deliveries",
      DeliveryStatus:     webhook.DeliveryStatus,
      EventTypes:         webhook.EventTypes,
      FailureHardCap:     webhook.FailureHardCap,
      IsActive:           webhook.IsActive,
      ResumeEndpoint:     "/api/v1/webhooks/" + webhook.ID + "/resume",
      TestEndpoint:       "/api/v1/webhooks/" + webhook.ID + "/test",
      URL:                webhook.URL,
      WebhookID:          webhook.ID,
    }
    _ = handoff
  }
  ```
</CodeGroup>

These snippets build a reconfiguration row. Store the current webhook
configuration with its test and delivery-log endpoints. Do not print the
full update response.

| Webhook update column | Request or response source | Verification rule |
| - | - | - |
| Webhook ID | Path `{id}` and response `id` | Require both IDs to match. |
| Receiver URL | Request and response `url` | Confirm the intended HTTPS endpoint. |
| Event filter | Request and response `eventTypes` | Confirm the complete replacement list. |
| Active state | Request and response `isActive` | Verify the intended pause or activation. |
| Failure count | Response `consecutiveFailures` | Confirm whether activation reset failures. |
| Delivery state | Response `deliveryStatus` | Handle active, paused, and needs-attention receivers separately. |
| Failure cap | Response `failureHardCap` | Record the failure cap. |

## Path parameters

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

## Headers

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

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`.
</ParamField>

## Body

At least 1 field is required.

<ParamField body="url" type="string">
  New HTTPS endpoint URL. Xquik rejects HTTP URLs.
</ParamField>

<ParamField body="eventTypes" type="string[]">
  Updated event types to subscribe to. Replaces the existing list. At least 1
  required when provided. Use any valid account monitor event type listed below.
  Keyword monitor webhooks should stay on `tweet.*` event types. Account monitor
  webhooks can use both `tweet.*` and `profile.*` event types.
</ParamField>

## Valid event types

Valid types: `tweet.new`, `tweet.quote`, `tweet.reply`, `tweet.retweet`,
`tweet.media`, `tweet.link`, `tweet.poll`, `tweet.mention`, `tweet.hashtag`,
`tweet.longform`, `profile.avatar.changed`, `profile.banner.changed`,
`profile.name.changed`, `profile.username.changed`, `profile.bio.changed`,
`profile.location.changed`, `profile.url.changed`, `profile.verified.changed`,
`profile.protected.changed`, `profile.pinned_tweet.changed`,
`profile.unavailable.changed`.

<CardGroup cols={2}>
  <Card title="tweet.new" icon="bell">
    Original tweet from an account monitor or matching keyword monitor. Use for
    new posts that are not replies, quotes, or retweets.
  </Card>

  <Card title="tweet.quote" icon="quote">
    Quote tweet from an account monitor or matching keyword monitor. Keep this
    only when your systems handle quote payloads.
  </Card>

  <Card title="tweet.reply" icon="message-circle">
    Reply from an account monitor or matching keyword monitor. Keep this when
    reply alerts or support routing should continue.
  </Card>

  <Card title="tweet.retweet" icon="repeat-2">
    Retweet from an account monitor or matching keyword monitor. Keep this when
    repost activity should keep triggering deliveries.
  </Card>
</CardGroup>

<Note>
  Only the [Test Webhook](/api-reference/webhooks/test) endpoint generates `webhook.test`. You cannot add it to a webhook subscription.
</Note>

<ParamField body="isActive" type="boolean">
  Set to `false` to pause deliveries. Set to `true` to turn it on and start
  sending waiting deliveries at once. Either value resets `consecutiveFailures`
  to `0`. To require a signed test first, use
  [Resume Webhook](/api-reference/webhooks/resume).
</ParamField>

## Response

### 200 OK

<ResponseField name="id" type="string">
  Unique webhook identifier.
</ResponseField>

<ResponseField name="url" type="string">
  The current delivery endpoint URL.
</ResponseField>

<ResponseField name="eventTypes" type="string[]">
  Event types this webhook subscribes to.
</ResponseField>

<ResponseField name="isActive" type="boolean">
  Whether the webhook is active.
</ResponseField>

<ResponseField name="consecutiveFailures" type="number">
  Consecutive delivery failures recorded for this webhook.
</ResponseField>

<ResponseField name="deliveryStatus" type="string">
  `active`, `paused`, or `needs_attention`.
</ResponseField>

<ResponseField name="failureHardCap" type="number">
  Failure count that sets `needs_attention`. Delivery continues past it.
</ResponseField>

<ResponseField name="createdAt" type="string">
  ISO 8601 creation timestamp.
</ResponseField>

```json theme={null}
{
  "id": "15",
  "url": "https://new-server.com/webhook",
  "eventTypes": ["tweet.new"],
  "isActive": false,
  "consecutiveFailures": 0,
  "deliveryStatus": "paused",
  "failureHardCap": 200,
  "createdAt": "2026-02-24T10:30:00.000Z"
}
```

### 401 Unauthenticated

```json theme={null}
{ "error": "unauthenticated" }
```

Missing or invalid API key or session cookie.

### 400 Invalid input

```json theme={null}
{ "error": "invalid_input" }
```

Invalid URL (must be HTTPS), empty `eventTypes`, or no fields provided.

```json theme={null}
{ "error": "invalid_id" }
```

The provided webhook ID is not a valid format.

### 404 Not found

```json theme={null}
{ "error": "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.

## Reconfiguration handoff

Use this endpoint when a receiver URL or event filter changes. It also pauses
or resumes webhook delivery without creating a new endpoint.

<CardGroup cols={2}>
  <Card title="Updated inventory" icon="clipboard-check">
    Store returned `id`, `url`, `eventTypes`, `isActive`, `deliveryStatus`,
    `consecutiveFailures`, `failureHardCap`, and `createdAt` as the current
    webhook configuration.
  </Card>

  <Card title="URL change" icon="link">
    After changing `url`, run [Test Webhook](/api-reference/webhooks/test) before
    expecting production monitor events at the new receiver.
  </Card>

  <Card title="Event filter" icon="funnel">
    `eventTypes` replaces the previous list. Keep it aligned with account or
    keyword monitor event types.
  </Card>

  <Card title="Pause delivery" icon="toggle-left">
    `isActive: false` stops future deliveries. Existing stored events and
    delivery records remain available. Xquik keeps queued events until all
    deliveries finish. Events expire 30 days after Xquik creates them.
  </Card>

  <Card title="Resume delivery" icon="toggle-right">
    `isActive: true` resumes delivery for matching future monitor events. It
    also starts sending waiting deliveries at once. Events that happen during
    a pause may never arrive. To catch up, page through
    [List Events](/api-reference/events/list). Use
    [Resume Webhook](/api-reference/webhooks/resume) when the receiver must pass a
    signed test first.
  </Card>

  <Card title="Signing secret" icon="shield-check">
    This endpoint does not rotate or return `secret`. Keep using the secret from
    [Create Webhook](/api-reference/webhooks/create) for signature verification.
  </Card>

  <Card title="Delivery check" icon="activity">
    After the signed test passes, use
    [List Deliveries](/api-reference/webhooks/deliveries) if production monitor
    events still miss the receiver. Check `status`, `attempts`,
    `lastStatusCode`, `lastError`, `createdAt`, and `deliveredAt`.
  </Card>

  <Card title="Event join" icon="link">
    Use delivery `streamEventId` as the `{id}` for
    [Get Event](/api-reference/events/get). Store `monitorId`, `monitorType`,
    `type`, `occurredAt`, and `data` with the reconfiguration 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) · [Test Webhook](/api-reference/webhooks/test) · [Resume Webhook](/api-reference/webhooks/resume) · [List Deliveries](/api-reference/webhooks/deliveries) · [Get Event](/api-reference/events/get) · [Delete Webhook](/api-reference/webhooks/delete)
</Note>


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