Skip to main content
Use this workflow when a sales, support, research, or marketing system needs an owned list of X followers with stable IDs, usernames, display names, verification state, profile images, and enrichment fields.

Outcome

1. Estimate

Call POST /extractions/estimate with follower_explorer to check credits and projected row count.

2. Extract

Call POST /extractions with targetUsername and optional resultsLimit to start the async job.

3. Retrieve

Call GET /extractions/{id} when a custom pipeline needs paginated JSON rows.

4. Export

Call GET /extractions/{id}/export?format=csv, format=json, or format=xlsx for CRM files; md, md-document, pdf, and txt are also supported.

5. Import

Map User ID to a CRM unique field for imports, upserts, segments, or warehouse loads.

Choose the right path

Saved follower export

Use POST /extractions/estimate, then POST /extractions with follower_explorer when you need a reusable job ID, cost preview, and CSV/JSON/XLSX files.

Paginated saved rows

Use GET /extractions/{id}?limit=1000&after={nextCursor} when a CRM sync, warehouse load, queue, or agent needs saved JSON pages.

Live follower page

Use GET /x/users/{id}/followers?pageSize=200&cursor={next_cursor} when you need the current follower page without creating an extraction job.

Shell or SDK handoff

Use CLI, TypeScript, Python, or Go when scheduled imports need code-owned JSON Lines, CSV, or XLSX files.
Use extraction jobs for repeatable exports, cost preview, audit trails, and file downloads. Use the direct followers API for low-latency pages and small app handoffs.

End-to-end follower export handoff

Store one checkpoint that carries the follower target through estimate, job creation, JSON pagination, file export, and CRM upsert:
{
  "workflow": "follower_export_crm",
  "request": {
    "toolType": "follower_explorer",
    "targetUsername": "elonmusk",
    "resultsLimit": 10000
  },
  "estimate": {
    "estimatedResults": 10000,
    "creditsRequired": "10000",
    "creditsAvailable": "77000",
    "allowed": true,
    "source": "resultsLimit",
    "resolvedXUserId": "44196397"
  },
  "create_receipt": {
    "id": "77777",
    "toolType": "follower_explorer",
    "status": "running",
    "poll_path": "/api/v1/extractions/77777"
  },
  "json_pages": {
    "limit": 1000,
    "page_cursor": null,
    "next_cursor": "1001",
    "has_more": true
  },
  "export_paths": {
    "csv": "/api/v1/extractions/77777/export?format=csv",
    "json": "/api/v1/extractions/77777/export?format=json",
    "xlsx": "/api/v1/extractions/77777/export?format=xlsx"
  },
  "normalized_row": {
    "x_user_id": "44196397",
    "x_username": "xquikcom",
    "display_name": "Xquik",
    "followers_count": 2400,
    "verified": true,
    "profile_image_url": "https://pbs.twimg.com/profile_images/xquik.jpg",
    "bio": "X automation platform",
    "location": "San Francisco",
    "account_created_at": "2021-03-01T12:00:00.000Z",
    "can_dm": true
  },
  "crm_import": {
    "unique_field": "x_user_id",
    "upsert_mode": "external_id",
    "file_format": "csv",
    "file_path": "x-followers-elonmusk.csv"
  },
  "handoff_state": "poll_until_completed_then_export"
}

Estimate checkpoint

Keep estimatedResults, creditsRequired, creditsAvailable, allowed, source, and resolvedXUserId; source is followers unless resultsLimit is lower than the follower count.

Job checkpoint

Store the returned job id, status, and poll_path; do not expect follower rows in the create response.

Cursor checkpoint

Store page_cursor, next_cursor, and has_more for saved JSON page loops, then pass nextCursor back as after.

CRM checkpoint

Store the CSV, JSON, or XLSX export_paths, unique_field, and normalized follower row fields used for the upsert.

Live follower page handoff

Use GET /x/users/{id}/followers when a CRM enrichment job, queue worker, audience sync, or agent needs the newest follower page without creating a saved extraction.
cURL
curl "https://xquik.com/api/v1/x/users/44196397/followers?pageSize=200&cursor=DAACCgACGRElMJcAAA" \
  -H "x-api-key: xq_YOUR_KEY_HERE" | jq
