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

# X (Twitter) API Ruby follower export to CSV & XLSX

> Export X (Twitter) followers with the Xquik Ruby SDK. Estimate the job, run the extraction, and save CSV, JSON, or XLSX files for your team and your CRM tools.

> For the complete documentation index, see [llms.txt](https://docs.xquik.com/llms.txt).

This guide builds on the [Ruby SDK setup](https://docs.xquik.com/sdks/ruby.md), which covers install and authentication.

## Follower export workflow to CSV, JSON, or XLSX

Use this workflow when Ruby code needs an owned follower list. That code can be a Ruby app, Rails job, Sidekiq worker, or agent tool. The list can feed a CRM import, warehouse load, or analyst CSV file. It can also feed an XLSX workbook or resumable JSON handoff. The workflow calls `POST /extractions/estimate` through `client.extractions.estimate_cost`. It creates the job with `client.extractions.run`. It reads saved rows with `client.extractions.retrieve`. It downloads files with `client.extractions.export_results`.

> [!NOTE]
>
> `client.extractions.run` returns the queued `202 Accepted` receipt from `POST /extractions`. Ruby exposes REST `id`, `toolType`, and `status: "running"` as `job.id`, `job.tool_type`, and `job.status`. Store `job.id` immediately, then poll `client.extractions.retrieve` before reading pages or calling `client.extractions.export_results`. Credit reservation happens after the job starts. Available credits may have changed since `estimate_cost`. If so, the run can fetch only the affordable count before export. Or it can mark the job `failed` with `insufficient_credits`.

```ruby theme={"theme":{"light":"github-light","dark":"github-dark"},"languages":{"custom":["/languages/bash.json","/languages/csharp.json","/languages/go.json","/languages/java.json","/languages/javascript.json","/languages/kotlin.json","/languages/php.json","/languages/python.json","/languages/ruby.json","/languages/typescript.json"]}}
require "json"
require "x_twitter_scraper"

client = XTwitterScraper::Client.new(
  api_key: ENV["X_TWITTER_SCRAPER_API_KEY"]
)
target_username = "username"

estimate = client.extractions.estimate_cost(
  tool_type: :follower_explorer,
  target_username: target_username
)

raise "Insufficient credits for follower export." unless estimate.allowed

job = client.extractions.run(
  tool_type: :follower_explorer,
  target_username: target_username
)

loop do
  status_page = client.extractions.retrieve(job.id, limit: 1)
  status = status_page.job[:status] || status_page.job["status"]

  break if status == "completed"

  raise "Follower export failed." if status == "failed"

  sleep 10
end

cursor = nil

File.open("xquik-followers.jsonl", "w") do |jsonl|
  loop do
    page = client.extractions.retrieve(job.id, limit: 1000, cursor: cursor)

    page.results.each do |row|
      jsonl.puts(JSON.generate(row))
    end

    break unless page.has_more && page.next_cursor.to_s != ""

    cursor = page.next_cursor
  end
end

csv_response = client.extractions.export_results(job.id, format_: :csv)
csv_response.rewind
File.binwrite("xquik-followers.csv", csv_response.read)

json_response = client.extractions.export_results(job.id, format_: :json)
json_response.rewind
File.binwrite("xquik-followers.json", json_response.read)

xlsx_response = client.extractions.export_results(job.id, format_: :xlsx)
xlsx_response.rewind
File.binwrite("xquik-followers.xlsx", xlsx_response.read)
```

`follower_explorer` requires `target_username`. Store `job.id`, `target_username`, `estimate.estimated_results`, and `estimate.source` before polling. That lets a Sidekiq retry, Rails job retry, or worker restart resume that job. `client.extractions.retrieve` returns `results`, `has_more`, and `next_cursor`. Pass `next_cursor` back as `cursor` when you need stored JSON pages before exporting files. Map exported `User ID` or row `xUserId` as the CRM unique key. Use `xquik-followers.jsonl` for queue replay or warehouse loads, and `xquik-followers.json` for app ingestion. Use `xquik-followers.csv` for CRM import and `xquik-followers.xlsx` for analyst handoff. The cost is 1 credit per follower extracted or returned. Exports cost no credits after the extraction job exists.

## Next steps

* [Ruby SDK setup](https://docs.xquik.com/sdks/ruby.md)
* [Tweet search](https://docs.xquik.com/sdks/ruby-tweet-search.md)
* [Media tweets](https://docs.xquik.com/sdks/ruby-media-tweets.md)


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