> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scrapebadger.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Ask Perplexity

> Send a prompt to the real perplexity.ai and get the grounded answer as structured JSON, with its cited sources, search queries and related questions.

Ask **the real `perplexity.ai`** a question anonymously and get the answer back
as JSON, plus every source Perplexity retrieved, which of those it cited, and
the sub-queries it searched for.

Accepts `GET` (query params) or `POST` (JSON body) with identical fields.

**Credits:** 20

> [!WARNING]
>
> This is a live answer, not a cache. A call can take up to about 75 s while
> exits are tried, so set your client timeout to at least 90 s.

## Authorization

**X-API-Key** `string` *required*

Your ScrapeBadger API key.

## Query Parameters

**prompt** `string` *required*

The question to ask. Maximum **4,096 characters**. Each request is standalone,
so include all the context you need here.

**country** `string`

ISO-3166 alpha-2 market, e.g. `US`, `DE`, `JP`. Sets the ask's language and
timezone (e.g. `DE`: `de-DE`, `Europe/Berlin`). Omit it and the market whose
exits answer best right now is used.

The egress is **best-effort**: when that market has no exit left, another one
carries the ask and the response `country` says which. Set `strict_country`
to forbid that.

**strict\_country** `boolean` (default: false)

Answer only from an exit in `country`, never another one. When no exit there
answers in time the call fails with **`503`** and
`detail.code = "country_unavailable"`. It is **not billed** (only `2xx`
responses are). Requires `country` — `400` otherwise. A JSON `boolean` on
`POST`.

**focus** `string` (default: web)

Retrieval focus: `web`, `scholar` (academic sources) or `social`
(discussions and forums).

## Response

**prompt** `string`

Echo of the prompt you sent.

**answer** `string`

The answer text. Citation offsets index into this string.

**answer\_markdown** `string | null`

The answer with its Markdown formatting.

**citations** `Citation[]`

The sources the answer actually references.

**Citation**

**url** `string`

Source URL.

**title** `string | null`

Page title.

**snippet** `string | null`

Snippet Perplexity retrieved from the page.

**domain** `string | null`

Hostname, e.g. `techcrunch.com`.

**source\_type** `string | null`

Perplexity's source kind, e.g. `web`, `scholar`, `social`.

**pub\_date\_utc** `number | null`

Publication date as a Unix timestamp.

**published\_at** `string | null`

Publication date as an ISO-8601 UTC string.

**last\_updated** `string | null`

Last-updated date as reported by Perplexity.

**ref\_index** `integer | null`

The inline `[n]` marker number.

**start\_index** `integer | null`

Character offset in `answer` where the cited span begins.

**end\_index** `integer | null`

Character offset in `answer` where the cited span ends.

**matched\_text** `string | null`

The substring of `answer` this source supports.

**search\_results** `SearchResult[]`

The **full** set Perplexity retrieved, cited or not. Same fields as
`Citation` without the answer offsets, plus `cited` (`boolean`).

**source\_domains** `string[]`

Distinct hostnames across the sources.

**related\_questions** `string[]`

Perplexity's suggested follow-up questions.

**images** `MediaItem[]`

Images attached to the answer (`url`, `title`, `source_url`, `thumbnail`).

**videos** `MediaItem[]`

Videos attached to the answer, same shape.

**web\_search\_triggered** `boolean`

Whether Perplexity searched the web for this answer.

**truncated** `boolean`

`true` when the stream budget expired mid-answer, so `answer` is partial.

**search\_queries** `string[]`

The sub-queries Perplexity sent to its search backend (its retrieval fan-out).

**focus** `string`

The retrieval focus used.

**model** `string | null`

Which model answered. Reported, not requestable.

**backend\_uuid** `string | null`

Perplexity's id for this answer.

**country** `string`

The market that actually answered. Without `strict_country` it can differ from the `country` you asked for.

**answer\_length** `integer`

Length of `answer` in characters.

**citation\_count** `integer`

Number of entries in `citations`.

**latency\_ms** `integer`

End-to-end time in milliseconds.

**created\_utc** `number | null`

Answer creation time as a Unix timestamp.

**created\_at** `string | null`

Answer creation time as an ISO-8601 UTC string.

## Example

```bash cURL theme={null}
curl -G "https://scrapebadger.com/v1/perplexity/ask" \
  -H "X-API-Key: YOUR_API_KEY" \
  --data-urlencode "prompt=Which companies lead the web scraping API market?" \
  --data-urlencode "country=US" \
  --max-time 120
```

```javascript Node.js theme={null}
const res = await fetch("https://scrapebadger.com/v1/perplexity/ask", {
  method: "POST",
  headers: {
    "X-API-Key": process.env.SCRAPEBADGER_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    prompt: "Which companies lead the web scraping API market?",
    country: "US",
  }),
  signal: AbortSignal.timeout(120_000),
});
const data = await res.json();
console.log(data.country, data.answer);
```

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

res = requests.post(
    "https://scrapebadger.com/v1/perplexity/ask",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"prompt": "Which companies lead the web scraping API market?", "country": "US"},
    timeout=120,
)
data = res.json()
for c in data["citations"]:
    print(c["domain"], "->", c["matched_text"])
```

## Strict country

By default `country` is best-effort, so a market that is short of exits still
gets an answer, from another market. Check the response `country` to see which
one answered. When the market matters more than the answer (local rankings,
per-country visibility tracking), set `strict_country=true`:

```bash theme={null}
curl -G "https://scrapebadger.com/v1/perplexity/ask" \
  -H "X-API-Key: YOUR_API_KEY" \
  --data-urlencode "prompt=best electricity provider" \
  --data-urlencode "country=DE" \
  --data-urlencode "strict_country=true" \
  --max-time 120
```

If no exit in that market answers in time you get a `503`, which is not billed.
Retry later rather than dropping `strict_country`:

```json 503 Response theme={null}
{
  "detail": {
    "code": "country_unavailable",
    "message": "no DE exit answered in 16 attempts {...}; strict_country never falls back to another country"
  }
}
```

> [!WARNING]
>
> Perplexity is non-deterministic. The same prompt can return different wording
> and different sources on each call. For tracking, sample on a schedule and
> aggregate.


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