Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Searlo Async API
description: Live search results as clean JSON. The search endpoints return Google results — web, images, news, video, shopping, maps, scholar, patents and the full results page with ads, People Also Ask and AI Overviews — plus AI answers (ChatGPT, Copilot, Gemini), rank checks, web data (scrape, crawl, map, extract) and account endpoints. Get a free API key with 3,000 credits (no card required) at https://dashboard.searlo.tech. Not affiliated with or endorsed by Google LLC or any other search engine. All trademarks belong to their owners.
version: 1.2.0
contact:
name: Searlo
url: https://searlo.tech
email: hello@searlo.tech
license:
name: Proprietary API — see https://searlo.tech/terms
servers:
- url: https://api.searlo.tech/api/v1
description: Production
security:
- ApiKeyAuth: []
- BearerAuth: []
tags:
- name: Async
description: Queue work and collect it later, by polling or webhook.
paths:
/async/task:
post:
tags:
- Async
summary: Queue one task and get a task id back
description: 'Submit work without holding a connection open. Poll `/async/task/{taskId}`, or supply `webhook` and Searlo POSTs the task when it completes or fails. The endpoint''s price is deducted when the task is queued, kept when it completes and refunded when it fails or is cancelled. The field is `endpoint` (not `type`) and the webhook is `webhook: {url, secret}` (not `webhookUrl`); unknown top-level fields are stripped without an error. For `serp`, `news/serp` and `rankings/check` tasks a country `location` is applied as gl; a city or state fails the task at once with CITY_LOCATION_UNAVAILABLE, and it is refunded.'
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/AsyncTaskSpec'
responses:
'202':
description: Task queued
content:
application/json:
schema:
$ref: '#/components/schemas/AsyncTaskReply'
'200':
description: Duplicate idempotencyKey; the existing task, with no new charge
content:
application/json:
schema:
$ref: '#/components/schemas/AsyncTaskReply'
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/InsufficientCredits'
operationId: postAsyncTask
x-operation-id-source: derived
/async/task/batch:
post:
tags:
- Async
summary: Queue up to 500 tasks in one request
description: Each task has the shape of a single request and is charged when it is queued. If credits run out part-way, the remaining tasks are not queued and are absent from `tasks`. A task that fails validation rejects the whole batch.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- tasks
properties:
tasks:
type: array
minItems: 1
maxItems: 500
items:
$ref: '#/components/schemas/AsyncTaskSpec'
responses:
'202':
description: At least one task was queued
content:
application/json:
schema:
$ref: '#/components/schemas/AsyncBatchReply'
'400':
description: No task was queued (each row says why), or the body failed validation
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/AsyncBatchReply'
- $ref: '#/components/schemas/ErrorResponse'
'401':
$ref: '#/components/responses/Unauthorized'
operationId: postAsyncTaskBatch
x-operation-id-source: derived
/async/task/{taskId}:
get:
tags:
- Async
summary: Fetch a queued task and its result (free)
parameters:
- name: taskId
in: path
required: true
schema:
type: string
responses:
'200':
description: The task, with `result` once it has completed or `error` once it has failed
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
task:
$ref: '#/components/schemas/AsyncTask'
'401':
$ref: '#/components/responses/Unauthorized'
'404':
description: No task with that id for this account
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
operationId: getAsyncTaskByTaskId
x-operation-id-source: derived
/async/status:
get:
tags:
- Async
summary: Queue depth for this account (free)
responses:
'200':
description: Queue status
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
queued:
type: integer
processing:
type: integer
priorityBreakdown:
type: array
items:
type: object
properties:
priority:
type: integer
count:
type: integer
last24h:
type: object
properties:
completed:
type: integer
failed:
type: integer
worker:
type: object
description: The answering process's workerId, enabled flag, and inflight and concurrency per lane.
additionalProperties: true
'401':
$ref: '#/components/responses/Unauthorized'
operationId: getAsyncStatus
x-operation-id-source: derived
/async/queue:
delete:
tags:
- Async
summary: Cancel every queued task and refund it (free)
responses:
'200':
description: Queued tasks cancelled
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
cleared:
type: integer
creditsRefunded:
type: number
'401':
$ref: '#/components/responses/Unauthorized'
operationId: deleteAsyncQueue
x-operation-id-source: derived
components:
responses:
Unauthorized:
description: Missing, invalid or expired API key (code UNAUTHORIZED)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
BadRequest:
description: 'Invalid request (code VALIDATION_ERROR; errors lists the fields). Search endpoints also answer 400 PAGE_OUT_OF_RANGE (maxPage) and DATE_FILTER_UNAVAILABLE, with the name in errorCode. Never charged.
'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
InsufficientCredits:
description: 'Account balance too low to complete the request (code INSUFFICIENT_CREDITS). details gives required, available and shortfall; topUpUrl links to buying more.
'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
schemas:
AsyncBatchReply:
type: object
properties:
success:
type: boolean
accepted:
type: integer
total:
type: integer
tasks:
type: array
items:
type: object
properties:
accepted:
type: boolean
duplicate:
type: boolean
taskId:
type: string
status:
type: string
creditsHeld:
type: number
error:
type: string
description: Present when accepted is false.
endpoint:
type: string
description: Present when accepted is false.
AsyncTask:
type: object
properties:
taskId:
type: string
format: uuid
endpoint:
type: string
status:
type: string
enum:
- QUEUED
- PROCESSING
- COMPLETED
- FAILED
- CANCELLED
priority:
type: integer
attempts:
type: integer
creditsHeld:
type: number
creditsUsed:
type: number
creditsRefunded:
type: boolean
request:
type: object
additionalProperties: true
result:
type: object
additionalProperties: true
description: Present when COMPLETED. Oversized results lose their bulkiest top-level fields, listed in `_trimmed`.
error:
type: object
description: Present when FAILED.
properties:
code:
type: string
message:
type: string
retryable:
type: boolean
webhook:
type: object
properties:
url:
type: string
attempts:
type: integer
lastStatus:
type:
- integer
- 'null'
deliveredAt:
type:
- string
- 'null'
format: date-time
queuedAt:
type: string
format: date-time
startedAt:
type:
- string
- 'null'
format: date-time
completedAt:
type:
- string
- 'null'
format: date-time
durationMs:
type:
- integer
- 'null'
expiresAt:
type: string
format: date-time
AsyncTaskReply:
type: object
properties:
success:
type: boolean
duplicate:
type: boolean
task:
$ref: '#/components/schemas/AsyncTask'
AsyncTaskSpec:
type: object
required:
- endpoint
properties:
endpoint:
type: string
description: 'What to run. keywords/*, domain/*, ai/aimode and ai/grok also pass validation, but those endpoints are switched off in production, and ai/perplexity is paused.
'
enum:
- serp
- news/serp
- rankings/check
- ai/chatgpt
- ai/perplexity
- ai/copilot
- ai/gemini
- web
- maps
- shopping
- goto
request:
type: object
additionalProperties: true
description: 'The endpoint''s parameters. Must include `q` (ai/* tasks also accept `prompt`), except for goto, which takes `url` or `urls`. rankings/check reads `keyword` and `domain` but still needs `q`. web reads the search service''s own names (`num`, `start`, `country`, `language`); maps and shopping read `num` for the result count. For serp, news/serp and rankings/check a country `location` is applied as gl; a city or state fails the task at once (CITY_LOCATION_UNAVAILABLE, refunded).
'
priority:
type: integer
minimum: 1
maximum: 100
default: 50
description: Higher runs first.
idempotencyKey:
type: string
maxLength: 128
description: A repeat returns the existing task with no new charge.
webhook:
type: object
required:
- url
description: 'POSTed when the task completes or fails. Any 2xx is delivered; otherwise it is retried after 5 minutes, 30 minutes, 2 hours and 12 hours.
'
properties:
url:
type: string
format: uri
description: HTTPS, resolving to a public address.
secret:
type: string
maxLength: 256
description: 'Signs each delivery: X-Searlo-Signature is v1= followed by the hex HMAC-SHA256 of "<X-Searlo-Timestamp>.<raw body>".
'
ErrorResponse:
type: object
properties:
success:
type: boolean
example: false
code:
description: 'Stable machine-readable name of the failure. Strings: VALIDATION_ERROR, INVALID_JSON, INVALID_IDEMPOTENCY_KEY, CITY_LOCATION_UNAVAILABLE, UNKNOWN_LOCATION, INVALID_DOMAIN, UNAUTHORIZED, INSUFFICIENT_CREDITS, FORBIDDEN, FEATURE_NOT_AVAILABLE, API_KEY_SCOPE_FORBIDDEN, NOT_FOUND, IDEMPOTENCY_REQUEST_IN_PROGRESS, PAYLOAD_TOO_LARGE, QUERY_NOT_SERVED, COUNTRY_UNAVAILABLE, IDEMPOTENCY_KEY_REUSED, TARGET_NOT_ALLOWED, AT_CAPACITY, BUSY, VERIFIER_BUSY, INTERNAL_ERROR, UPSTREAM_UNAVAILABLE, UPSTREAM_RATE_LIMITED, WARMING, UPSTREAM_TIMEOUT, CREDIT_SYSTEM_UNAVAILABLE, REVIEWS_WITHHELD, SERVICE_UNAVAILABLE, UPSTREAM_FAILED. The rate-limit 429s use numbers: 4201 (account), 4202 (API key), 4203 (searches in flight). Some 4xx carry their name in errorCode instead (see errorCode). No error is charged.
'
oneOf:
- type: string
- type: integer
example: CITY_LOCATION_UNAVAILABLE
message:
type: string
description: For people; may be reworded. Branch on code.
retryable:
type: boolean
description: Whether the same request can succeed later.
retryAfterSec:
type: integer
description: Seconds to wait before a retry (also the Retry-After header).
errors:
type: array
description: Validation errors, one per field.
items:
type: object
properties:
field:
type: string
message:
type: string
suggestions:
type: array
items:
type: string
description: 'UNKNOWN_LOCATION: close matches.'
location:
type: string
description: 'CITY_LOCATION_UNAVAILABLE: the place the request named.'
errorCode:
type: string
description: 'The name on errors that carry it here instead of in code, so read code and fall back to errorCode: PAGE_OUT_OF_RANGE (with maxPage), DATE_FILTER_UNAVAILABLE, INVALID_REQUEST, PLACE_NOT_FOUND, TARGET_REFUSED (with targetStatus), TARGET_UNREACHABLE (with targetError), INSUFFICIENT_CREDITS on POST /extract. Also set with code on 4203 (CONCURRENCY_LIMIT), FEATURE_NOT_AVAILABLE, TARGET_NOT_ALLOWED, REVIEWS_WITHHELD and every 503.
'
retryAfter:
type: integer
description: Seconds to wait, on 429 4201 to 4203 and on a retryable 503.
maxPage:
type: integer
description: 'PAGE_OUT_OF_RANGE: the last page that can be served at this limit.'
targetStatus:
type: integer
description: 'TARGET_REFUSED: the site''s own HTTP status.'
targetError:
type: string
description: 'TARGET_UNREACHABLE: why the site could not be fetched.'
details:
type: object
description: 'INSUFFICIENT_CREDITS: required, available and shortfall.'
additionalProperties:
type: number
topUpUrl:
type: string
description: 'INSUFFICIENT_CREDITS: a link to buy more credits.'
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: x-api-key
description: 'API key from your Searlo dashboard, e.g. sk_.... Get a free key with 3,000 credits at https://dashboard.searlo.tech (no card required).
'
BearerAuth:
type: http
scheme: bearer
description: 'The same API key, sent as Authorization: Bearer sk_.... A bearer token that does not start with sk_ is read as a dashboard login token.
'
CseKeyParam:
type: apiKey
in: query
name: key
description: 'The Searlo API key as the key query parameter, where Google''s Custom Search JSON API takes its key. Used by /customsearch/v1 only.
'
externalDocs:
description: Full documentation
url: https://searlo.tech/docs