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

# List extractions

> Retrieve extraction job history with filtering and cursor-based pagination

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

<Callout icon="circle-check" color="#16a34a">
  **Free** - does not consume credits
</Callout>

<CodeGroup>
  ```bash cURL theme={null}
  curl -X GET "https://xquik.com/api/v1/extractions?limit=20&toolType=reply_extractor" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  const params = new URLSearchParams({
    limit: "20",
    toolType: "reply_extractor",
  });

  const response = await fetch(`https://xquik.com/api/v1/extractions?${params}`, {
    method: "GET",
    headers: {
      "x-api-key": "xq_YOUR_KEY_HERE",
    },
  });
  const data = await response.json();
  ```

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

  response = requests.get(
      "https://xquik.com/api/v1/extractions",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
      params={
          "limit": 20,
          "toolType": "reply_extractor",
      },
  )
  data = response.json()
  ```

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

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

  func main() {
      req, err := http.NewRequest("GET", "https://xquik.com/api/v1/extractions?limit=20&toolType=reply_extractor", nil)
      if err != nil {
          panic(err)
      }
      req.Header.Set("x-api-key", "xq_YOUR_KEY_HERE")

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

      var data map[string]interface{}
      if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
          panic(err)
      }
      fmt.Println(data)
  }
  ```
</CodeGroup>

## Headers

<ParamField header="x-api-key" type="string" required>
  Your API key. Session cookie authentication is also supported. Generate a key from the [dashboard](https://xquik.com/dashboard).
</ParamField>

## Query parameters

<ParamField query="limit" type="number">
  Number of extractions to return per page. Default: `50`. Maximum: `100`.
</ParamField>

<ParamField query="toolType" type="string">
  Filter by tool type. One of: `article_extractor`, `community_extractor`, `community_moderator_explorer`, `community_post_extractor`, `community_search`, `favoriters`, `follower_explorer`, `following_explorer`, `list_follower_explorer`, `list_member_extractor`, `list_post_extractor`, `mention_extractor`, `people_search`, `post_extractor`, `quote_extractor`, `reply_extractor`, `repost_extractor`, `space_explorer`, `thread_extractor`, `tweet_search_extractor`, `user_likes`, `user_media`, `verified_follower_explorer`.
</ParamField>

<ParamField query="status" type="string">
  Filter by job status. One of: `completed`, `failed`, `running`.
</ParamField>

<ParamField query="after" type="string">
  Cursor for pagination. Use the `nextCursor` value from the previous response to fetch the next page.
</ParamField>

## Response

<Tabs>
  <Tab title="200 OK">
    <ResponseField name="extractions" type="object[]">
      Array of extraction job summaries.

      <Expandable title="Extraction object properties">
        <ResponseField name="id" type="string">Unique extraction job ID.</ResponseField>
        <ResponseField name="toolType" type="string">Tool type used for this extraction.</ResponseField>
        <ResponseField name="status" type="string">Job status: `completed`, `failed`, or `running`.</ResponseField>
        <ResponseField name="totalResults" type="number">Total number of extracted results.</ResponseField>
        <ResponseField name="createdAt" type="string">ISO 8601 timestamp of when the job was created.</ResponseField>
        <ResponseField name="completedAt" type="string">ISO 8601 timestamp of when the job finished. Only present for completed jobs.</ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="hasMore" type="boolean">Whether more results exist beyond this page.</ResponseField>
    <ResponseField name="nextCursor" type="string">Cursor to pass as the `after` parameter for the next page. Only present when `hasMore` is `true`.</ResponseField>

    ```json theme={null}
    {
      "extractions": [
        {
          "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
          "toolType": "reply_extractor",
          "status": "completed",
          "totalResults": 150,
          "createdAt": "2026-02-24T10:00:00.000Z",
          "completedAt": "2026-02-24T10:00:12.000Z"
        },
        {
          "id": "b2c3d4e5-f6a1-7890-abcd-ef2345678901",
          "toolType": "follower_explorer",
          "status": "completed",
          "totalResults": 4832,
          "createdAt": "2026-02-23T18:30:00.000Z",
          "completedAt": "2026-02-23T18:31:45.000Z"
        },
        {
          "id": "c3d4e5f6-a1b2-7890-abcd-ef3456789012",
          "toolType": "repost_extractor",
          "status": "failed",
          "totalResults": 0,
          "createdAt": "2026-02-23T12:00:00.000Z"
        }
      ],
      "hasMore": true,
      "nextCursor": "eyJjIjoiMjAyNi0wMi0yM1QxMjowMDowMC4wMDBaIiwiaSI6Ijc3NzY4In0"
    }
    ```
  </Tab>

  <Tab title="401 Unauthenticated">
    ```json theme={null}
    { "error": "unauthenticated" }
    ```

    Missing or invalid API key.
  </Tab>

  <Tab title="429 Rate Limited">
    ```json theme={null}
    { "error": "rate_limit_exceeded", "message": "Too many requests. Try again later.", "retryAfter": 1 }
    ```

    Wait for the `Retry-After` value before making another request.
  </Tab>
</Tabs>

## Pagination

Results are ordered by creation date (newest first). To iterate through all extractions:

1. Make the initial request without the `after` parameter.
2. Check `hasMore` in the response. If `true`, use `nextCursor` as the `after` value in the next request.
3. Repeat until `hasMore` is `false`.

```javascript theme={null}
import { appendFile } from "node:fs/promises";

