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

# n8n

> Connect Xquik to n8n workflows with API-key auth, MCP tools, monitor webhooks, and extraction jobs

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

Use Xquik in n8n when a workflow needs X (Twitter) search, account lookups, trends, publishing, extraction jobs, monitors, webhooks, or MCP tools without an X Developer app.

Xquik uses one API key and the REST base URL `https://xquik.com/api/v1`.

## Prerequisites

* [Xquik API key](/quickstart)
* n8n Cloud or self-hosted n8n
* An HTTPS n8n webhook URL for monitor recipes
* Optional Slack and Google Sheets credentials for the recipes below

## API Key Credential

Create a reusable n8n credential for Xquik:

<CardGroup cols={3}>
  <Card title="Authentication" icon="key-round">
    Select Header Auth for the HTTP Request credential.
  </Card>

  <Card title="Header name" icon="braces">
    Set the header name to `x-api-key`.
  </Card>

  <Card title="Header value" icon="shield-check">
    Paste your Xquik API key as the credential value.
  </Card>
</CardGroup>

Use that credential in every HTTP Request node that calls `https://xquik.com/api/v1`.

## Community Node Blueprint

If you package Xquik as a community node, keep the first release narrow and reliable.

<CardGroup cols={2}>
  <Card title="Credential" icon="key-round">
    Create an `Xquik API Key` credential and inject it as `x-api-key`.
  </Card>

  <Card title="Base URL" icon="link">
    Point every REST action at `https://xquik.com/api/v1`.
  </Card>

  <Card title="Request helper" icon="workflow">
    Support `GET`, `POST`, `PATCH`, `DELETE`, JSON bodies, structured errors, and `Retry-After` backoff.
  </Card>

  <Card title="Resources" icon="boxes">
    Start with Tweet, User, Trends, Extraction, Monitor, and Webhook resources.
  </Card>

  <Card title="Actions" icon="play">
    Ship Get Tweet, Search Tweets, Get User, Get Trends, Create Tweet, Create Extraction, Create Monitor, and Create Webhook first.
  </Card>

  <Card title="Sources" icon="radio">
    Add Monitor Event Webhook and Extraction Completed Polling sources.
  </Card>
</CardGroup>

Handle these response classes explicitly:

<CardGroup cols={2}>
  <Card title="400 invalid input" icon="circle-alert">
    Surface the Xquik `error` and `message` fields in the failed item.
  </Card>

  <Card title="401 authentication" icon="key-round">
    Ask the user to check the Header Auth credential and `x-api-key` value.
  </Card>

  <Card title="402 billing state" icon="credit-card">
    Route to subscription or credit setup before retrying the node.
  </Card>

  <Card title="429 rate limit" icon="timer">
    Read `Retry-After` from response headers and wait before retrying.
  </Card>

  <Card title="5xx transient" icon="refresh-cw">
    Enable n8n Retry on Fail with exponential backoff, then fail the item.
  </Card>
</CardGroup>

## Result Handoff

Use an Edit Fields node after each HTTP Request node when the next node only
needs stable handoff fields. Keep raw responses out of Slack messages, Sheets
rows, and retry queues. Use snake\_case storage keys for handoff rows even when
direct API responses use camelCase.

<CardGroup cols={2}>
  <Card title="Tweet search page" icon="search">
    Store request `q`; map each tweet `id`, `text`, `author.username`, and `createdAt` to `tweet_id`, `text`, `author_username`, and `created_at`; keep `has_next_page` and `next_cursor` for page loops.
  </Card>

  <Card title="User profile rows" icon="users">
    Store source `id` as `user_id`, plus `username`, `name`, `followers`, `verified`, `profile_picture`, `has_next_page`, `next_cursor`, and the lookup or search input.
  </Card>

  <Card title="Trend rows" icon="trending-up">
    Store each trend `name`, `rank`, `query`, and `description`. Keep response `count`, `woeid`, and the requested region with the workflow run.
  </Card>

  <Card title="Tweet or reply write" icon="send">
    Send a unique `Idempotency-Key`. Store `id`, `status`, `billing`, `result`, and `statusUrl`. Poll while `terminal` is false. Retry only when `safeToRetry` is true, using a new key.
  </Card>

  <Card title="Media attachments" icon="image">
    For tweets or replies, pass public URLs in `media`; do not send `media_ids`. For DMs, upload first, pass 1 `media_id` in `media_ids`, store `message_id`, and leave `reply_to_message_id` unset.
  </Card>

  <Card title="Monitor and webhook setup" icon="radio">
    Store monitor `id`, `username`, `xUserId`, `eventTypes`, `isActive`, and `nextBillingAt`; store webhook `id`, `url`, `eventTypes`, and one-time `secret`. For storage rows, map production `deliveryId` to `delivery_id` for receiver retry de-dupe and `streamEventId` to `stream_event_id` when one monitor event should process once across endpoint changes.
  </Card>

  <Card title="Webhook event de-dupe" icon="fingerprint">
    Store `deliveryId` for receiver retry de-dupe and `streamEventId` when one monitor event should process once across endpoint changes.
  </Card>

  <Card title="Stored Event Replay" icon="activity">
    Call `GET /events` with `after` when a workflow needs replay. Map `id`, `monitorId`, `monitorType`, `occurredAt`, `hasMore`, and `nextCursor` to `event_id`, `monitor_id`, `monitor_type`, `occurred_at`, `has_more`, and `next_cursor`.
  </Card>

  <Card title="Receiver acceptance" icon="copy-check">
    Return `2xx` after accepting duplicate `deliveryId` or `streamEventId`; keep endpoint signing values, raw request body, raw signature, and full headers out of n8n executions, data stores, Slack messages, Sheets rows, and retry queues.
  </Card>

  <Card title="Extraction job" icon="database">
    Store `id` as `extraction_id`, `toolType` as `tool_type`, plus `status`, `has_more`, and `next_cursor` before batch loops fetch detail rows.
  </Card>
