Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Searlo Account 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: Account
description: Balance, usage and capability endpoints. Free — do not consume credits.
paths:
/credits/balance:
get:
tags:
- Account
summary: Credits available to the account (free)
description: 'The credit balance and nothing else about the account. Works with an API key (x-api-key, or Authorization: Bearer sk_...) and with a dashboard login. Free; like any call it counts against the request limits. available is the balance GET /user/profile shows (0 while the account is on hold). The answer is never cached.'
responses:
'200':
description: The balance
content:
application/json:
schema:
$ref: '#/components/schemas/CreditsBalance'
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
operationId: getCreditsBalance
x-operation-id-source: derived
/credit/balance:
get:
tags:
- Account
summary: Current credit balance, with expiry detail
description: The fuller view; GET /credits/balance returns the balance alone.
responses:
'200':
description: Account balance
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
type: object
properties:
balance:
type: number
example: 2500
available:
type: number
example: 2500
description: Credits you can spend now (same as balance).
isLowBalance:
type: boolean
lastUpdated:
type: string
format: date-time
expiry:
type: object
description: When the credits expire.
properties:
policyApplies:
type: boolean
durationDays:
type: integer
totalExpiringAmount:
type: number
nonExpiringAmount:
type: number
nextExpiryAt:
type:
- string
- 'null'
format: date-time
daysUntilNextExpiry:
type:
- integer
- 'null'
nextExpiryAmount:
type:
- number
- 'null'
breakdown:
type: array
items:
type: object
additionalProperties: true
additionalProperties: true
'401':
$ref: '#/components/responses/Unauthorized'
operationId: getCreditBalance
x-operation-id-source: derived
/search/countries:
get:
tags:
- Account
summary: Countries the AI answer endpoints accept as gl (does not consume credits)
description: The countries the AI answer endpoints accept as gl. The search endpoints accept any two-letter gl, applied as the results country.
responses:
'200':
description: Supported countries
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
engine:
type: string
example: all
countries:
type: array
items:
type: object
properties:
code:
type: string
example: US
name:
type: string
example: United States
states:
type: boolean
description: US states are listed by GET /search/states.
exit:
type: boolean
description: Available as gl on the AI answer endpoints.
'401':
$ref: '#/components/responses/Unauthorized'
operationId: getSearchCountries
x-operation-id-source: derived
/search/states:
get:
tags:
- Account
summary: US states with their Google location (does not consume credits)
description: 'US states, with Google''s name and uule token for each. State- and city-level location is not available yet: targeting is false, and a state passed as location or uule returns 400 CITY_LOCATION_UNAVAILABLE. Only country=US is available; any other country returns 400. exitPinning false: results are not localized to the state.'
parameters:
- name: country
in: query
schema:
type: string
default: US
responses:
'200':
description: US states
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
country:
type: string
example: US
exitPinning:
type: boolean
targeting:
type: boolean
example: false
description: 'Whether results can be localized to a state. false: a state location returns 400 CITY_LOCATION_UNAVAILABLE.'
message:
type: string
states:
type: array
items:
type: object
properties:
code:
type: string
example: TX
name:
type: string
example: Texas
location:
type: string
example: Texas,United States
uule:
type: string
'401':
$ref: '#/components/responses/Unauthorized'
operationId: getSearchStates
x-operation-id-source: derived
/search/capabilities:
get:
tags:
- Account
summary: Every endpoint this API serves, priced, with recent health (does not consume…
description: Each endpoint this deployment serves, with its credit price, whether it is switched on (reason when it is not) and its last two hours of calls. state is off when switched off, degraded when at least 3 calls in the window and fewer than half succeeded, live otherwise. May be cached for 30 seconds.
responses:
'200':
description: Capabilities
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
generatedAt:
type: string
format: date-time
capabilities:
type: array
items:
type: object
properties:
id:
type: string
example: serp/html
method:
type: string
example: GET
path:
type: string
example: /serp/html
credits:
oneOf:
- type: number
- type: string
creditsNote:
type: string
group:
type: string
enabled:
type: boolean
reason:
type: string
description: Why it is switched off.
state:
type: string
enum:
- live
- degraded
- 'off'
health:
type: object
properties:
window:
type: string
example: 2h
ok:
type: integer
fail:
type: integer
successRate:
type:
- number
- 'null'
description: 0-1; null with no calls in the window.
states:
type: object
additionalProperties:
type: string
'401':
$ref: '#/components/responses/Unauthorized'
operationId: getSearchCapabilities
x-operation-id-source: derived
/search/analytics:
get:
tags:
- Account
summary: Search history and usage analytics for the key
responses:
'200':
description: Usage analytics
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
operationId: getSearchAnalytics
x-operation-id-source: derived
/credit/transactions:
get:
tags:
- Account
summary: Credit transaction history (does not consume credits)
parameters:
- name: page
in: query
schema:
type: integer
minimum: 1
default: 1
- name: limit
in: query
schema:
type: integer
minimum: 1
maximum: 100
default: 20
- name: type
in: query
schema:
type: string
enum:
- deduction
- grant
- refund
- name: status
in: query
schema:
type: string
enum:
- pending
- completed
- failed
- refunded
responses:
'200':
description: Transactions, newest first
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
type: object
'401':
$ref: '#/components/responses/Unauthorized'
operationId: getCreditTransactions
x-operation-id-source: derived
components:
responses:
RateLimited:
description: 'The account''s rate limit (code 4201), the API key''s own (code 4202) or the cap on searches in flight (code 4203, errorCode CONCURRENCY_LIMIT, Retry-After 1, X-Concurrency-Limit carries the cap). Wait Retry-After seconds. See also AT_CAPACITY / BUSY / VERIFIER_BUSY, a full lane rather than a limit reached. Never charged.
'
headers:
Retry-After:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
Unauthorized:
description: Missing, invalid or expired API key (code UNAUTHORIZED)
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
schemas:
CreditsBalance:
type: object
required:
- success
- credits
properties:
success:
type: boolean
example: true
credits:
type: object
required:
- available
properties:
available:
type: number
example: 2500
description: 'Credits you can spend now: the balance GET /user/profile shows (0 while the account is on hold).'
reserved:
type: number
example: 6
description: 'Present when known: how much of available requests still in flight, or awaiting settlement, already hold.'
expiresAt:
type: string
format: date-time
description: 'Present when some credits expire: when the next ones do.'
expiringCredits:
type: number
description: 'Present with expiresAt: how many credits expire then.'
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