Every API here is available over the APIs.io API and to AI agents over MCP.
openapi: 3.2.0
info:
title: Spicrawl Com Browser API
version: 1.0.0
contact:
name: Spicrawl support
url: https://docs.spicrawl.com
description: 'Operations tagged Browser across 2 of this provider''s published API definitions: spicrawl-openapi.yaml, spicrawl-com-openapi.yaml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://api.spicrawl.com
description: Production
- url: http://localhost:8080
description: Local development
security:
- bearerAuth: []
tags:
- name: Browser
description: Drive a hosted browser over a DevTools Protocol (CDP) WebSocket.
paths:
/v1/browser:
get:
tags:
- Browser
operationId: browserConnect
summary: Coming soon. Open a DevTools Protocol (CDP) WebSocket to a cloud browser
description: 'Coming soon.
A WebSocket upgrade, not a JSON endpoint. Connect with any CDP client, using the URL as its browser WebSocket endpoint. Authenticate with, in order of preference: `Authorization: Bearer `
on the upgrade; a single-use `token` from `POST /v1/browser/token` (60 s, one connection, bound to its
options — the URL the CLI and MCP return); or the `apikey` query parameter (`api_key` alias), kept for
ZenRows-style URLs. When `token` is present it is the only credential consulted. Requires the
`browser` scope.
Every refusal happens before the upgrade and is an RFC 7807 problem. After the 101 there is no HTTP
response left; the session ends by closing the TCP connection, never with a close frame or error
message.
Why a session ends (recorded server-side, not sent to you):
`client_closed` (you disconnected, or stopped answering WebSocket pings: the API pings every 15 s and
closes after 2 unanswered, so a half-open client frees its slot within about 30 s),
`ttl_expired` (`session_ttl` elapsed; a hard wall, not idle),
`idle_timeout` (no CDP messages in either direction for the deployment idle timeout, 2 minutes by
default, measured from the last message; pings and pongs do not count),
`byte_limit` (the deployment''s per-session traffic cap was reached, if configured),
`upstream_closed` (the browser went away).
Pricing: a session costs 8 credits per started minute, the same as one full-browser-rendered page. At
admission the session HOLDS the price of its whole `session_ttl` against the monthly credit
allowance (default `session_ttl` 180 s = 24 credits; 60–900 s range = 8–120 credits). At close it
is charged for the minutes it actually held (rounded up, capped at `session_ttl`''s minutes) and
the unused part of the hold is returned immediately. A session the platform ends (upstream closed,
or API shutdown) costs 0; a session that never opens costs 0 and returns its hold.
While the operator has switched billing off, sessions hold and cost 0.
Admission, before the upgrade, in this order:
- Rate limit on session opens per key: 429 `ERR::LIMIT::RATE_LIMITED`, with `X-RateLimit-*` and `Retry-After`.
- Monthly credit allowance cannot cover the whole `session_ttl` hold: 402 `ERR::LIMIT::QUOTA_EXCEEDED`,
refused before any browser is leased. A shorter `session_ttl` may fit.
- Simultaneous sessions per organization (`browser_concurrency`, default 2): 429
`ERR::LIMIT::CONCURRENCY_EXCEEDED`, `Retry-After: 5`, `Concurrency-Limit`/`Concurrency-Remaining: 0`.
The slot is held until the socket closes, so always close your browser.
- If the limiter store is unreachable the session is refused (fail closed): 503
`ERR::INTERNAL::UNAVAILABLE`, `Retry-After: 10`.
- No CDP backend on this deployment: 501 `ERR::ENGINE::UNAVAILABLE`, `retryable: false`. Do not retry.
Rate and concurrency headers appear only on refusals; the 101 is the browser backend''s handshake
forwarded verbatim.'
security:
- bearerAuth: []
- apiKeyQuery: []
x-spicrawl-scope: browser
parameters:
- name: token
in: query
description: A single-use browser token from `POST /v1/browser/token`. Consumed on arrival, whatever happens next; expires 60 s after issue; revoked with the key that minted it. The session options are the ones bound into the token; an option in the URL that differs from (or was not part of) the binding is refused with 400 `ERR::REQUEST::INVALID_PARAMETER`. A used, expired or unknown token is 401 `ERR::AUTH::INVALID_KEY`.
schema:
type: string
examples:
- wbt_Q2hhbmdlTWVJbkEtVGVzdC1Ub2tlbi1FeGFtcGxlLVZhbHVlMDE
- name: apikey
in: query
description: The API key, for WebSocket clients that cannot set headers. `api_key` is accepted as an alias. Ignored when an `Authorization` Bearer header is present. Keep the URL out of logs you do not control.
schema:
type: string
examples:
- spicrawl_live_…
- name: api_key
in: query
description: Alias for `apikey`, consulted only when `apikey` is absent or blank.
schema:
type: string
- name: engine
in: query
description: Optional. The rendering tier of the cloud browser - `browser` (default; full browser, full protocol) or `js` (lighter JavaScript rendering with a smaller protocol surface). `fetch` runs no browser and is refused with 400. A tier the plan does not include is 403 `ERR::AUTH::ENGINE_NOT_ENTITLED`; one the deployment lacks is 501 `ERR::ENGINE::UNAVAILABLE`.
schema:
type: string
enum:
- browser
- js
default: browser
- name: proxy_region
in: query
description: Broad exit region such as `eu`. Case-insensitive. `global` means no constraint and is the same as omitting it. Cannot be combined with `proxy_country`.
schema:
type: string
default: global
examples:
- eu
- name: proxy_country
in: query
description: Exit country as a two-letter ISO 3166-1 alpha-2 code (case-insensitive, normalised to lowercase). Combining it with a non-`global` `proxy_region` is refused with 400 `ERR::REQUEST::INCOMPATIBLE_FLAGS`.
schema:
type: string
pattern: ^[A-Za-z]{2}$
examples:
- de
- name: session_ttl
in: query
description: Hard session lifetime in whole seconds. Out-of-range values are refused, not clamped. When it elapses the socket is closed even mid-command.
schema:
type: integer
minimum: 60
maximum: 900
default: 180
- name: headless
in: query
description: Optional and legacy. The display mode is chosen automatically; leave it out. If sent, it is `true`/`1` or `false`/`0` (case-insensitive); anything else is 400.
schema:
type: string
enum:
- 'true'
- 'false'
- '1'
- '0'
- name: sticky_key
in: query
description: Pins the exit for the session. 2-64 letters, digits and hyphens; no underscores. Omitted means the exit rotates, the opposite of `/v1/sessions`.
schema:
type: string
minLength: 2
maxLength: 64
pattern: ^[A-Za-z0-9-]{2,64}$
- name: Upgrade
in: header
required: true
description: Must be `websocket` (case-insensitive). A plain HTTP GET is refused with 400 `ERR::REQUEST::INVALID`.
schema:
type: string
const: websocket
- name: Connection
in: header
required: true
description: Must contain the token `Upgrade`.
schema:
type: string
examples:
- Upgrade
- name: Sec-WebSocket-Key
in: header
required: true
description: Forwarded to the browser backend unchanged; the returned `Sec-WebSocket-Accept` is computed from it. Your WebSocket library sets it.
schema:
type: string
- name: Sec-WebSocket-Version
in: header
required: true
description: Forwarded unchanged. Normally `13`.
schema:
type: string
examples:
- '13'
responses:
'101':
description: Switching Protocols. The socket now carries raw CDP JSON messages in both directions, spliced to the browser without inspection.
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'402':
$ref: '#/components/responses/PaymentRequired'
'403':
$ref: '#/components/responses/Forbidden'
'429':
$ref: '#/components/responses/RateLimited'
'500':
$ref: '#/components/responses/ServerError'
'501':
$ref: '#/components/responses/NotImplemented'
'502':
description: 'The browser backend could not be reached or refused the session (`ERR::UPSTREAM::ERROR`), or the
worker reported another upstream-class code. Not caused by your request; retry with backoff and
quote the `request_id` if it persists.
'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
'503':
$ref: '#/components/responses/ServiceUnavailable'
servers:
- url: https://api.spicrawl.com
description: Production
- url: http://localhost:8080
description: Local development
/v1/browser/token:
post:
tags:
- Browser
operationId: browserToken
summary: Coming soon. Mint a single-use connect URL for /v1/browser
description: 'Coming soon.
Returns a `/v1/browser` URL that carries a short-lived token instead of the API key, for CDP clients
that accept only a URL. The key goes in the `Authorization` header of THIS request only (a query key
is refused). The token is single-use, expires after 60 s, and is bound to the options in the body:
connect with the URL unchanged. `path` is authoritative: the URL relative to the API base. `url` is
built from the deployment''s SPICRAWL_BROWSER_PUBLIC_URL when set, otherwise from this request''s scheme and
Host header (caller-controlled, a convenience only). The token is
never logged and never stored in plaintext. Requires the `browser` scope.'
security:
- bearerAuth: []
x-spicrawl-scope: browser
requestBody:
required: false
content:
application/json:
schema:
type: object
additionalProperties: false
description: The options `GET /v1/browser` accepts, validated the same way. All optional.
properties:
engine:
type: string
enum:
- browser
- js
default: browser
proxy_country:
type: string
pattern: ^[a-z]{2}$
proxy_region:
type: string
sticky_key:
type: string
pattern: ^[A-Za-z0-9-]{2,64}$
session_ttl:
type: integer
minimum: 60
maximum: 900
headless:
type: boolean
responses:
'200':
description: The connect URL, sent with Cache-Control no-store.
content:
application/json:
schema:
type: object
required:
- url
- path
- expires_at
- expires_in
- single_use
properties:
url:
type: string
examples:
- wss://api.spicrawl.com/v1/browser?proxy_country=de&token=wbt_Q2hhbmdlTWVJbkEtVGVzdC1Ub2tlbi1FeGFtcGxlLVZhbHVlMDE
path:
type: string
expires_at:
type: string
format: date-time
expires_in:
type: integer
examples:
- 60
single_use:
type: boolean
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
'403':
$ref: '#/components/responses/Forbidden'
'503':
$ref: '#/components/responses/ServiceUnavailable'
servers:
- url: https://api.spicrawl.com
description: Production
- url: http://localhost:8080
description: Local development
components:
responses:
RateLimited:
description: Rate, concurrency or live-session limit reached. Retryable after `Retry-After`.
headers:
Retry-After:
$ref: '#/components/headers/Retry-After'
X-RateLimit-Limit:
$ref: '#/components/headers/X-RateLimit-Limit'
X-RateLimit-Remaining:
$ref: '#/components/headers/X-RateLimit-Remaining'
X-RateLimit-Reset:
$ref: '#/components/headers/X-RateLimit-Reset'
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
Unauthorized:
description: Missing, invalid, revoked or expired key. Not retryable with the same key.
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
ServiceUnavailable:
description: No proxy exit or engine capacity was available. Retryable after `Retry-After`; 0 credits.
headers:
Retry-After:
$ref: '#/components/headers/Retry-After'
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
Forbidden:
description: The key lacks the scope this route requires (`ERR::AUTH::INSUFFICIENT_SCOPE`), or the action is not permitted.
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
BadRequest:
description: The request is invalid. Not retryable; fix the request using `code` and `diagnostics.hint`.
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
PaymentRequired:
description: '`ERR::LIMIT::QUOTA_EXCEEDED`: the organization is out of credits. Not retryable until credits are added.'
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
X-Credits-Remaining:
description: '`/v1/scrape` only: whole credits left in the monthly allowance when the request was refused. Can be above 0: less than this request needed.'
schema:
type: integer
minimum: 0
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
ServerError:
description: Internal error. Retryable when `retryable` is true.
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
NotImplemented:
description: The capability is not deployed on this host. Not retryable.
headers:
X-Request-Id:
$ref: '#/components/headers/X-Request-Id'
content:
application/problem+json:
schema:
$ref: '#/components/schemas/Problem'
headers:
X-RateLimit-Reset:
description: Seconds until the bucket has one request available again. Only sent when the limiter imposed a wait.
schema:
type: integer
X-RateLimit-Remaining:
description: Requests left in that bucket. Never above `X-RateLimit-Limit`.
schema:
type: integer
X-Request-Id:
description: ULID of this request. Quote it in support requests and use it with `GET /v1/requests/{id}`.
schema:
type: string
X-RateLimit-Limit:
description: Size of the key's rate-limit bucket, the most requests that can be sent back to back.
schema:
type: integer
Retry-After:
description: Seconds to wait before retrying. Present on retryable errors.
schema:
type: integer
minimum: 0
schemas:
Problem:
type: object
description: 'RFC 7807 error body, served as `application/problem+json`. Switch on `code`;
retry only when `retryable` is true, after `retry_after_seconds`.
'
required:
- type
- title
- status
- code
- retryable
- doc_url
- target_status
properties:
type:
type: string
format: uri
description: Link to this code's entry in the error reference.
title:
type: string
description: Short fixed summary of the code. Do not parse it.
status:
type: integer
description: The platform's HTTP status for this response. Not the target site's.
code:
$ref: '#/components/schemas/ErrorCode'
detail:
type: string
description: What happened on this occurrence, in prose. Useful to show a human; do not parse it.
retryable:
type: boolean
description: The server's own verdict on whether the same request can succeed on retry. Prefer it to guessing from `status`.
doc_url:
type: string
format: uri
description: Documentation for this code, including how to fix it.
request_id:
type: string
description: ULID of the failed request. Pass it to `GET /v1/requests/{id}` for the full trace.
instance:
type: string
description: Request path that produced the error.
target_status:
type:
- integer
- 'null'
description: The target site's HTTP status when the failure came from the site, otherwise null.
retry_after_seconds:
type: integer
minimum: 0
description: Mirrors the `Retry-After` header for clients that read only the body.
warnings:
type: array
items:
type: string
description: Non-fatal decisions the platform made for you, such as a flag ignored by proxy precedence.
diagnostics:
$ref: '#/components/schemas/ProblemDiagnostics'
ProblemDiagnostics:
type: object
description: Where the request failed and whether the platform, the proxy or the target was at fault.
properties:
failed_at:
type: string
description: Name of the stage that failed; always the last row of `timeline`.
timeline:
type: array
description: Stages in order, stopping at the failure.
items:
type: object
required:
- stage
- ms
- ok
properties:
stage:
type: string
description: Stage name.
ms:
type: integer
description: Time spent in the stage in milliseconds.
ok:
type: boolean
description: False only on the failing stage.
detail:
type: string
description: What happened in the stage.
attempts:
type: array
description: Each execution attempt. Under `mode=auto` these span the escalation ladder.
items:
type: object
required:
- n
- outcome
- ms
properties:
n:
type: integer
description: Attempt number, from 1.
engine:
type: string
enum:
- fetch
- js
- browser
description: Rendering tier this attempt used (`fetch`, `js` for JavaScript rendering, `browser` for full-browser rendering).
proxy:
type: string
description: Redacted exit label or proxy scheme and host. Never contains credentials.
outcome:
type: string
description: How the attempt ended.
ms:
type: integer
description: Attempt duration in milliseconds.
error_code:
$ref: '#/components/schemas/ErrorCode'
budget_ms:
type: integer
description: Time budget the request had, in milliseconds. Compare with `elapsed_ms` to tell a timeout from a refusal.
elapsed_ms:
type: integer
description: Time actually spent, in milliseconds.
engine:
type: string
enum:
- fetch
- js
- browser
description: Rendering tier that served the final attempt.
proxy:
type: object
description: Redacted description of the exit used.
required:
- source
properties:
source:
type: string
description: 'Where the exit came from: `pool`, `custom` or `direct`.'
endpoint:
type: string
description: Exit identifier. Not the exit IP.
country:
type: string
description: Exit country, ISO 3166-1 alpha-2 lowercase.
hint:
type: string
description: The next thing to try, naming the parameter to change. Act on it before retrying the same request.
ErrorCode:
type: string
description: 'Stable machine-readable error code, `ERR::FAMILY::NAME`. Switch on this, not on
`title` or `detail`. `x-spicrawl-errors` lists each code''s HTTP status and
whether it is retryable.
'
enum:
- ERR::AUTH::MISSING_KEY
- ERR::AUTH::INVALID_KEY
- ERR::AUTH::REVOKED_KEY
- ERR::AUTH::EXPIRED_KEY
- ERR::AUTH::FORBIDDEN
- ERR::AUTH::INSUFFICIENT_SCOPE
- ERR::AUTH::INVALID_TOKEN
- ERR::AUTH::INVALID_CREDENTIALS
- ERR::AUTH::ENGINE_NOT_ENTITLED
- ERR::REQUEST::INVALID
- ERR::REQUEST::MISSING_PARAMETER
- ERR::REQUEST::INVALID_PARAMETER
- ERR::REQUEST::INCOMPATIBLE_FLAGS
- ERR::REQUEST::NOT_FOUND
- ERR::REQUEST::BEYOND_RETENTION
- ERR::REQUEST::CONFLICT
- ERR::REQUEST::PAYLOAD_TOO_LARGE
- ERR::SECURITY::SSRF_BLOCKED
- ERR::SECURITY::URL_BLOCKED
- ERR::SECURITY::INVALID_URL
- ERR::SESSION::NOT_FOUND
- ERR::SESSION::EXPIRED
- ERR::SESSION::RELEASED
- ERR::SESSION::BUSY
- ERR::SESSION::STATE_CORRUPT
- ERR::LIMIT::RATE_LIMITED
- ERR::LIMIT::CONCURRENCY_EXCEEDED
- ERR::LIMIT::QUOTA_EXCEEDED
- ERR::LIMIT::MAX_COST_EXCEEDED
- ERR::LIMIT::SESSIONS_EXCEEDED
- ERR::UPSTREAM::TIMEOUT
- ERR::UPSTREAM::DNS_FAILED
- ERR::UPSTREAM::TLS_FAILED
- ERR::UPSTREAM::CONNECTION_RESET
- ERR::UPSTREAM::TOO_MANY_REDIRECTS
- ERR::UPSTREAM::ERROR
- ERR::UPSTREAM::CHALLENGE
- ERR::PROXY::EXHAUSTED
- ERR::PROXY::UNREACHABLE
- ERR::PROXY::AUTH_FAILED
- ERR::PROXY::RATE_LIMITED
- ERR::ENGINE::RENDER_FAILED
- ERR::ENGINE::UNAVAILABLE
- ERR::EXTRACT::FAILED
- ERR::EXTRACT::INVALID_RULES
- ERR::INTERNAL::ERROR
- ERR::INTERNAL::UNAVAILABLE
x-spicrawl-errors:
ERR::AUTH::MISSING_KEY:
status: 401
retryable: false
title: No API key supplied
ERR::AUTH::INVALID_KEY:
status: 401
retryable: false
title: API key not recognised
ERR::AUTH::REVOKED_KEY:
status: 401
retryable: false
title: API key has been revoked
ERR::AUTH::EXPIRED_KEY:
status: 401
retryable: false
title: API key has expired
ERR::AUTH::FORBIDDEN:
status: 403
retryable: false
title: Not permitted for this organization
ERR::AUTH::INSUFFICIENT_SCOPE:
status: 403
retryable: false
title: API key lacks the required scope
ERR::AUTH::INVALID_TOKEN:
status: 401
retryable: false
title: Session token is invalid or expired
ERR::AUTH::INVALID_CREDENTIALS:
status: 401
retryable: false
title: Email or password is incorrect
ERR::AUTH::ENGINE_NOT_ENTITLED:
status: 403
retryable: false
title: The organization's plan does not include this engine
ERR::REQUEST::INVALID:
status: 400
retryable: false
title: Request could not be understood
ERR::REQUEST::MISSING_PARAMETER:
status: 400
retryable: false
title: A required parameter is missing
ERR::REQUEST::INVALID_PARAMETER:
status: 400
retryable: false
title: A parameter has an invalid value
ERR::REQUEST::INCOMPATIBLE_FLAGS:
status: 400
retryable: false
title: Incompatible flag combination
ERR::REQUEST::NOT_FOUND:
status: 404
retryable: false
title: Resource not found
ERR::REQUEST::BEYOND_RETENTION:
status: 410
retryable: false
title: Beyond the request-log retention window
ERR::REQUEST::CONFLICT:
status: 409
retryable: false
title: Resource already exists
ERR::REQUEST::PAYLOAD_TOO_LARGE:
status: 413
retryable: false
title: Request body is too large
ERR::REQUEST::CAPABILITY_UNSUPPORTED:
status: 400
retryable: false
title: The request needs a capability that is not available
ERR::SECURITY::SSRF_BLOCKED:
status: 400
retryable: false
title: Target resolves to a private address
ERR::SECURITY::URL_BLOCKED:
status: 400
retryable: false
title: Target URL is blocked by policy
ERR::SECURITY::INVALID_URL:
status: 400
retryable: false
title: Target URL is not a valid http(s) URL
ERR::SESSION::NOT_FOUND:
status: 404
retryable: false
title: No such session
ERR::SESSION::EXPIRED:
status: 410
retryable: false
title: Session has expired and its context was purged
ERR::SESSION::RELEASED:
status: 410
retryable: false
title: Session was released and its context was purged
ERR::SESSION::BUSY:
status: 409
retryable: true
title: Session is in use by a running task
ERR::SESSION::STATE_CORRUPT:
status: 500
retryable: false
title: Stored session context could not be read
ERR::LIMIT::RATE_LIMITED:
status: 429
retryable: true
title: Rate limit exceeded
ERR::LIMIT::CONCURRENCY_EXCEEDED:
status: 429
retryable: true
title: Concurrency limit exceeded
ERR::LIMIT::QUOTA_EXCEEDED:
status: 402
retryable: false
title: Credit quota exhausted
ERR::LIMIT::MAX_COST_EXCEEDED:
status: 400
retryable: false
title: Request would exceed max_cost
ERR::LIMIT::SESSIONS_EXCEEDED:
status: 429
retryable: true
title: Too many live sessions
ERR::UPSTREAM::TIMEOUT:
status: 504
retryable: true
title: Target did not respond in time
ERR::UPSTREAM::DNS_FAILED:
status: 502
retryable: true
title: Target hostname could not be resolved
ERR::UPSTREAM::TLS_FAILED:
status: 502
retryable: true
title: TLS handshake with the target failed
ERR::UPSTREAM::CONNECTION_RESET:
status: 502
retryable: true
title: Target closed the connection
ERR::UPSTREAM::TOO_MANY_REDIRECTS:
status: 502
retryable: false
title: Too many redirects
ERR::UPSTREAM::ERROR:
status: 502
retryable: true
title: Target request failed
ERR::UPSTREAM::CHALLENGE:
status: 502
retryable: true
title: Target served a bot challenge
ERR::PROXY::EXHAUSTED:
status: 503
retryable: true
title: No healthy proxy exit available
ERR::PROXY::UNREACHABLE:
status: 502
retryable: false
title: Supplied proxy is unreachable
ERR::PROXY::AUTH_FAILED:
status: 502
retryable: false
title: Proxy rejected the credentials
ERR::PROXY::RATE_LIMITED:
status: 502
retryable: true
title: Proxy exit is rate limited
ERR::ENGINE::RENDER_FAILED:
status: 502
retryable: true
title: The page could not be rendered
ERR::ENGINE::UNAVAILABLE:
status: 503
retryable: true
title: No engine capacity available
ERR::EXTRACT::FAILED:
status: 502
retryable: false
title: The document could not be extracted
ERR::EXTRACT::INVALID_RULES:
status: 400
retryable: false
title: The extraction rules are invalid
ERR::INTERNAL::ERROR:
status: 500
retryable: true
title: Internal error
ERR::INTERNAL::UNAVAILABLE:
status: 503
retryable: true
title: Service temporarily unavailable
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: spicrawl_live_… | spicrawl_test_…
description: '`Authorization: Bearer <key>`. Read the key from the `SPICRAWL_API_KEY` environment
variable; never hard-code or log it. `spicrawl_test_…` keys can never spend live
credits. Scopes: `scrape`, `batch`, `sessions` (granted by default), `browser`
and `read` (granted deliberately). A missing scope is `403
ERR::AUTH::INSUFFICIENT_SCOPE` naming the scope.
'
apiKeyQuery:
type: apiKey
in: query
name: apikey
description: 'The key as a query parameter. Only for clients that cannot set headers, such as
a WebSocket upgrade from a browser-automation library. Prefer `bearerAuth` everywhere
else, because URLs end up in logs.
'
externalDocs:
description: Guides and error reference
url: https://docs.spicrawl.com
x-refined-from:
- spicrawl-openapi.yaml
- spicrawl-com-openapi.yaml