The response returns users, has_next_page, and next_cursor. Treat next_cursor as opaque, store it with the import checkpoint, and pass it back as cursor only when has_next_page is true. Map direct API fields before import:

Identity

Map users[].id to x_user_id, users[].username to x_username, and users[].name to display_name.

Audience fields

Map optional followers, following, statusesCount, verified, and verifiedType for scoring or segments.

Profile context

Map optional description, location, url, profilePicture, coverPicture, createdAt, and canDm for enrichment and review queues.

Credit-aware pages

pageSize accepts 20 to 200, but paid calls can return fewer users when remaining credits are lower than the requested page. If no result can be afforded, the endpoint returns 402 insufficient_credits; lower pageSize or add credits before retrying.
For scheduled direct pulls, store one page checkpoint per import attempt. Never treat cursor as a stable follower ID; it only resumes the next page.
{
  "job": "direct_follower_page",
  "source_x_user_id": "44196397",
  "page_size_requested": 200,
  "rows_returned": 200,
  "cursor_used": "DAACCgACGRElMJcAAA",
  "next_cursor": "DAACCgACGE...",
  "has_next_page": true,
  "fetched_at": "2026-05-16T16:50:00.000Z",
  "page_checkpoint": "44196397:DAACCgACGE..."
}
For CRM or warehouse rows, map users[].createdAt to account_created_at and users[].canDm to can_dm when those fields are returned.

Step 1: Estimate cost

Estimate first so the workflow can stop before spending credits.
curl -X POST https://xquik.com/api/v1/extractions/estimate \
  -H "x-api-key: xq_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "toolType": "follower_explorer",
    "targetUsername": "elonmusk",
    "resultsLimit": 10000
  }' | jq
{
  "allowed": true,
  "creditsRequired": "10000",
  "creditsAvailable": "77000",
  "estimatedResults": 10000,
  "source": "resultsLimit",
  "resolvedXUserId": "44196397"
}
resultsLimit caps both the estimate and the extraction. Use it for first imports, test segments, and nightly syncs. When the account has fewer followers than resultsLimit, the estimate keeps source: "followers" and uses the smaller follower count.

Step 2: Start the extraction

Run the same request against POST /extractions.
curl -X POST https://xquik.com/api/v1/extractions \
  -H "x-api-key: xq_YOUR_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{
    "toolType": "follower_explorer",
    "targetUsername": "elonmusk",
    "resultsLimit": 10000
  }' | jq
Store extractionHandoff in your job table. Poll by extraction_id, keep source_username and results_limit for audit, and replace status with the value returned by GET /extractions/{id}.
{
  "id": "77777",
  "toolType": "follower_explorer",
  "status": "running"
}

Step 3: Poll until complete

Poll the job before exporting. Use the paginated endpoint when your pipeline wants JSON rows instead of a file.
cURL
curl -s "https://xquik.com/api/v1/extractions/77777?limit=1000" \
  -H "x-api-key: xq_YOUR_KEY_HERE" | jq
The job is ready for file export when status is completed.

Paginated JSON handoff

