Skip to content

New AI assistant answers: ChatGPT, Gemini, Copilot and AI Mode by API

SerpKite
Get API key

Cited AI answers, JSON extraction and research in one API

SerpKite now writes cited answers from live Google results, turns pages into JSON with your schema and runs async research tasks. Credits, SDKs and MCP.

SerpKite team 8 min read

On this page

Until now SerpKite stopped at retrieval. Search found the sources, extract and crawl read them, and your own model wrote the answer. That is still the most flexible setup, but a lot of agents only need three things from it: a short answer with sources, a page’s data as JSON, or a longer report on a question that takes many searches.

SerpKite now does all three, on the same API key and credit balance:

  • Cited answers. POST /v1/answer answers a question from live Google results and the top pages, with numbered [n] citations. It can stream. include_answer: true adds the same kind of answer to any /v1/search or /v1/news call.
  • Structured extraction. /v1/extract takes a JSON Schema and returns each page’s data as JSON that matches it, or a short summary of each page.
  • Deep research. POST /v1/research starts a background task that plans Google searches, reads and ranks the pages, fills gaps in a second or third round, and returns a Markdown report with citations.

Claude Haiku 5.5 (Anthropic) writes the answers, extractions and reports. OpenAI's Decisions API handles the small typed checks: is this source relevant, is this page a bot wall, is this a yes/no or enum field. Your model choice stays yours; these features are for the cases where you would rather not run that step yourself.

Which one to use

You have You want Use Credits
A search you already run A short answer on top of the results include_answer: true on search or news +2 (+4 with include_content)
A question A quick cited answer from the results page /v1/answer, depth: "fast" 3
A question An answer read from the top pages /v1/answer, depth: "standard" 8 with 3 pages (6–10 for 1–5)
Up to 20 URLs Each page as JSON for your schema /v1/extract with output_schema 5 per page
Up to 20 URLs A short summary of each page /v1/extract with summary: true 5 per page
A broad question A cited report from many searches /v1/research 30 / 75 / 200 (lite / standard / deep)

A rule of thumb: if the question fits in one search, use an answer. If you already know the URLs, use extract. If you would otherwise write a loop of searches and page reads, use research.

Cited answers from live Google results

/v1/answer runs the question on Google and gives the model a numbered list of sources. With depth: "fast" those are the answer box, the knowledge panel and the results’ snippets, which is enough for most factual questions and returns in a few seconds. With depth: "standard" (the default) SerpKite also reads the top num_sources pages (default 3, up to 5) and gives the model the passages most relevant to the question.

curl https://api.serpkite.com/v1/answer \
  -H "Authorization: Bearer $SERPKITE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "q": "what is retrieval-augmented generation", "depth": "standard", "num_sources": 3 }'

The response keeps the answer and its sources apart, so you can render the [n] markers as links and check them:

POST /v1/answer · depth=standard
{
  "request": {
    "endpoint": "answer",
    "engine": "google",
    "q": "what is retrieval-augmented generation",
    "depth": "standard"
  },
  "answer": "Retrieval-augmented generation (RAG) grounds a model's answer in documents retrieved at query time [1], so answers stay current without retraining [2].",
  "citations": [
    {
      "index": 1,
      "title": "Retrieval-augmented generation",
      "link": "https://en.wikipedia.org/wiki/Retrieval-augmented_generation",
      "domain": "en.wikipedia.org"
    },
    {
      "index": 2,
      "title": "What is RAG?",
      "link": "https://www.example.com/blog/what-is-rag",
      "domain": "example.com"
    }
  ],
  "results": [
    "… every source the model was given, numbered"
  ],
  "meta": {
    "credits_used": 8,
    "credits": {
      "search": 4,
      "answer": 4
    }
  }
}

citations holds the sources the answer actually cites, in first-cited order; results holds every source the model saw. A marker that doesn’t point at a source is removed before the response is sent. meta.credits splits the search part from the model part.

With stream: true the endpoint returns Server-Sent Events: the numbered sources first, then the text as it is written, then a done event with the final answer and the total credits. With output_schema the answer comes back as JSON instead of prose, which is handy for “what is the latest version of X” style lookups. Every search option works too: include_domains to answer only from official docs, time: "week" for recent coverage, country and language for local results.

We wrote a step-by-step tutorial for this: cited web answers for RAG agents. The product page is AI Search API.

Pages to JSON with your schema

Add output_schema to an extract call and each page also comes back as JSON that matches it. An optional prompt says what to pick and how to normalise it.

{
  "urls": ["https://www.example.com/pricing"],
  "output_schema": {
    "type": "object",
    "properties": {
      "plans": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "name": { "type": "string" },
            "price_per_month": { "type": ["number", "null"] }
          }
        }
      },
      "free_trial": { "type": "boolean" }
    }
  },
  "prompt": "Monthly prices in USD; null when a plan has no list price."
}

