Skip to content

New Official SDKs for TypeScript, Python and Go

SerpKite
Get API key
Docs menu / Quickstart

Quickstart

Create an API key, install the SDK (or use curl), run your first Google search with SerpKite, read the response and check your credit balance. Takes about five minutes.

View as Markdown

This guide takes you from zero to a working search call. Use one of the official SDKs (TypeScript, Python or Go), or any HTTP client: the API is plain JSON over HTTPS.

  1. Create an account and a key

    Sign in at app.serpkite.com with your email, GitHub or Google. New accounts start with 1,000 free credits (2,500 once you link GitHub or Google). No card is needed.

    Open API keys, click Create key, give it a name such as local-dev, and copy the secret. It starts with skt_live_ and is shown only once.

  2. Store the key in an environment variable

    Keep the key out of source code. The SDKs and every example in these docs read it from SERPKITE_API_KEY:

    export SERPKITE_API_KEY="skt_live_..."
  3. Install an SDK (optional)

    The SDKs handle auth, retries, timeouts and typed responses. Skip this step if you prefer curl or your own HTTP client.

    npm install serpkite                          # TypeScript / JavaScript (Node 18+, Bun, Deno, edge)
    pip install serpkite                          # Python 3.9+ (sync and async clients)
    go get github.com/serpkite/serpkite-go   # Go

    LangChain and CrewAI tools are available too. See SDKs.

  4. POST /v1/search takes a JSON object. Only q is required. country sets the country and language the interface language.

    curl https://api.serpkite.com/v1/search \
      -H "Authorization: Bearer $SERPKITE_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{"q":"best espresso machine 2026","country":"us","language":"en"}'
  5. Read the response

    Every endpoint returns the same envelope. request echoes the normalised request, results holds the ten blue links with resolved destination URLs and a canonical domain, and meta tells you what the call cost and whether the page parsed cleanly. All keys are snake_case.

    200 OK · illustrative
    {
      "request": {
        "endpoint": "search",
        "engine": "google",
        "q": "best espresso machine 2026",
        "country": "us",
        "language": "en",
        "num": 10,
        "page": 1,
        "device": "desktop",
        "autocorrect": true
      },
      "results": [
        {
          "position": 1,
          "title": "The Best Espresso Machines of 2026, Tested and Reviewed",
          "link": "https://www.example.com/best-espresso-machines",
          "domain": "example.com",
          "displayed_link": "https://www.example.com › best-espresso-machines",
          "snippet": "We pulled more than 1,200 shots on 42 machines to find the best espresso makers for every budget, from beginner-friendly to prosumer.",
          "date": "Sep 12, 2026",
          "sitelinks": [
            {
              "title": "Best budget pick",
              "link": "https://www.example.com/best-espresso-machines#budget"
            },
            {
              "title": "Best dual boiler",
              "link": "https://www.example.com/best-espresso-machines#dual-boiler"
            }
          ]
        },
        {
          "position": 2,
          "title": "Espresso Machine Buying Guide (2026)",
          "link": "https://coffee.example.org/guides/espresso",
          "domain": "coffee.example.org",
          "displayed_link": "https://coffee.example.org › guides › espresso",
          "snippet": "Single boiler, heat exchanger or dual boiler? What the specs mean and which features are worth paying for."
        },
        {
          "position": 3,
          "title": "r/espresso: What machine would you buy in 2026?",
          "link": "https://www.reddit.com/r/espresso/comments/abc123/",
          "domain": "reddit.com",
          "displayed_link": "https://www.reddit.com › r › espresso",
          "snippet": "Discussion thread with 480 comments comparing entry-level and prosumer machines."
        }
      ],
      "people_also_ask": [
        {
          "question": "What is the #1 rated espresso machine?",
          "snippet": "Reviewers most often rank dual-boiler machines with PID control at the top…",
          "link": "https://www.example.com/best-espresso-machines"
        },
        {
          "question": "Is a $500 espresso machine worth it?",
          "snippet": "For daily drinkers, a mid-range machine usually pays for itself within a year…",
          "link": "https://coffee.example.org/guides/espresso"
        }
      ],
      "related_searches": [
        {
          "query": "best espresso machine under $500"
        },
        {
          "query": "best espresso machine for beginners"
        },
        {
          "query": "dual boiler vs heat exchanger"
        }
      ],
      "meta": {
        "request_id": "req_01J8ZK4M6Q2V7",
        "credits_used": 1,
        "cached": false,
        "engine": "google",
        "latency_ms": 942,
        "parse_quality": "ok",
        "resolved_urls": true
      }
    }

