Skip to main content

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.

Use Xquik in Zapier when a workflow needs X (Twitter) search, account lookups, trends, publishing, extraction jobs, monitors, or webhook automation without an X Developer app. Start with a private Zapier Platform CLI integration. Keep the first release focused on high-volume workflow primitives, then expand once real Zaps show which endpoints users need.

Prerequisites

  • Xquik API key
  • Zapier account with Platform CLI access
  • Node.js 18+
  • HTTPS callback URLs for REST Hook testing
Install and sign in to the Zapier CLI:
npm install -g zapier-platform-cli
zapier login
zapier init xquik-zapier --template minimal
cd xquik-zapier
npm install

Integration Shape

SurfaceInitial scope
AuthAPI key field named apiKey, injected as x-api-key
Base URLhttps://xquik.com/api/v1
Request helperJSON requests, structured error messages, Retry-After handling
ActionsSearch Tweets, Get Tweet, Get User, Get Trends, Create Tweet, Create Reply, Create Extraction, Create Monitor, Create Webhook
TriggersNew Matching Tweet polling, Monitor Event instant trigger, Extraction Completed polling, Webhook Delivery Failure polling
This gives Zapier builders API-key auth, 111 REST endpoints, monitor webhooks, extraction jobs, and agent-adjacent workflows. The visible Zapier X templates are narrower: they focus on polling a query and taking one write action.

API Key Auth

Add a custom auth field and inject it into every Xquik request:
const BASE_URL = "https://xquik.com/api/v1";

function addApiKeyHeader(request, z, bundle) {
  request.headers = request.headers || {};
  request.headers["x-api-key"] = bundle.authData.apiKey;
  return request;
}

async function testAuth(z) {
  const response = await z.request({
    method: "GET",
    url: `${BASE_URL}/account`,
  });

  return response.data;
}

module.exports = {
  authentication: {
    type: "custom",
    fields: [{ key: "apiKey", label: "Xquik API Key", required: true }],
    test: testAuth,
  },
  beforeRequest: [addApiKeyHeader],
};

Shared Error Handling

Normalize Xquik responses in one helper so every action reports the same remediation:
function xquikErrorMessage(status, data, headers) {
  if (status === 401) {
    return "Authentication failed. Check the Xquik API key.";
  }

  if (status === 402) {
    return "Subscription or credits required. Update billing in Xquik.";
  }

  if (status === 429) {
    const retryAfter = headers?.["retry-after"];
    return retryAfter
      ? `Rate limited. Retry after ${retryAfter} seconds.`
      : "Rate limited. Retry after the cooldown period.";
  }

  return data?.message || data?.error || "Xquik request failed.";
}

function throwForXquikError(z, response) {
  if (response.status < 400) {
    return;
  }

  throw new z.errors.Error(
    xquikErrorMessage(response.status, response.data, response.headers),
    "XquikError",
    response.status,
  );
}
Call throwForXquikError(z, response) after each z.request.

Starter Actions

ActionMethod and pathNotes
Search TweetsGET /x/tweets/searchInputs: q, limit, optional cursor
Get TweetGET /x/tweets/{id}Input: tweet ID
Get UserGET /x/users/{id}Input: user ID
Get TrendsGET /x/trendsInputs: optional woeid and count
Create TweetPOST /x/tweetsInputs: account, text, optional public media URLs
Create ReplyPOST /x/tweetsInputs: account, text, and reply_to_tweet_id
Create ExtractionPOST /extractionsInputs: toolType, query fields, result limit
Create MonitorPOST /monitorsInputs: username and event types
Create WebhookPOST /webhooksInputs: callback URL and event types
Use a Zapier dropdown to map friendly region names to WOEID values before calling Xquik. Example search action:
async function performSearchTweets(z, bundle) {
  const response = await z.request({
    method: "GET",
    url: `${BASE_URL}/x/tweets/search`,
    params: {
      q: bundle.inputData.q,
      limit: bundle.inputData.limit || 25,
    },
  });

  throwForXquikError(z, response);
  return response.data.tweets || [];
}

