Properties
| Name | Type | Description |
|---|---|---|
| connected | boolean | |
| openUrl | string | |
| error | string | |
| totals | object | |
| prevTotals | object | |
| rows | array | by=date: one row per day. by=query|page: ranked by clicks. |
| fetchedAt | string | |
| dataThrough | string | |
| stale | boolean | Google failed; this is the last good copy from fetchedAt. |
| refreshLimited | boolean | refresh=1 came within 10 minutes of the last fetch; cached numbers. |
| top | object | Core and up, by=date without path: top 10 searches and pages by clicks. |
| improve | array | by=date without path: up to 5 pages to improve (Free: 3). |
| improveLimited | boolean | Free: improve is cut to 3. |
| queries | array | Core and up, with path: the page's top 5 searches. |
| before | object | |
| after | object | |
| delta | object | after − before, on each number. |
| complete | boolean | around: false while the after window is still coming in. |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/dotsy-ai/json-schema/dotsy-ai-search-performance-schema.json",
"title": "SearchPerformance",
"x-generated": "2026-11-06",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/dotsy-ai-openapi.yml#/components/schemas/SearchPerformance",
"type": "object",
"properties": {
"connected": {
"type": "boolean"
},
"openUrl": {
"type": "string"
},
"error": {
"type": "string"
},
"totals": {
"type": "object",
"properties": {
"clicks": {
"type": "number"
},
"impressions": {
"type": "number"
},
"ctr": {
"type": "number",
"description": "clicks / impressions, 0–1."
},
"position": {
"type": "number",
"description": "Average position, weighted by impressions."
}
},
"required": [
"clicks",
"impressions",
"ctr",
"position"
]
},
"prevTotals": {
"type": "object",
"properties": {
"clicks": {
"type": "number"
},
"impressions": {
"type": "number"
},
"ctr": {
"type": "number",
"description": "clicks / impressions, 0–1."
},
"position": {
"type": "number",
"description": "Average position, weighted by impressions."
}
},
"required": [
"clicks",
"impressions",
"ctr",
"position"
]
},
"rows": {
"type": "array",
"items": {
"type": "array",
"prefixItems": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"description": "[key, clicks, impressions, ctr, position]. key is a date, a search, or a site path."
},
"description": "by=date: one row per day. by=query|page: ranked by clicks."
},
"fetchedAt": {
"type": "string"
},
"dataThrough": {
"type": "string"
},
"stale": {
"type": "boolean",
"description": "Google failed; this is the last good copy from fetchedAt."
},
"refreshLimited": {
"type": "boolean",
"description": "refresh=1 came within 10 minutes of the last fetch; cached numbers."
},
"top": {
"type": "object",
"properties": {
"queries": {
"type": "array",
"items": {
"type": "array",
"prefixItems": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"description": "[key, clicks, impressions, ctr, position]. key is a date, a search, or a site path."
}
},
"pages": {
"type": "array",
"items": {
"type": "array",
"prefixItems": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"description": "[key, clicks, impressions, ctr, position]. key is a date, a search, or a site path."
}
}
},
"required": [
"queries",
"pages"
],
"description": "Core and up, by=date without path: top 10 searches and pages by clicks."
},
"improve": {
"type": "array",
"items": {
"$ref": "#/$defs/SearchOpportunity"
},
"description": "by=date without path: up to 5 pages to improve (Free: 3)."
},
"improveLimited": {
"type": "boolean",
"description": "Free: improve is cut to 3."
},
"queries": {
"type": "array",
"items": {
"type": "array",
"prefixItems": [
{
"type": "string"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
],
"description": "[key, clicks, impressions, ctr, position]. key is a date, a search, or a site path."
},
"description": "Core and up, with path: the page's top 5 searches."
},
"before": {
"type": "object",
"properties": {
"clicks": {
"type": "number"
},
"impressions": {
"type": "number"
},
"ctr": {
"type": "number",
"description": "clicks / impressions, 0–1."
},
"position": {
"type": "number",
"description": "Average position, weighted by impressions."
},
"start": {
"type": "string"
},
"end": {
"type": "string"
}
},
"required": [
"clicks",
"impressions",
"ctr",
"position",
"start",
"end"
]
},
"after": {
"type": "object",
"properties": {
"clicks": {
"type": "number"
},
"impressions": {
"type": "number"
},
"ctr": {
"type": "number",
"description": "clicks / impressions, 0–1."
},
"position": {
"type": "number",
"description": "Average position, weighted by impressions."
},
"start": {
"type": "string"
},
"end": {
"type": "string"
}
},
"required": [
"clicks",
"impressions",
"ctr",
"position",
"start",
"end"
]
},
"delta": {
"type": "object",
"properties": {
"clicks": {
"type": "number"
},
"impressions": {
"type": "number"
},
"ctr": {
"type": "number",
"description": "clicks / impressions, 0–1."
},
"position": {
"type": "number",
"description": "Average position, weighted by impressions."
}
},
"required": [
"clicks",
"impressions",
"ctr",
"position"
],
"description": "after − before, on each number."
},
"complete": {
"type": "boolean",
"description": "around: false while the after window is still coming in."
}
},
"$defs": {
"SearchOpportunity": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "`{kind}:{path}:{query}`. Stable across reads of the same numbers."
},
"source": {
"type": "string",
"enum": [
"gsc"
]
},
"kind": {
"type": "string",
"enum": [
"ctr_gap",
"striking_distance",
"not_shown"
]
},
"path": {
"type": "string"
},
"query": {
"type": "string"
},
"metric": {
"type": "object",
"properties": {
"clicks": {
"type": "number"
},
"impressions": {
"type": "number"
},
"ctr": {
"type": "number",
"description": "clicks / impressions, 0–1."
},
"position": {
"type": "number",
"description": "Average position, weighted by impressions."
}
},
"required": [
"clicks",
"impressions",
"ctr",
"position"
]
},
"potentialClicks": {
"type": "number",
"description": "A guess at extra clicks a month. Absent on not_shown."
},
"why": {
"type": "string"
},
"fix": {
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"edit_title",
"brief_agent",
"check_indexing"
]
},
"tool": {
"type": "string",
"enum": [
"patch_route",
"inspect_url"
]
},
"prompt": {
"type": "string",
"description": "A ready instruction for an agent."
}
},
"required": [
"action",
"prompt"
]
}
},
"required": [
"id",
"source",
"kind",
"metric",
"why",
"fix"
]
}
}
}
Work with this as data
Every JSON Schema 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 schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.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.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/dotsy-ai-search-performance"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
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.