let cursor = undefined;
let pageIndex = 0;

do {
  const params = new URLSearchParams({
    limit: "100",
    status: "completed",
  });
  if (cursor) params.set("after", cursor);
  const pageCursor = cursor ?? null;

  const response = await fetch(`https://xquik.com/api/v1/extractions?${params}`, {
    headers: { "x-api-key": "xq_YOUR_KEY_HERE" },
  });
  const data = await response.json();

  const rows = data.extractions.map((job) => ({
    extraction_id: job.id,
    tool_type: job.toolType,
    status: job.status,
    total_results: job.totalResults,
    created_at: job.createdAt,
    completed_at: job.completedAt ?? null,
    detail_path: `/api/v1/extractions/${job.id}`,
    export_path:
      job.status === "completed"
        ? `/api/v1/extractions/${job.id}/export?format=csv`
        : null,
    page_index: pageIndex,
    page_cursor: pageCursor,
    next_cursor: data.nextCursor ?? null,
    has_more: data.hasMore,
    handoff_format: "jsonl",
  }));

  if (rows.length > 0) {
    await appendFile(
      "xquik-extraction-jobs.jsonl",
      `${rows.map((row) => JSON.stringify(row)).join("\n")}\n`,
    );
  }

  cursor = data.hasMore ? data.nextCursor : undefined;
  pageIndex += 1;
} while (cursor);
```

## Job inventory handoff

Use `GET /extractions` as the job inventory step before fetching details or
exporting files. Treat `nextCursor` as opaque and pass it back as `after`; do
not dump raw job lists into shared logs.

<CardGroup cols={2}>
  <Card title="Page checkpoint" icon="bookmark">
    Store `page_index`, `page_cursor`, `next_cursor`, `has_more`, `limit`,
    `tool_type_filter`, and `status_filter` after each successful page.
  </Card>

  <Card title="Completed jobs" icon="circle-check">
    Store completed job `id`, `toolType`, `totalResults`, `completedAt`,
    `detail_path`, and `export_path` for the next fetch or file export.
  </Card>

  <Card title="Running or failed jobs" icon="circle-alert">
    Keep `status`, `createdAt`, and `id` so dashboards can retry failed jobs or
    poll running jobs without rereading older pages.
  </Card>

  <Card title="Next API step" icon="route">
    Use [Get Extraction](/api-reference/extractions/get) for paginated JSON
    rows, or [Export Extraction](/api-reference/extractions/export) for files.
  </Card>
</CardGroup>

Store page checkpoints separately from job rows:

```json theme={null}
{
  "page_index": 2,
  "page_cursor": "eyJjIjoiMjAyNi0wMi0yM1QxODozMTo0NS4wMDBaIiwiaSI6Ijc3NzY4In0",
  "next_cursor": "eyJjIjoiMjAyNi0wMi0yM1QxMjowMDowMC4wMDBaIiwiaSI6Ijc3NzY0In0",
  "has_more": true,
  "limit": 100,
  "tool_type_filter": "reply_extractor",
  "status_filter": "completed",
  "handoff_format": "jsonl"
}
```

<Note>
  **Next steps:** [Get Extraction](/api-reference/extractions/get) to retrieve full results for a specific job, or [Create Extraction](/api-reference/extractions/create) to run a new extraction.
</Note>