module.exports = {
  key: "search_tweets",
  noun: "Tweet",
  display: {
    label: "Search Tweets",
    description: "Find recent tweets that match a search query.",
  },
  operation: {
    inputFields: [
      { key: "q", label: "Query", required: true, type: "string" },
      { key: "limit", label: "Limit", required: false, type: "integer" },
    ],
    perform: performSearchTweets,
    sample: {
      id: "1840000000000000000",
      text: "Example tweet text",
      author: { username: "xquikcom" },
      url: "https://x.com/xquikcom/status/1840000000000000000",
    },
    outputFields: [
      { key: "id", label: "Tweet ID" },
      { key: "text", label: "Text" },
      { key: "author__username", label: "Author Username" },
      { key: "url", label: "URL" },
    ],
  },
};

Trigger 1: New Matching Tweet

Use polling for query-based alerts. Return a stable array of tweet records and let Zapier deduplicate by id.
async function performNewMatchingTweet(z, bundle) {
  const response = await z.request({
    method: "GET",
    url: `${BASE_URL}/x/tweets/search`,
    params: {
      q: bundle.inputData.q,
      limit: 25,
    },
  });

  throwForXquikError(z, response);
  return response.data.tweets || [];
}

Trigger 2: Monitor Event REST Hook

Use REST Hooks for monitor events so Zapier receives new tweets, replies, quotes, and retweets immediately.

Subscribe

async function subscribeHook(z, bundle) {
  const response = await z.request({
    method: "POST",
    url: `${BASE_URL}/webhooks`,
    body: {
      url: bundle.targetUrl,
      eventTypes: bundle.inputData.eventTypes,
    },
  });

  throwForXquikError(z, response);
  return { id: response.data.id };
}

Unsubscribe

async function unsubscribeHook(z, bundle) {
  const response = await z.request({
    method: "DELETE",
    url: `${BASE_URL}/webhooks/${bundle.subscribeData.id}`,
  });

  throwForXquikError(z, response);
  return response.data;
}

Perform

function performMonitorEvent(z, bundle) {
  const payload = bundle.cleanedRequest;

  return [
    {
      id: payload.streamEventId || payload.deliveryId,
      deliveryId: payload.deliveryId,
      eventType: payload.eventType,
      occurredAt: payload.occurredAt,
      username: payload.username,
      tweetId: payload.data?.id,
      text: payload.data?.text,
      authorUserName: payload.data?.author?.userName || payload.username,
    },
  ];
}
Use performList to return one recent monitor event with the same schema. Zapier requires sample output fields that match live webhook payloads.

Trigger 3: Extraction Completed

Use polling when users want bulk jobs without webhook setup:
async function performCompletedExtractions(z) {
  const response = await z.request({
    method: "GET",
    url: `${BASE_URL}/extractions`,
    params: { status: "completed", limit: 25 },
  });

  throwForXquikError(z, response);
  return response.data.extractions || [];
}

Trigger 4: Webhook Delivery Failure

Use polling for operations teams that need delivery alerts:
async function performWebhookFailures(z, bundle) {
  const response = await z.request({
    method: "GET",
    url: `${BASE_URL}/webhooks/${bundle.inputData.webhookId}/deliveries`,
  });

  throwForXquikError(z, response);
  return (response.data.deliveries || []).filter(
    (delivery) => delivery.status === "failed",
  );
}

Test Coverage

Add focused Zapier tests before sharing the private app:
TestExpected assertion
Auth header injectionEvery request includes x-api-key from bundle.authData.apiKey
Invalid key401 returns “Authentication failed. Check the Xquik API key.”
Rate limit429 includes Retry-After in the user-facing message when present
REST Hook subscribePOST /webhooks sends bundle.targetUrl and selected event types
REST Hook unsubscribeDELETE /webhooks/{id} uses bundle.subscribeData.id
Sample outputTrigger samples include id, eventType, occurredAt, tweet text, and author username
Search actionSearch returns an array of tweets with stable IDs
Run the local Zapier suite with:
zapier-platform test
zapier-platform validate

Launch Checklist

  • Keep the first version private until auth, REST Hook lifecycle, sample output, and rate-limit behavior are verified.
  • Use clear labels in the Zap editor: Search Tweets, Create Tweet, Monitor Event, Extraction Completed.
  • Document which actions consume credits before publishing to a broader team.
  • Add more endpoints only when Zap history shows repeated manual API Request steps.

Next Steps

  • Read API Reference for auth, rate limits, and errors.
  • Read Webhooks for payload shape and retries.
  • Read Extraction Workflow for job creation and result pagination.
  • Use n8n when the team prefers visual workflows without a custom Zapier app.