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

# Get extraction

> Retrieve extraction job details with paginated results

<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/a1b2c3d4-e5f6-7890-abcd-ef1234567890?limit=100" \
    -H "x-api-key: xq_YOUR_KEY_HERE" | jq
  ```

  ```javascript Node.js theme={null}
  const extractionId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
  const params = new URLSearchParams({ limit: "100" });

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

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

  extraction_id = "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  response = requests.get(
      f"https://xquik.com/api/v1/extractions/{extraction_id}",
      headers={"x-api-key": "xq_YOUR_KEY_HERE"},
      params={"limit": 100},
  )
  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/a1b2c3d4-e5f6-7890-abcd-ef1234567890?limit=100", 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>

## Path parameters

<ParamField path="id" type="string" required>
  Extraction job ID returned from [Create Extraction](/api-reference/extractions/create) or [List Extractions](/api-reference/extractions/list).
</ParamField>

## Query parameters

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

<ParamField query="after" type="string">
  Result ID 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="job" type="object">
      Extraction job metadata.

      <Expandable title="Job 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="targetTweetId" type="string">Target tweet ID. Present for tweet-based tools.</ResponseField>
        <ResponseField name="targetUsername" type="string">Target username. Present for user-based tools.</ResponseField>
        <ResponseField name="targetUserId" type="string">Target X user ID. Present for user-based tools.</ResponseField>
        <ResponseField name="targetCommunityId" type="string">Target community ID. Present for `community_extractor`, `community_moderator_explorer`, `community_post_extractor`, `community_search`.</ResponseField>
        <ResponseField name="searchQuery" type="string">Search query. Present for `people_search`, `community_search`.</ResponseField>
        <ResponseField name="errorMessage" type="string">Error description. Only present for failed jobs.</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="results" type="object[]">
      Array of extracted user/tweet records for the current page.

      <Info>
        Only `id` and `xUserId` are guaranteed on every result. All other fields are **omitted entirely** when unavailable (never set to `null`). Always check for the presence of a field before accessing it.
      </Info>

      <Expandable title="Result object properties">
        <ResponseField name="id" type="string" required>Unique result ID.</ResponseField>
        <ResponseField name="xUserId" type="string" required>X user ID.</ResponseField>
        <ResponseField name="xUsername" type="string">X username (handle). Omitted if unavailable.</ResponseField>
        <ResponseField name="xDisplayName" type="string">X display name. Omitted if unavailable.</ResponseField>
        <ResponseField name="xFollowersCount" type="number">Follower count at time of extraction. Omitted if unavailable.</ResponseField>
        <ResponseField name="xVerified" type="boolean">Whether the user has a verified badge. Omitted if unavailable.</ResponseField>
        <ResponseField name="xProfileImageUrl" type="string">URL to the user's profile image. Omitted if unavailable.</ResponseField>
        <ResponseField name="tweetId" type="string">Tweet ID. Omitted for non-tweet-based extractions.</ResponseField>
        <ResponseField name="tweetText" type="string">Tweet text content. Omitted for non-tweet-based extractions.</ResponseField>
        <ResponseField name="tweetCreatedAt" type="string">ISO 8601 timestamp of the tweet. Omitted for non-tweet-based extractions.</ResponseField>
        <ResponseField name="createdAt" type="string">ISO 8601 timestamp of when the result was created.</ResponseField>
        <ResponseField name="enrichmentData" type="object">Additional profile, tweet, and article metadata. Omitted when unavailable. Contains nested user fields (`description`, `location`, `coverPicture`, `followingCount`, `favouritesCount`, `mediaCount`, `statusesCount`), tweet fields (`likeCount`, `replyCount`, `repostCount`, `quoteCount`, `viewCount`, `bookmarkCount`, `conversationId`, `lang`, `source`), and article fields (`title`, `bodyText`, `previewText`).</ResponseField>
      </Expandable>
    </ResponseField>

    <Tip>
      Enrichment data is returned directly in the API response via the `enrichmentData` field and is also available through [Export Extraction](/api-reference/extractions/export) in CSV, XLSX, or Markdown format with flattened columns.
    </Tip>

    <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}
    {
      "job": {
        "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "toolType": "reply_extractor",
        "status": "completed",
        "totalResults": 150,
        "targetTweetId": "1893704267862470862",
        "createdAt": "2026-02-24T10:00:00.000Z",
        "completedAt": "2026-02-24T10:00:12.000Z"
      },
      "results": [
        {
          "id": "b2c3d4e5-f6a1-7890-abcd-ef2345678901",
          "xUserId": "44196397",
          "xUsername": "elonmusk",
          "xDisplayName": "Elon Musk",
          "xFollowersCount": 210500000,
          "xVerified": true,
          "xProfileImageUrl": "https://pbs.twimg.com/profile_images/el0n.jpg",
          "tweetId": "1893710452812718080",
          "tweetText": "This is a great thread, thanks for sharing.",
          "tweetCreatedAt": "2026-02-24T10:05:00.000Z",
          "createdAt": "2026-02-24T10:00:05.000Z"
        },
        {
          "id": "c3d4e5f6-a1b2-7890-abcd-ef3456789012",
          "xUserId": "1849726401547751424",
          "xUsername": "xquik_",
          "xDisplayName": "Xquik",
          "xFollowersCount": 2400,
          "xVerified": false,
          "xProfileImageUrl": "https://pbs.twimg.com/profile_images/xquik.jpg",
          "tweetId": "1893712000288563200",
          "tweetText": "Agreed, very useful tool.",
          "tweetCreatedAt": "2026-02-24T10:08:30.000Z",
          "createdAt": "2026-02-24T10:00:06.000Z"
        }
      ],
      "hasMore": true,
      "nextCursor": "c3d4e5f6-a1b2-7890-abcd-ef3456789012"
    }
    ```
  </Tab>

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

    Missing or invalid API key.
  </Tab>

  <Tab title="404 Not Found">
    ```json theme={null}
    { "error": "not_found" }
    ```

    No extraction job exists with this ID, or it belongs to a different account.
  </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 polling again.
  </Tab>
</Tabs>

## Paginating results

Results are ordered by ID ascending. To iterate through all results for a large extraction:

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";

const extractionId = "a1b2c3d4-e5f6-7890-abcd-ef1234567890";
let cursor = undefined;
let pageIndex = 0;

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

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

  const rows = data.results.map((result) => ({
    extraction_id: extractionId,
    row_id: result.id,
    x_user_id: result.xUserId,
    x_username: result.xUsername,
    tweet_id: result.tweetId,
    tweet_text: result.tweetText,
    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-results.jsonl",
      `${rows.map((row) => JSON.stringify(row)).join("\n")}\n`,
    );
  }

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

## Cursor handoff

Use `GET /extractions/{id}` when an integration needs structured JSON rows,
incremental checkpoints, or more rows than a file export can return. Treat
`nextCursor` as an opaque checkpoint and pass it back as `after`.

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

  <Card title="Row shape" icon="braces">
    Persist selected fields such as `row_id`, `x_user_id`, `x_username`,
    `tweet_id`, and `tweet_text`. Do not dump raw result arrays into shared logs.
  </Card>

  <Card title="Large jobs" icon="list-tree">
    Stream pages to `xquik-extraction-results.jsonl` when you need replayable
    rows or results beyond the export row cap.
  </Card>

  <Card title="File handoff" icon="download">
    Use [Export Extraction](/api-reference/extractions/export) when CSV, JSON,
    XLSX, Markdown, PDF, or TXT files are enough.
  </Card>
</CardGroup>

Store page checkpoints separately from row data:

```json theme={null}
{
  "extraction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "page_index": 3,
  "page_cursor": "990100",
  "next_cursor": "990200",
  "has_more": true,
  "result_count": 1000,
  "handoff_format": "jsonl"
}
```

<Note>
  **Next steps:** [Export Extraction](/api-reference/extractions/export) to download all results as CSV, XLSX, or Markdown, or [List Extractions](/api-reference/extractions/list) to browse your job history.
</Note>
