---
title: "Submit X Scrape"
method: POST
path: "/api/x/scrape"
tags: ["X"]
---

# Submit X Scrape

`POST /api/x/scrape`

## Request

- Base URL: `https://api.kolens.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.kolens.ai/api/x/scrape`
- Auth: HTTP bearer

Submit an X (Twitter) scrape job.

Pre-charges credits using the same ``ceil(max_tweets / 10)`` shape
as the YT / IG routes. The apidojo X actor is cheaper per item
(~$0.40 / 1K tweets vs ~$2.40 / 1K YT videos) so this is a
conservative over-estimate until the cross-cutting
pricing-per-platform sub-issue lands.

## Headers

- `x-kolens-user-id` string, nullable

## Request body

- XScrapeRequest: Either ``query`` or ``handles`` must be supplied — not both. ``max_tweets`` follows the IG / YT semantics: the number of recent tweets to pull per handle (NOT the total across the batch).
  - `query` string, nullable
  - `handles` string[], nullable
  - `max_tweets` integer

## Response `202`

Successful Response

- XScrapeResponse
  - `job_id` string, required
  - `status` string, required
  - `keyword` string, required
  - `estimated_seconds` integer, required
  - `query_plan` QueryPlanEcho: Display-only echo of how the NL query planner interpreted a typed intent sentence (Phase 1). Returned on the create / search-submit response so the UI can show "Interpreted as: [terms] · filters". Only present when the planner flag is ON *and* the planner produced a real (non-passthrough) interpretation — null otherwise so existing clients ignore it. An editable confirm step is Phase 2.
    - `raw_query` string, required
    - `search_terms` string[]
    - `filters` object
    - `market` string, nullable
    - `language` string, nullable
    - `notes` string

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/kolens/apis/kolens-api.md) · [All operations](https://skmtc.dev/kolens/apis/kolens-api/llms.txt) · [OpenAPI document](https://skmtc.dev/kolens/apis/kolens-api/revisions/5d6865ab0a24?raw)
