prompter API
Ask one of nine AI platforms a single question and get the raw answer back, with native citations where the platform provides them. prompter is stateless: every call is a real, live upstream request.
Overview
prompter exposes a small REST API. You send a prompt and a platform, prompter calls that platform, and returns the unmodified answer. It never summarizes or invents data: if a platform cannot answer, the response says so.
Base URL
https://api.prompter.searchestra.com
Conventions
- All request and response bodies are
application/json. - Successful reads return a top level
datafield. Errors return a top levelerrorfield (see Errors). - Every
/v1/*endpoint requires theX-API-Keyheader./healthzdoes not. - Timestamps are UTC, ISO 8601 (for example
2026-08-16T13:47:09Z).
4xx the error message is real and specific. On 5xx (500 and 503) the message is always masked to a fixed string; the real cause is only in prompter's server logs.Quickstart
Send your first query. Replace pr_your_key with the API key issued to your tenant (see Authentication).
curl -X POST https://api.prompter.searchestra.com/v1/collect \
-H "X-API-Key: pr_your_key" \
-H "Content-Type: application/json" \
-d '{
"platform": "perplexity",
"promptText": "which dishwasher detergent is best, briefly",
"countryCode": "tr",
"language": "tr"
}'{
"data": {
"rawText": "Finish and Fairy are among the most preferred...",
"rawHtml": "",
"citations": [
{ "url": "https://example.com/review", "title": "Best detergent", "position": 1 }
],
"textLinks": [],
"collectedAt": "2026-08-16T13:47:09Z"
}
}Authentication
Every /v1/* request must carry an API key in the X-API-Key header. Keys begin with the pr_ prefix and identify a tenant, not a user.
X-API-Key: pr_your_key
The server stores only a SHA-256 hash of the key. The raw value is shown once, at creation, and cannot be recovered. If a key is lost, issue a new one. A tenant can hold several keys; revoking one does not affect the others.
401 unauthorized with a clear message.Query a platform
Sends one prompt to one platform and returns the raw answer. The flow: validate promptText, confirm the platform is registered, then make a real upstream request.
Request body
| Field | Type | Notes |
|---|---|---|
| platform required | string | One of the nine codes (see Platforms). |
| promptText required | string | The question to ask. Must not be empty. |
| countryCode optional | string | ISO country code (for example tr, us). Localizes the system instruction. |
| language optional | string | Language code. Used only by aimode and aio; other platforms ignore it. |
| timeoutMs optional | integer | Upper bound including retries, in milliseconds. Defaults to 25000. |
Response data
| Field | Type | Notes |
|---|---|---|
| rawText | string | The raw answer text. May be empty for aimode and aio when the model produced no AI summary. That is an honest empty result, not an error. |
| rawHtml | string | Reserved. Always empty for now. |
| citations | array | Sources the provider explicitly returned. Only perplexity, aimode and aio populate this. Never null. |
| textLinks | array | Links observed inside the answer text (Markdown links). Not proof of retrieval. Never null. |
| collectedAt | string | prompter's UTC timestamp for the call. |
citations are the provider's native sources. textLinks are links the model wrote into its prose. They use different ordering systems, so relate them by URL, not by position.List platforms
Returns the fixed list of registered platforms. A platform whose credentials are not configured still appears here; it only fails on a real /v1/collect call. Fetch this once and cache it on your side.
{
"data": [
{ "code": "chatgpt", "unsupportedCountries": [] },
{ "code": "perplexity", "unsupportedCountries": null }
]
}unsupportedCountries is either an empty array or null; both mean "no restriction". Treat them the same way.
Health check
Liveness probe for container orchestration. No authentication. Returns 200 when the service is up.
Platforms
Nine platforms have a real integration. citations are native only on the three sourced platforms; the six LLM platforms surface links through textLinks instead.
| Code | Provider | Citations |
|---|---|---|
chatgpt | OpenAI Chat Completions | textLinks only |
claude | Anthropic Messages | textLinks only |
gemini | Google Generative Language | textLinks only |
deepseek | DeepSeek Chat Completions | textLinks only |
grok | xAI Chat Completions | textLinks only |
metaai | Meta Model API | textLinks only |
perplexity | Perplexity Sonar | native |
aimode | Google AI Mode (DataForSEO) | native |
aio | Google AI Overviews (DataForSEO) | native |
Errors
Errors return an error object with a code and a message.
{ "error": { "code": "unauthorized", "message": "X-API-Key required." } }| Status | code | When |
|---|---|---|
| 400 | validation_failed | Empty promptText, or the country is not supported. |
| 401 | unauthorized | Missing, invalid or revoked API key. |
| 404 | not_found | Unknown platform code (typo, or a platform with no integration). |
| 422 | quota_exceeded | Daily request quota or cost budget for this tenant and platform is spent. Try again tomorrow. |
| 429 | rate_limited | Per-key requests per minute or concurrency limit exceeded. Retry shortly. |
| 500 | internal | Upstream or internal failure. Message is masked. |
| 503 | unavailable | Platform not configured, or its circuit breaker is open. Message is masked. |
422 means "try again tomorrow" (a daily budget is spent). 429 means "try again shortly" (a short window limit). Do not confuse them.Rate limits and quotas
prompter applies four independent guards. The first two are per API key and return 429; the next two are per tenant and platform and return 422; the last is shared across all tenants and returns 503.
| Guard | Scope | On limit |
|---|---|---|
| Requests per minute | per API key | 429 rate_limited |
| Concurrent requests | per API key | 429 rate_limited |
| Daily request quota | per tenant and platform | 422 quota_exceeded |
| Daily cost budget | per tenant and platform | 422 quota_exceeded |
| Circuit breaker | per platform, all tenants | 503 unavailable |
Limits scale with your plan. The circuit breaker opens after a platform fails repeatedly and closes automatically after a cooldown.