</CardGroup>

## Recipe 1: AI Agent X Research With MCP

Use this when an n8n AI Agent needs to research live X data, summarize trends, or compare account activity.

<Steps>
  <Step title="Add an AI Agent node">
    Create an AI Agent workflow with your preferred chat model.
  </Step>

  <Step title="Add an MCP Client Tool">
    Set Server Transport to `HTTP Streamable`. Set MCP Endpoint URL to `https://xquik.com/mcp`. Set Authentication to `Header Auth`. Create or select a Header Auth credential. Set Name to `x-api-key` and Value to your Xquik API key.
  </Step>

  <Step title="Prompt the agent">
    Tell the agent to use Xquik for X search, trends, account lookups, and extraction planning.
  </Step>
</Steps>

<Note>
  The MCP Client Tool also supports `MCP OAuth2`. This recipe uses Header Auth for unattended workflows with an n8n credential.
</Note>

Suggested agent system prompt:

```text theme={null}
Use Xquik for every X research request. Search tweets, inspect accounts, fetch trends, and cite the returned post URLs. Prefer small, targeted searches before broad extraction jobs.
```

Example user prompt:

```text theme={null}
Find recent posts about AI agents in fintech, group them by theme, and list 5 accounts worth monitoring.
```

The MCP server exposes `explore` for endpoint discovery. It exposes `xquik` for authenticated calls. One agent loop can select an endpoint and request current API data.

## Recipe 2: Monitor To Slack

Use this when a Slack channel should receive new tweets, replies, quotes, or retweets from monitored accounts.

### Workflow Shape

<CardGroup cols={2}>
  <Card title="Webhook Trigger" icon="webhook">
    Receive Xquik monitor events on the production Webhook URL.
  </Card>

  <Card title="Create webhook" icon="send">
    Use HTTP Request to call `POST /webhooks` with the Webhook Trigger URL.
  </Card>

  <Card title="Create monitor" icon="radio">
    Use HTTP Request to call `POST /monitors` for the username and event types.
  </Card>

  <Card title="Format alert" icon="type">
    Use Set to build Slack text from `data`, with `username` as fallback.
  </Card>

  <Card title="Post alert" icon="message-square">
    Send the formatted message to Slack after the webhook and monitor exist.
  </Card>
</CardGroup>

### Create Webhook

Call this once during setup, using the production URL from your n8n Webhook Trigger.

```json theme={null}
{
  "method": "POST",
  "url": "https://xquik.com/api/v1/webhooks",
  "headers": {
    "x-api-key": "={{$credentials.xquikApi.apiKey}}"
  },
  "body": {
    "url": "={{$node['Webhook Trigger'].webhookUrl}}",
    "eventTypes": ["tweet.new", "tweet.reply", "tweet.quote", "tweet.retweet"]
  }
}
```

### Create Monitor

```json theme={null}
{
  "method": "POST",
  "url": "https://xquik.com/api/v1/monitors",
  "headers": {
    "x-api-key": "={{$credentials.xquikApi.apiKey}}"
  },
  "body": {
    "username": "username",
    "eventTypes": ["tweet.new", "tweet.reply", "tweet.quote", "tweet.retweet"]
  }
}
```

### Slack Message

Use a Set node before Slack:

```text theme={null}
{{$json.eventType}} from @{{$json.data.author?.userName || $json.username}}
{{$json.data.text}}
https://x.com/{{$json.data.author?.userName || $json.username}}/status/{{$json.data.id}}
```

