> ## 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 API quickstart for monitors & webhooks

> Build a Twitter API integration with Xquik. Create an API key, authenticate a REST request, monitor tweets every 1 second, and send secure signed webhooks.

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

Use this X API quickstart to build a Twitter API integration with Xquik. First,
follow the REST API key authentication example. Then call `GET /account`,
monitor tweets every 1 second, and register a Twitter webhook.

For accountless reads, use a [guest wallet](/guides/guest-wallets) across its
eligible routes. You can also use [direct MPP](/mpp/quickstart) on its fixed-price operations.

| Integration step | Exact API call | Save for the next step |
| - | - | - |
| Check access and credits | `GET /account` | `plan`, `creditInfo.balance`, and monitor billing |
| Monitor tweets and replies | `POST /monitors` | Monitor `id`, `username`, `eventTypes`, and `isActive` |
| Register the receiver | `POST /webhooks` | Webhook `id`, `url`, `eventTypes`, and one-time `secret` |
| Test delivery | `POST /webhooks/{id}/test` | HTTP status and receiver log timestamp |
| Verify live delivery | HMAC-SHA256 verification | `deliveryId` and `streamEventId` idempotency keys |

## How the integration works

Your first API request checks credentials, credits, and monitor billing. Send
the `x-api-key` request header for API key authentication. Each
write sends `Content-Type: application/json` with a JSON request body.

The monitor watches one X account for selected tweet events. The Twitter API
webhook step stores your HTTPS API endpoint and chosen webhook events. Signed
webhooks then deliver new tweets and replies to that endpoint. Verify every
delivery with the saved secret before processing its payload.

This flow checks access, creates a monitor, and registers a webhook. The monitor
detects tweets. The webhook forwards each matching event. Keep the
returned monitor and webhook IDs for later updates, tests, or deletion.

## Before you start

* Create an Xquik account with enough credits for the monitor.
* Prepare a secret manager for the API key and webhook secret.
* Expose an HTTPS endpoint that can receive webhook events.
* Choose the X username and exact tweet event types to monitor.
* Use an HTTP client that can send JSON requests and headers.

Keep the 2 credentials separate. The API key grants Xquik API access. The
webhook secret verifies deliveries sent to your server. Never send the Xquik
key to the webhook endpoint. Treat the webhook secret as a separate secret
key.

<CardGroup cols={2}>
  <Card title="First API call" icon="terminal">
    Call `GET /account` to confirm authentication, plan status, available credits, and monitor billing.
  </Card>

  <Card title="First monitor" icon="radio">
    Create an account monitor that checks every 1 second. Active monitors cost 21 credits per hour while enabled.
  </Card>

  <Card title="First webhook" icon="shield-check">
    Register an HTTPS endpoint and save the one-time secret for HMAC signature verification.
  </Card>

  <Card title="Accountless reads" icon="wallet-cards" href="/guides/guest-wallets">
    Prepay the eligible GET routes with a USD 10 to 250 hosted checkout. You need no account.
  </Card>
</CardGroup>