Each result keeps its Markdown and gains output. Values come only from the page, so nullable fields come back as null rather than a guess. A schema made only of booleans and enums is treated as a classification and goes to the decision model, which can only answer with values the schema allows. summary: true adds a short summary of each page, focused on query when you send one.

The full walkthrough, with pydantic and TypeScript examples, is in extract structured data from any web page. See also the AI Data Extraction API page.

Research tasks that end in a cited report

Some questions need a dozen searches and thirty pages: comparing vendors, summarising what changed in a regulation, building a brief from trusted sources. /v1/research runs that work in the background:

  1. Claude plans a first round of Google queries from your input.
  2. Each query runs on Google; the top pages are read and their passages ranked.
  3. The decision model checks whether the notes cover the task and drops off-topic sources.
  4. If something is missing, Claude plans follow-up queries for the next round.
  5. Claude writes the report: a summary, then sections and tables, every claim cited.
effort First-round queries Rounds Pages per query Credits
lite 3 1 2 30
standard 5 2 3 75
deep 8 3 4 200

The call returns 202 with a task ID. Poll GET /v1/research/{id} (free) to see progress (round, queries, sources, current step), or pass webhook_url to receive a signed research.completed event. The result holds the report, its citations, every source read with the query that found it, and every query run. With output_schema you also get the findings as JSON. Results are kept for 24 hours.

The price is flat per effort, reserved when the task is queued and charged only when the report is written. A task that fails is refunded in full; a canceled one pays only for the searches it already ran. Research and crawl tasks share a limit of 20 queued or running tasks per account. More on the Deep Research API page and in the deep research guide.

What you are not billed for

The same rule as the rest of SerpKite: you pay for work that produced something.

  • A failed model step is free. If the model can’t write an answer, the model part is refunded. include_answer returns your results with a meta.warnings entry; /v1/answer returns 503 ai_unavailable and its message says what the search part cost. A failed extraction or summary is reported in output_error or summary_error, and you pay only for the page.
  • Nothing to answer from costs only the search. When the search finds nothing useful, answer is null and the model part is not charged.
  • Pages that aren’t pages are free. A URL that can’t be read is listed in failed at no cost, and so is a short page that turns out to be a bot check, a login wall, a soft 404 or an empty app shell.
  • Stopping a stream early. If your client closes an answer stream before it finishes, the model part is not charged.

The prices for every AI option are on the pricing page and in credits and billing.

How the answers stay grounded

The model may use only the numbered sources it is given, and it is told to say when they don’t answer the question. Text inside a fetched page is treated as data: instructions in a page are ignored. meta.llm reports which provider and model wrote the response and how many tokens it used.

The question and the source text are sent to the model providers under API terms that exclude training. SerpKite doesn’t log prompts or page text, and answers and extractions are not cached. The details are in privacy and data retention.

SDKs, frameworks and MCP

Everything above is in the official SDKs and integrations:

Package Version What’s new
serpkite (npm), serpkite (PyPI), serpkite-go 0.7.0 Answers (plain and streamed), research tasks with a wait helper, and output_schema, prompt and summary on extract
langchain-serpkite 0.3.0 SerpKiteAnswer and SerpKiteResearch tools
@serpkite/ai-sdk 0.4.0 21 tools for the Vercel AI SDK, including answer, research and research_result
Remote MCP server 18 tools, including answer, research and research_result; extract takes output_schema

In TypeScript:

import { SerpKite } from "serpkite";

const sk = new SerpKite(); // reads SERPKITE_API_KEY
const res = await sk.answer({ q: "latest stable Node.js LTS", depth: "fast" });
console.log(res.answer, res.citations);

In Python, a research task:

from serpkite import SerpKite

with SerpKite() as sk:
    task = sk.research("compare managed Postgres offerings in the EU", effort="lite")
    done = sk.wait_research(task.id)
    if done.status == "completed" and done.result:
        print(done.result.report)

In Go:

c := serpkite.NewClient() // reads SERPKITE_API_KEY
res, err := c.Answer(ctx, serpkite.AnswerParams{Q: "latest stable Go release", Depth: serpkite.DepthFast})
if err != nil {
	return err
}
fmt.Println(res.Text())

For a LangChain agent, add the tools next to search:

from langchain_serpkite import SerpKiteAnswer, SerpKiteResearch

tools = [SerpKiteAnswer(depth="fast"), SerpKiteResearch(effort="lite")]

In Claude, Cursor or any other MCP client, connect to the remote MCP server and the answer and research tools show up next to search. research starts a paid task, so like crawl it is not marked read-only.

Where to go next

To try an answer, an extraction or a research task without writing code, open the playground in the dashboard. It runs on your key and credits like any API call.

Written by the SerpKite team. Questions or corrections: support@serpkite.com. Subscribe via RSS.

Related posts

3 min read

Introducing SerpKite

A Google search API built for AI agents: JSON or Markdown, official TypeScript, Python and Go SDKs, LangChain, CrewAI and MCP, and credits that never expire.

Start building

Get your API key in 30 seconds

2,500 free credits, then 1,000 every month. No credit card.