searlo-tech Async API

Queue work and collect it later, by polling or webhook.

Operations 5

POST /async/task Queue one task and get a task id back #
POST /async/task/batch Queue up to 500 tasks in one request #
GET /async/task/{taskId} Fetch a queued task and its result (free) #
GET /async/status Queue depth for this account (free) #
DELETE /async/queue Cancel every queued task and refund it (free) #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/searlo-tech:searlo-tech-async-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

searlo-tech-async-api-openapi.yml Raw ↑
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