<Steps>
  <Step title="Create an account">
    Sign up at [xquik.com](https://xquik.com) with your email. You'll receive a magic link. You need no password.
  </Step>

  <Step title="Fund your account">
    <Warning>
      Metered account operations require enough available credits. You need no active plan while enough credits remain.
    </Warning>

    Subscribe for monthly credits or use your remaining account balance. Starter is USD 20/month and includes 140,000 monthly credits. Manage funding from the [dashboard billing page](https://dashboard.xquik.com/en/account?tab=subscription). Guest wallets cover the prepaid paid-read routes without an account. Direct MPP covers fixed-price operations.
  </Step>

  <Step title="Generate an API key">
    Open [API Keys](https://dashboard.xquik.com/en/account?tab=api-keys) in the dashboard and create a new key. Copy the full key right away. The dashboard shows it once.

    ```text theme={null}
    xq_your_api_key_here
    ```

    <Warning>
      Store your API key in a secret manager. You cannot retrieve it after creation. Revoke and replace a leaked key.
    </Warning>
  </Step>

  <Step title="Make your first request">
    Verify your setup by fetching your account info:

    <CodeGroup>
      ```bash cURL theme={null}
      curl -s https://xquik.com/api/v1/account \
        -H "x-api-key: xq_your_api_key_here" | jq
      ```

      ```javascript Node.js theme={null}
      const response = await fetch("https://xquik.com/api/v1/account", {
        headers: { "x-api-key": "xq_your_api_key_here" },
      });
      const account = await response.json();
      process.stdout.write(`${JSON.stringify(account, null, 2)}\n`);
      ```

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

      response = requests.get(
          "https://xquik.com/api/v1/account",
          headers={"x-api-key": "xq_your_api_key_here"},
      )
      print(response.json())
      ```

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

      import (
          "fmt"
          "io"
          "net/http"
      )

      func main() {
          req, _ := http.NewRequest("GET", "https://xquik.com/api/v1/account", nil)
          req.Header.Set("x-api-key", "xq_your_api_key_here")

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

          body, _ := io.ReadAll(resp.Body)
          fmt.Println(string(body))
      }
      ```
    </CodeGroup>

    **Response.**

    ```json theme={null}
    {
      "plan": "active",
      "monitorsAllowed": 9007199254740991,
      "monitorsUsed": 0,
      "monitorBilling": {
        "activeDailyEstimate": "0",
        "activeHourlyBurn": "0",
        "creditsPerActiveMonitorDay": "500",
        "creditsPerActiveMonitorHour": "21",
        "eventsIncluded": true,
        "instantCheckIntervalSeconds": 1,
        "unlimitedSlots": true
      },
      "creditInfo": {
        "balance": "50000",
        "lifetimePurchased": "140000",
        "lifetimeUsed": "90000",
        "autoTopupEnabled": false,
        "autoTopupAmountDollars": 10,
        "autoTopupThreshold": "50000"
      }
    }
    ```
  </Step>

  <Step title="Create a monitor">
    Start tracking an X account:

    <CodeGroup>
      ```bash cURL theme={null}
      curl -s -X POST https://xquik.com/api/v1/monitors \
        -H "x-api-key: xq_your_api_key_here" \
        -H "Content-Type: application/json" \
        -d '{"username": "elonmusk", "eventTypes": ["tweet.new", "tweet.reply"]}' | jq
      ```

      ```javascript Node.js theme={null}
      const response = await fetch("https://xquik.com/api/v1/monitors", {
        method: "POST",
        headers: {
          "x-api-key": "xq_your_api_key_here",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          username: "elonmusk",
          eventTypes: ["tweet.new", "tweet.reply"],
        }),
      });
      const monitor = await response.json();
      process.stdout.write(`${JSON.stringify(monitor, null, 2)}\n`);
      ```

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

      response = requests.post(
          "https://xquik.com/api/v1/monitors",
          headers={"x-api-key": "xq_your_api_key_here"},
          json={
              "username": "elonmusk",
              "eventTypes": ["tweet.new", "tweet.reply"],
          },
      )
      print(response.json())
      ```

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

      import (
          "bytes"
          "encoding/json"
          "fmt"
          "io"
          "net/http"
      )

      func main() {
          body, _ := json.Marshal(map[string]interface{}{
              "username":   "elonmusk",
              "eventTypes": []string{"tweet.new", "tweet.reply"},
          })

          req, _ := http.NewRequest("POST", "https://xquik.com/api/v1/monitors", bytes.NewReader(body))
          req.Header.Set("x-api-key", "xq_your_api_key_here")
          req.Header.Set("Content-Type", "application/json")

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

          respBody, _ := io.ReadAll(resp.Body)
          fmt.Println(string(respBody))
      }
      ```
    </CodeGroup>

    **Response.**

    ```json theme={null}
    {
      "id": "7",
      "username": "elonmusk",
      "xUserId": "44196397",
      "eventTypes": ["tweet.new", "tweet.reply"],
      "isActive": true,
      "createdAt": "2026-02-24T10:30:00.000Z",
      "nextBillingAt": "2026-02-24T10:30:00.000Z"
    }
    ```
  </Step>

  <Step title="Set up a webhook (optional)">
    Receive signed monitor events at your endpoint:

    <CodeGroup>
      ```bash cURL theme={null}
      curl -s -X POST https://xquik.com/api/v1/webhooks \
        -H "x-api-key: xq_your_api_key_here" \
        -H "Content-Type: application/json" \
        -d '{"url": "https://your-server.com/webhook", "eventTypes": ["tweet.new"]}' | jq
      ```

      ```javascript Node.js theme={null}
      const response = await fetch("https://xquik.com/api/v1/webhooks", {
        method: "POST",
        headers: {
          "x-api-key": "xq_your_api_key_here",
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          url: "https://your-server.com/webhook",
          eventTypes: ["tweet.new"],
        }),
      });
      const webhook = await response.json();
      const webhookSecret = webhook.secret;
      if (!webhookSecret) throw new Error("missing webhook secret");
      process.stdout.write(`Webhook ${webhook.id} ready\n`);
      // Store webhookSecret in your secret manager; do not print it.
      ```

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

      response = requests.post(
          "https://xquik.com/api/v1/webhooks",
          headers={"x-api-key": "xq_your_api_key_here"},
          json={
              "url": "https://your-server.com/webhook",
              "eventTypes": ["tweet.new"],
          },
      )
      webhook = response.json()
      webhook_secret = webhook["secret"]
      if not webhook_secret:
          raise RuntimeError("missing webhook secret")
      print(f"Webhook {webhook['id']} ready")
      # Store webhook_secret in your secret manager; do not print it.
      ```

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

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

      func main() {
          body, _ := json.Marshal(map[string]interface{}{
              "url":        "https://your-server.com/webhook",
              "eventTypes": []string{"tweet.new"},
          })

          req, _ := http.NewRequest("POST", "https://xquik.com/api/v1/webhooks", bytes.NewReader(body))
          req.Header.Set("x-api-key", "xq_your_api_key_here")
          req.Header.Set("Content-Type", "application/json")

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

          var webhook struct {
              ID     string `json:"id"`
              Secret string `json:"secret"`
          }
          if err := json.NewDecoder(resp.Body).Decode(&webhook); err != nil {
              panic(err)
          }

          webhookSecret := webhook.Secret
          if webhookSecret == "" {
              panic("missing webhook secret")
          }
          fmt.Printf("Webhook %s ready\n", webhook.ID)
          // Store webhookSecret in your secret manager; do not print it.
      }
      ```
    </CodeGroup>

    **Response.**

    ```json theme={null}
    {
      "id": "15",
      "url": "https://your-server.com/webhook",
      "eventTypes": ["tweet.new"],
      "secret": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2",
      "createdAt": "2026-02-24T10:30:00.000Z"
    }
    ```

    Save the `secret` from the response in a secret manager. Xquik returns it once. Use it to [verify webhook signatures](/webhooks/verification). Do not print it in shared logs.
  </Step>
</Steps>

## Verify each result

Confirm every step before continuing. The account API endpoint should return a
successful status code. Its response shows the plan, credit balance, and
monitor billing values. A `401` means the API key is missing, invalid, or
revoked.

Next, inspect the monitor response. Confirm its `id`, `username`, `eventTypes`,
and `isActive` values. The username must match the account you intend to watch.
The event types must match the tweets or replies you need.

Finally, inspect the webhook response. Confirm its `id`, `url`, and
`eventTypes`. Store the returned `secret` immediately. Xquik returns that
secret only during creation. Use the test endpoint before relying on live
webhook events.

Verify the HMAC signature before parsing a delivery. Return `2xx` after
accepting the event. Inspect failed HTTP requests using their status and
response body. Never log secret-bearing HTTP headers.
Use the troubleshooting steps below for authentication, payment, webhook, or
rate-limit failures.

## Next steps

<CardGroup cols={3}>
  <Card title="API reference" icon="book" href="/api-reference/overview">
    Browse tweet, profile, follower, timeline, monitor, and webhook endpoints.
  </Card>

  <Card title="Export tweets & followers" icon="pickaxe" href="/api-reference/extractions/create">
    Export tweets, replies, followers, following, likes, lists, and media.
  </Card>

  <Card title="Run a draw" icon="trophy" href="/api-reference/draws/create">
    Run a giveaway draw on a tweet.
  </Card>

  <Card title="Webhook verification" icon="shield-check" href="/webhooks/verification">
    Verify HMAC signatures on incoming webhooks.
  </Card>

  <Card title="MCP server" icon="bot" href="/mcp/overview">
    Connect API MCP through Streamable HTTP. Use Code Mode by default, or add `?codemode=false` for OpenAPI-native tools.
  </Card>

  <Card title="Error handling" icon="circle-alert" href="/guides/error-handling">
    Handle errors, rate limits, and retries.
  </Card>

  <Card title="Billing & usage" icon="credit-card" href="/guides/billing">
    Track credits, monitor costs, subscriptions, and rate-limit quotas.
  </Card>
</CardGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Magic link email not received">
    Keep using your Xquik account email. Wait 60 seconds, request a new link, then open the newest email within 15 minutes. Check your spam or junk folder. If no email arrives, contact [support@xquik.com](mailto:support@xquik.com) with the exact request time.
  </Accordion>

  <Accordion title="API key not working (401)">
    Verify the header name is `x-api-key` (lowercase). Check that the key starts with `xq_` and hasn't been revoked. Regenerate from the [API Keys dashboard](https://dashboard.xquik.com/en/account?tab=api-keys).
  </Accordion>

  <Accordion title="Getting 401 or 402">
    Neither status creates checkout. Anonymous non-MPP paid reads return `401` with a Bearer challenge and guest wallet action. The direct MPP reads return `402` with a Payment challenge and the same action. A `402` response lists choices for account or guest credit failures. Ask the user to choose and confirm before creating checkout. See [Billing](/guides/billing).
  </Accordion>

  <Accordion title="Webhook not receiving events">
    Verify the URL uses HTTPS. Check that the webhook is active via [List Webhooks](/api-reference/webhooks/list). Test delivery with the [Test Webhook](/api-reference/webhooks/test) endpoint.
  </Accordion>

  <Accordion title="Rate limited (429)">
    The fixed windows allow 500 reads per 1 second, 120 writes per 60 seconds, and 60 deletes per 60 seconds. Respect `Retry-After`. See [Rate Limits](/guides/rate-limits).
  </Accordion>
</AccordionGroup>


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