Use GET /extractions/{id} when a custom CRM sync, warehouse load, queue, or agent needs rows before a file export. The API returns camelCase JSON fields. Only id and xUserId are guaranteed on every result; optional profile and enrichment fields are omitted when unavailable.
{
  "job": {
    "id": "77777",
    "toolType": "follower_explorer",
    "status": "completed",
    "totalResults": 10000,
    "targetUsername": "elonmusk",
    "createdAt": "2026-05-08T13:46:00.000Z",
    "completedAt": "2026-05-08T13:51:00.000Z"
  },
  "results": [
    {
      "id": "1001",
      "xUserId": "44196397",
      "xUsername": "xquikcom",
      "xDisplayName": "Xquik",
      "xFollowersCount": 2400,
      "xVerified": true,
      "xProfileImageUrl": "https://pbs.twimg.com/profile_images/xquik.jpg",
      "enrichmentData": {
        "user": {
          "followingCount": 120,
          "statusesCount": 830,
          "description": "X automation platform",
          "location": "San Francisco",
          "coverPicture": "https://pbs.twimg.com/profile_banners/xquik"
        },
        "tweet": {}
      },
      "createdAt": "2026-05-08T13:51:00.000Z"
    }
  ],
  "hasMore": true,
  "nextCursor": "1001"
}
Use limit up to 1000 and pass nextCursor as after until hasMore is false. For CRM or warehouse rows, map xUserId to x_user_id, xUsername to x_username, xDisplayName to display_name, xFollowersCount to followers_count, xVerified to verified, and enrichmentData.user.description or enrichmentData.user.location to optional enrichment columns. Normalize each follower row before sending it downstream:
{
  "job": "follower_export",
  "source_username": "elonmusk",
  "result_id": "1001",
  "x_user_id": "44196397",
  "x_username": "xquikcom",
  "display_name": "Xquik",
  "followers_count": 2400,
  "verified": true,
  "profile_image_url": "https://pbs.twimg.com/profile_images/xquik.jpg",
  "bio": "X automation platform",
  "location": "San Francisco",
  "handoff_format": "json"
}

Step 4: Export the CRM file

Use CSV for most CRM imports, XLSX for analyst review, or JSON for a data pipeline.
curl -s "https://xquik.com/api/v1/extractions/77777/export?format=csv" \
  -H "x-api-key: xq_YOUR_KEY_HERE" \
  -o x-followers-elonmusk.csv
Use the local -o path, exportFilePath, or export_file_path as the durable handoff value. Read Content-Disposition only when you need the server filename for audit.
{
  "job": "follower_export_file",
  "extraction_id": "77777",
  "source_username": "elonmusk",
  "export_format": "csv",
  "export_file_path": "x-followers-elonmusk.csv",
  "handoff_format": "file"
}
Exports are free and capped at 100,000 rows per extraction, with a 10,000-row cap for PDF. Use paginated JSON for larger custom syncs.

CRM field mapping

Map stable X identifiers first. Names, bios, and locations can change.

Stable account key

Map export column User ID to x_user_id as the custom unique field. Use it for CRM upserts because it is the stable X account identifier.

Handle and display name

Map Username to x_username or a social profile field, and map Display Name to display_name for triage and human review.

Audience metrics

Map Followers to followers_count, Following to following_count, and Posts to posts_count for segmentation, scoring, and reporting.

Verification flag

Map Verified to verified so lead scoring, audience filters, and reviewer queues can separate verified accounts.

Profile context

Map Description to a bio or notes field, and map Location to a regional field. Treat both as mutable enrichment, not identity.

Profile media

Map Profile Image to an avatar URL field and Cover Picture to a banner URL field for internal views that show account context.

Import and upsert rules

Use the CRM’s own unique field rules. HubSpot’s official import docs say update or dedupe imports need a unique identifier, and supported import files include CSV, XLSX, and XLS. Salesforce Bulk API 2.0 upserts use CSV data and require an external ID field for upsert jobs.

HubSpot import docs

Check file requirements, unique identifier rules, and supported spreadsheet formats before importing.

Salesforce Bulk API 2.0

Use CSV upserts with an external ID field when loading large contact or lead datasets.

Automation handoff

Use this handoff when the export runs on a schedule:
  1. Store the Xquik extraction ID and source username in your job table.
  2. Poll GET /extractions/{id} until status is completed.
  3. Download format=json for code pipelines or format=csv for CRM import tools.
  4. Upsert by x_user_id, not by display name or username.
  5. Save the Xquik job ID, export format, export file path, row count, and import result for audit.
  6. For JSON Lines, write one normalized follower object per line to xquik-follower-export.jsonl.

Extraction workflow

Estimate costs, run jobs, paginate results, and export files.

Followers API

Fetch one live follower page with users, has_next_page, and next_cursor.

n8n guide

Send extraction rows into Sheets, Slack, and downstream automation.
Last modified on May 23, 2026