Webhook tweet fields live under `data`. Use `data.author.userName` when present; `username` is the monitored-account fallback.

Keep the webhook secret returned by Xquik. If your n8n plan supports custom verification code before routing, verify the `x-xquik-signature` header with that secret before sending Slack messages.

## Recipe 3: Extraction To Google Sheets

Use this when a team needs bulk follower, reply, quote, media, list, community, or search results in a spreadsheet.

### Workflow Shape

<CardGroup cols={2}>
  <Card title="Schedule Trigger" icon="calendar-clock">
    Run daily or hourly exports; execute manually while testing.
  </Card>

  <Card title="Create extraction" icon="send">
    Use HTTP Request to call `POST /extractions` and store the returned `id`.
  </Card>

  <Card title="Wait before polling" icon="timer">
    Pause before the first status check so the extraction can start.
  </Card>

  <Card title="Fetch results" icon="list-checks">
    Use HTTP Request to call `GET /extractions/{id}` and read `job.status`.
  </Card>

  <Card title="Gate completed jobs" icon="circle-check">
    Use IF to continue only when `job.status` is `completed`.
  </Card>

  <Card title="Append rows" icon="file-spreadsheet">
    Use Google Sheets Append Row with the mapped result fields below.
  </Card>
</CardGroup>

### Create Extraction

```json theme={null}
{
  "method": "POST",
  "url": "https://xquik.com/api/v1/extractions",
  "headers": {
    "x-api-key": "={{$credentials.xquikApi.apiKey}}"
  },
  "body": {
    "toolType": "tweet_search_extractor",
    "searchQuery": "AI agents lang:en",
    "resultsLimit": 500
  }
}
```

Store the returned `id` for the polling step.

### Poll Results

```json theme={null}
{
  "method": "GET",
  "url": "https://xquik.com/api/v1/extractions/{{$json.id}}",
  "headers": {
    "x-api-key": "={{$credentials.xquikApi.apiKey}}"
  },
  "query": {
    "limit": "1000"
  }
}
```

Map these fields into Google Sheets:

<CardGroup cols={2}>
  <Card title="Tweet ID" icon="hash">
    Map to `id`.
  </Card>

  <Card title="Author" icon="at-sign">
    Map to `author.username`.
  </Card>

  <Card title="Text" icon="type">
    Map to `text`.
  </Card>

  <Card title="Created At" icon="calendar">
    Map to `createdAt`.
  </Card>

  <Card title="Likes" icon="heart">
    Map to `likeCount`.
  </Card>

  <Card title="Reposts" icon="repeat-2">
    Map to `retweetCount`.
  </Card>

  <Card title="URL" icon="link">
    Build from `https://x.com/{author.username}/status/{id}`.
  </Card>
</CardGroup>

For jobs larger than 1,000 rows, loop while `hasMore` is `true` and pass `after` with the `nextCursor` value.

## Useful REST Actions

<CardGroup cols={2}>
  <Card title="Get tweet" icon="message-circle">
    Read one or more posts with `GET /x/tweets?ids=<id>`.
  </Card>

  <Card title="Search tweets" icon="search">
    Run X query searches with `GET /x/tweets/search?q=<query>`.
  </Card>

  <Card title="Get user" icon="user-round">
    Fetch an X profile with `GET /x/users/{id}`.
  </Card>

  <Card title="Get trends" icon="trending-up">
    Read regional X trends with `GET /x/trends`.
  </Card>

  <Card title="Create tweet" icon="send">
    Publish text or media posts with `POST /x/tweets`.
  </Card>

  <Card title="Create extraction" icon="boxes">
    Start bulk export jobs with `POST /extractions`.
  </Card>

  <Card title="Create monitor" icon="radio">
    Watch accounts or keywords with `POST /monitors`.
  </Card>

  <Card title="Create webhook" icon="webhook">
    Register signed delivery URLs with `POST /webhooks`.
  </Card>
</CardGroup>

## Testing Checklist

* Use the n8n Test Step action on each HTTP Request node.
* Confirm every request includes `x-api-key`.
* Confirm monitor webhooks use the production webhook URL, not the test URL.
* Send a test event from [Test Webhook](/api-reference/webhooks/test).
* For extraction jobs, poll until `completed` before writing to Sheets.
* On `429`, wait for the `Retry-After` header before retrying.

## Next Steps

* Read [Webhooks](/webhooks/overview) for payload and retry behavior.
* Read [Extraction Workflow](/guides/extraction-workflow) for pagination and export patterns.
* Use [MCP Tools](/mcp/tools) when building AI Agent workflows.