Check what it cost

Every billed response carries headers with the cost and your remaining balance, so you never need a separate call to track spend. meta.credits_used repeats the cost in the body:

Response headers
HTTP/2 200
content-type: application/json
x-request-id: req_01J8ZK4M6Q2V7
x-credits-used: 1
x-credits-remaining: 61499
x-cost-usd: 0.0008
x-cache: MISS
x-latency-ms: 942
x-tokens-estimate: 1184

A regular search costs 1 credit per page of 10 results. Failed, empty and blocked requests are refunded automatically and show X-Credits-Used: 0. See Credits and billing and Response headers.

You can also ask for the balance directly. GET /v1/account is free:

curl "https://api.serpkite.com/v1/account" \
  -H "Authorization: Bearer $SERPKITE_API_KEY"

Get fewer tokens for an LLM

If the results go into a model’s context, ask for Markdown. The same query drops from a large JSON document to a few hundred tokens of prose, with links kept. The SDKs return a plain string for format: "markdown":

curl https://api.serpkite.com/v1/search \
  -H "Authorization: Bearer $SERPKITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"q":"best espresso machine 2026","country":"us","format":"markdown"}'
format=markdown
# best espresso machine 2026

## Results
1. **The Best Espresso Machines of 2026, Tested and Reviewed** — example.com
   https://www.example.com/best-espresso-machines
   We pulled more than 1,200 shots on 42 machines to find the best espresso makers for every budget.
2. **Espresso Machine Buying Guide (2026)** — coffee.example.org
   https://coffee.example.org/guides/espresso
   Single boiler, heat exchanger or dual boiler? What the specs mean.
3. **r/espresso: What machine would you buy in 2026?** — reddit.com
   https://www.reddit.com/r/espresso/comments/abc123/

## People also ask
- **What is the #1 rated espresso machine?** Reviewers most often rank dual-boiler machines with PID control at the top…
- **Is a $500 espresso machine worth it?** For daily drinkers, a mid-range machine usually pays for itself within a year…

## Related searches
best espresso machine under $500 · best espresso machine for beginners · dual boiler vs heat exchanger

format: "compact" returns lean JSON instead, and fields projects only the parts you need (for example results.title,results.link,knowledge_graph). The X-Tokens-Estimate header tells you how big the body is. See Output formats.

Handle errors

Errors always have the same shape and are never billed:

{
  "error": {
    "code": "insufficient_credits",
    "message": "Your balance is 0 credits. Buy a pack at https://app.serpkite.com/billing.",
    "request_id": "req_01J8ZK7T2RX4B"
  }
}

The SDKs raise it as a typed error (SerpKiteError in TypeScript and Python, *serpkite.Error in Go) with status, code, message and the request ID, and retry 429 and 5xx for you.

Retry 429 and 503 with backoff (honour Retry-After). Fix the request for 400, the key for 401, and your balance or limits for 402 and 403. The full list is in Errors.

Parameters are validated strictly: an unknown or misspelled parameter returns 400 invalid_request and names the right one, instead of being ignored.

400 Bad Request
{
  "error": {
    "code": "invalid_request",
    "message": "unknown parameter \"gl\": use country",
    "request_id": "req_01J8ZK9W3HC2D"
  }
}

See Strict validation.

Next steps

Last updated: 2026-09-29