{
  "openapi": "3.1.0",
  "info": {
    "title": "ChatGPT AI Visibility API",
    "version": "1.0.0",
    "description": "AI visibility tracking for ChatGPT: whether an answer mentions a brand, whether it cites the brand’s pages, where the brand ranks among the options the answer recommends over repeated runs, the prompts and searches that lead to a topic, and share of voice across prompts — exposed through FetchLayer as structured JSON."
  },
  "servers": [
    {
      "url": "https://api.fetchlayer.dev/chatgpt"
    }
  ],
  "security": [
    {
      "BearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API Key",
        "description": "Send your FetchLayer key as Authorization: Bearer ss-your-key."
      }
    }
  },
  "paths": {
    "/mentions": {
      "post": {
        "operationId": "mentions",
        "tags": [
          "AI visibility"
        ],
        "summary": "Check brand mentions and citations",
        "description": "Whether named brands appear in one ChatGPT answer, and whether that answer actually cites them. The two are different and both come back: a brand can be recommended in the prose while none of its pages are among the sources (mentioned true, citedAsSource false), and a page can be cited without the brand being recommended. Each target reports mentioned, mentionCount, firstMentionIndex, orderOfFirstMention, contexts (each match with the sentence around it), citedAsSource with sourcePositions into the answer’s sources, and retrieved — one of its domains was among the pages ChatGPT read while searching, even if it cited none. otherBrandsMentioned is the brands the answer itself put forward, each with the rank it gave them: your competitor set for that prompt, as ChatGPT sees it. A brand to look for: a name such as \"FetchLayer\", or an object { name, aliases[], domains[] }. Names and aliases match on whole words, case-insensitively — \"Twenty\" matches \"twenty's\" and \"(TWENTY)\", not \"Twentyfold\". Domains match when the answer writes them out, subdomains included and look-alikes excluded. Give aliases and domains when the name is an ordinary word. Answers vary between runs, so a single check is a snapshot; use ai-rank to track a brand over several answers. Billing: 1 credit — one answer.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "The prompt, exactly as a person would type it into ChatGPT (1–4000 characters)."
                  },
                  "targets": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "description": "The brands to look for, 1–10. A brand to look for: a name such as \"FetchLayer\", or an object { name, aliases[], domains[] }. Names and aliases match on whole words, case-insensitively — \"Twenty\" matches \"twenty's\" and \"(TWENTY)\", not \"Twentyfold\". Domains match when the answer writes them out, subdomains included and look-alikes excluded. Give aliases and domains when the name is an ordinary word."
                  },
                  "includeAnswer": {
                    "type": "boolean",
                    "description": "Include the full answer in the response.",
                    "example": "true"
                  },
                  "provider": {
                    "type": "string",
                    "description": "The assistant to ask. chatgpt is the only one available today; the field exists so the same request serves further assistants as they are added.",
                    "example": "chatgpt"
                  },
                  "country": {
                    "type": "string",
                    "description": "Two-letter country the answer should come from, such as US, GB or DE. Answers differ by country. When that country cannot be served, the answer comes from the default one and notes says so.",
                    "example": "us"
                  },
                  "language": {
                    "type": "string",
                    "description": "Language of ChatGPT’s own interface, such as en, de or pt-BR. The answer itself follows the language of your prompt.",
                    "example": "en"
                  },
                  "webSearch": {
                    "type": "string",
                    "description": "auto lets ChatGPT decide whether to search the web; on asks it to search before answering, and answer.usedWebSearch reports what it did. There is no \"off\": an anonymous visitor has no such setting.",
                    "example": "auto"
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown.",
                    "example": "json"
                  }
                },
                "additionalProperties": false,
                "required": [
                  "prompt",
                  "targets"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "prompt": "best reddit api alternatives",
                    "targets": [
                      {
                        "name": "FetchLayer",
                        "domains": [
                          "fetchlayer.dev"
                        ]
                      },
                      "Apify"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "resultType": {
                      "type": "string",
                      "description": "ask, mentions, ai-rank, prompt-discovery or visibility-report."
                    },
                    "provider": {
                      "type": "string",
                      "description": "The assistant that was asked. Always \"chatgpt\" today."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The assistant page the answers correspond to."
                    },
                    "transport": {
                      "type": "string",
                      "description": "The upstream source. Always \"chatgpt\"."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats you can act on — a country that could not be served, runs that could not be completed, details the answer did not show. Empty when there are none. Read it on every call."
                    },
                    "answersGenerated": {
                      "type": "number",
                      "description": "Answers ChatGPT produced for this request."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Billable units, which is the same number: one credit per answer. An answer that could not be produced is never billed."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of when the data was collected."
                    },
                    "prompt": {
                      "type": "string",
                      "description": "The prompt that was asked."
                    },
                    "targets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "The brand name."
                          },
                          "mentioned": {
                            "type": "boolean",
                            "description": "Whether the answer text names it."
                          },
                          "mentionCount": {
                            "type": "number",
                            "description": "How many times. Overlapping matches count once."
                          },
                          "firstMentionIndex": {
                            "type": "number",
                            "description": "Character offset of the first mention in answer.text, or null."
                          },
                          "orderOfFirstMention": {
                            "type": "number",
                            "description": "1 for whichever of your targets the answer mentions first, or null when it mentions none."
                          },
                          "contexts": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Each match: offset, matched (the text that matched) and snippet (the surrounding sentence). Read it when a brand name is an ordinary word."
                          },
                          "citedAsSource": {
                            "type": "boolean",
                            "description": "Whether the answer cites one of its pages. Matched on the cited page’s hostname, where subdomains count and look-alikes do not."
                          },
                          "sourcePositions": {
                            "type": "array",
                            "items": {
                              "type": "number"
                            },
                            "description": "Positions in answer.sources that belong to it."
                          },
                          "retrieved": {
                            "type": "boolean",
                            "description": "Whether one of its domains was among the pages ChatGPT read while searching, cited or not. null when the answer did not show what it read."
                          }
                        }
                      },
                      "description": "One entry per brand you gave, in the order you gave them."
                    },
                    "otherBrandsMentioned": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "The brands the answer itself presents that are none of your targets — the entries of its recommendation list with their rank, and the sites it links by name. Each { name, rank, firstMentionIndex }."
                    },
                    "answer": {
                      "type": "object",
                      "properties": {
                        "markdown": {
                          "type": "string",
                          "description": "The answer as Markdown. Citations appear inline as ([label](url))."
                        },
                        "text": {
                          "type": "string",
                          "description": "The answer as plain text: no formatting, no citation labels. Every character offset in this response points into this string."
                        },
                        "sources": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true,
                            "properties": {
                              "position": {
                                "type": "number",
                                "description": "1-based position in the citation order."
                              },
                              "url": {
                                "type": "string",
                                "description": "The destination URL, with the assistant’s own tracking parameter removed."
                              },
                              "title": {
                                "type": "string",
                                "description": "The page title."
                              },
                              "domain": {
                                "type": "string",
                                "description": "Hostname of url."
                              },
                              "attribution": {
                                "type": "string",
                                "description": "The label shown on the citation, e.g. \"Reddit Help\"."
                              },
                              "publishedAt": {
                                "type": "string",
                                "description": "When the page was published, or null when the answer did not show it."
                              },
                              "citedText": {
                                "type": "string",
                                "description": "The sentence that first cites this page. null for a page listed only in the answer’s closing \"Sources\" list, which comes after the cited ones."
                              },
                              "citationCount": {
                                "type": "number",
                                "description": "How many citations in the answer point at this page."
                              }
                            }
                          },
                          "description": "The pages the answer cites, in the order it first cites them."
                        },
                        "inlineCitations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Each citation in the answer: index, citedText (the sentence it is attached to) and sourcePositions (into sources)."
                        },
                        "searchQueries": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The web searches ChatGPT ran for this answer, in order. [] when it did not search, null when the answer did not show them."
                        },
                        "retrievedPages": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Every page it looked at while searching — url, title, domain, snippet, publishedAt and cited. A page can be read and never cited, which is worth knowing on its own. null when the answer did not show them."
                        },
                        "sitesConsulted": {
                          "type": "number",
                          "description": "How many sites ChatGPT said it consulted, or null."
                        },
                        "usedWebSearch": {
                          "type": "boolean",
                          "description": "Whether this answer used the web."
                        },
                        "model": {
                          "type": "string",
                          "description": "The model the answer reported, or null when it did not say. It is never guessed."
                        },
                        "answeredAt": {
                          "type": "string",
                          "description": "ISO 8601 timestamp of when the answer finished."
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "resultType": "mentions",
                      "provider": "chatgpt",
                      "requestedUrl": "https://chatgpt.com/",
                      "transport": "chatgpt",
                      "notes": [],
                      "answersGenerated": 1,
                      "pagesScraped": 1,
                      "scrapedAt": "2026-09-16T01:57:30.208Z",
                      "prompt": "best reddit api alternatives",
                      "targets": [
                        {
                          "name": "FetchLayer",
                          "mentioned": false,
                          "mentionCount": 0,
                          "firstMentionIndex": null,
                          "orderOfFirstMention": null,
                          "contexts": [],
                          "citedAsSource": false,
                          "sourcePositions": [],
                          "retrieved": true
                        },
                        {
                          "name": "Apify",
                          "mentioned": true,
                          "mentionCount": 1,
                          "firstMentionIndex": 510,
                          "orderOfFirstMention": 1,
                          "contexts": [
                            {
                              "offset": 510,
                              "matched": "Apify",
                              "snippet": "…for production live search without maintaining scrapers; pricing and capabilities vary. Apify Reddit scrapers — useful for extraction jobs and datasets rather than a conventional…"
                            }
                          ],
                          "citedAsSource": false,
                          "sourcePositions": [],
                          "retrieved": false
                        }
                      ],
                      "otherBrandsMentioned": [
                        {
                          "name": "Arctic Shift",
                          "rank": 1,
                          "firstMentionIndex": 60
                        },
                        {
                          "name": "PullPush",
                          "rank": 2,
                          "firstMentionIndex": 171
                        }
                      ],
                      "answer": {
                        "text": "For Reddit API alternatives in 2026, the main options are:\n\nArctic Shift — free historical Reddit dumps; best for bulk research/archive data, not real-time.\nPullPush — Pushshift-compatible historical REST API; useful for older scripts, but community-run and less reliable.\n…",
                        "sources": [
                          {
                            "position": 1,
                            "url": "https://www.redditapis.com/blogs/reddit-api-ai-training-data-2026",
                            "title": "Arctic Shift for Reddit 2026: AI Training Data, JSONL, APIs",
                            "domain": "redditapis.com",
                            "attribution": "Reddit APIs",
                            "publishedAt": "2026-06-25T00:00:00.000Z",
                            "citedText": "Arctic Shift — free historical Reddit dumps; best for bulk research/archive data, not real-time.",
                            "citationCount": 2
                          }
                        ],
                        "searchQueries": [
                          "Reddit API alternatives Reddit data API Pushshift Arctic Shift PullPush 2026"
                        ],
                        "sitesConsulted": 8,
                        "usedWebSearch": true,
                        "model": "gpt-5-6",
                        "answeredAt": "2026-09-16T01:57:30.206Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/ai-rank": {
      "post": {
        "operationId": "ai-rank",
        "tags": [
          "AI visibility"
        ],
        "summary": "Track where a brand ranks in ChatGPT answers",
        "description": "Where a brand ranks among the options a ChatGPT answer recommends, over several answers to the same prompt — the AI analogue of a search rank check, and the route to use for tracking. Each run reports rank (null when the brand is not one of the recommendations), mentioned, citedAsSource, citationRank (its best position among the pages the answer cites, a separate ranking from the recommendations), method, the ordered recommendations the rank was read from, and competitorRanks. method says where the ranking came from, because answers are not laid out the same way twice: numbered_list, table, headings, bulleted_list, or first_mention when the answer presents no list at all and the ranking is the order your brands are first mentioned. A brand mentioned only in the surrounding prose has rank null and mentioned true. Answers vary between runs — the same prompt gives a different answer minutes apart — which is exactly why this route asks it repeatedly: read aggregate (mentionRate, averageRank, bestRank, worstRank, citationRate, averageCitationRank), not any single run, and keep prompt, country and webSearch fixed when comparing over time. runs is 1–5. Timing: every answer is a real ChatGPT session, and a request’s answers are generated alongside each other rather than one after the other — asking for more answers costs credits, not proportionally more time. Measured against the live service, the largest request this route accepts finishes inside a minute. For tracking wider than one request allows, run several smaller requests on a schedule and store the results, rather than trying to fit everything into one call. Billing: 1 credit per completed run; runs that could not be completed are noted and not billed.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "The prompt, exactly as a person would type it into ChatGPT (1–4000 characters)."
                  },
                  "target": {
                    "type": "object",
                    "additionalProperties": true,
                    "description": "The brand whose rank you want. A brand to look for: a name such as \"FetchLayer\", or an object { name, aliases[], domains[] }. Names and aliases match on whole words, case-insensitively — \"Twenty\" matches \"twenty's\" and \"(TWENTY)\", not \"Twentyfold\". Domains match when the answer writes them out, subdomains included and look-alikes excluded. Give aliases and domains when the name is an ordinary word."
                  },
                  "competitors": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "description": "Brands to rank alongside it, up to 10. Same shape as target."
                  },
                  "runs": {
                    "type": "number",
                    "description": "Separate answers to generate for the prompt, 1–5. Answers vary, so more runs give a steadier mentionRate and average rank. Each run is billed.",
                    "example": "1"
                  },
                  "includeAnswers": {
                    "type": "boolean",
                    "description": "Include each run’s full answer.",
                    "example": "false"
                  },
                  "provider": {
                    "type": "string",
                    "description": "The assistant to ask. chatgpt is the only one available today; the field exists so the same request serves further assistants as they are added.",
                    "example": "chatgpt"
                  },
                  "country": {
                    "type": "string",
                    "description": "Two-letter country the answer should come from, such as US, GB or DE. Answers differ by country. When that country cannot be served, the answer comes from the default one and notes says so.",
                    "example": "us"
                  },
                  "language": {
                    "type": "string",
                    "description": "Language of ChatGPT’s own interface, such as en, de or pt-BR. The answer itself follows the language of your prompt.",
                    "example": "en"
                  },
                  "webSearch": {
                    "type": "string",
                    "description": "auto lets ChatGPT decide whether to search the web; on asks it to search before answering, and answer.usedWebSearch reports what it did. There is no \"off\": an anonymous visitor has no such setting.",
                    "example": "auto"
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown.",
                    "example": "json"
                  }
                },
                "additionalProperties": false,
                "required": [
                  "prompt",
                  "target"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "prompt": "best reddit api alternatives",
                    "target": {
                      "name": "FetchLayer",
                      "domains": [
                        "fetchlayer.dev"
                      ]
                    },
                    "competitors": [
                      "Apify"
                    ],
                    "runs": 2
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "resultType": {
                      "type": "string",
                      "description": "ask, mentions, ai-rank, prompt-discovery or visibility-report."
                    },
                    "provider": {
                      "type": "string",
                      "description": "The assistant that was asked. Always \"chatgpt\" today."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The assistant page the answers correspond to."
                    },
                    "transport": {
                      "type": "string",
                      "description": "The upstream source. Always \"chatgpt\"."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats you can act on — a country that could not be served, runs that could not be completed, details the answer did not show. Empty when there are none. Read it on every call."
                    },
                    "answersGenerated": {
                      "type": "number",
                      "description": "Answers ChatGPT produced for this request."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Billable units, which is the same number: one credit per answer. An answer that could not be produced is never billed."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of when the data was collected."
                    },
                    "prompt": {
                      "type": "string",
                      "description": "The prompt that was asked, once per run."
                    },
                    "target": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The brand as it was resolved: { name, aliases, domains }."
                    },
                    "competitors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "The competitor brands, resolved the same way."
                    },
                    "runsRequested": {
                      "type": "number",
                      "description": "Runs you asked for. Fewer may have completed — notes says so."
                    },
                    "runs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "run": {
                            "type": "number",
                            "description": "1-based run number."
                          },
                          "rank": {
                            "type": "number",
                            "description": "Position among the options this answer recommends, or null when the brand is not one of them."
                          },
                          "mentioned": {
                            "type": "boolean",
                            "description": "Whether this answer names it anywhere, list or prose."
                          },
                          "citedAsSource": {
                            "type": "boolean",
                            "description": "Whether this answer cites one of its pages."
                          },
                          "citationRank": {
                            "type": "number",
                            "description": "Its best position among the cited sources, or null. Separate from rank."
                          },
                          "method": {
                            "type": "string",
                            "description": "How this answer presented its options: numbered_list, table, headings, bulleted_list or first_mention. When an answer has several such structures, the one it presents first is used."
                          },
                          "recommendations": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "The ordered list the rank was read from, each { rank, name }."
                          },
                          "competitorRanks": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "additionalProperties": true
                            },
                            "description": "Each competitor in this run: { name, rank, mentioned }."
                          },
                          "usedWebSearch": {
                            "type": "boolean",
                            "description": "Whether this run used the web."
                          },
                          "answeredAt": {
                            "type": "string",
                            "description": "When this run’s answer finished."
                          },
                          "answer": {
                            "type": "object",
                            "additionalProperties": true,
                            "description": "The full answer, when includeAnswers is true. null otherwise."
                          }
                        }
                      },
                      "description": "One entry per completed answer."
                    },
                    "aggregate": {
                      "type": "object",
                      "additionalProperties": true,
                      "description": "The figures over all completed runs. This is what tracking should read.",
                      "properties": {
                        "runs": {
                          "type": "number",
                          "description": "Completed answers the figures are over."
                        },
                        "mentionRate": {
                          "type": "number",
                          "description": "Percentage of runs that mentioned the brand at all (0–100)."
                        },
                        "averageRank": {
                          "type": "number",
                          "description": "Mean rank over the runs where it was ranked, or null when it never was. Runs where it was not ranked are left out rather than counted as last."
                        },
                        "bestRank": {
                          "type": "number",
                          "description": "Its best rank across the runs, or null."
                        },
                        "worstRank": {
                          "type": "number",
                          "description": "Its worst rank across the runs, or null."
                        },
                        "citationRate": {
                          "type": "number",
                          "description": "Percentage of runs whose answer cited one of its pages (0–100). This is a different measure from mentionRate: an answer can name a brand without citing it, and cite it without recommending it."
                        },
                        "averageCitationRank": {
                          "type": "number",
                          "description": "Mean position among the cited sources over the runs that cited it, or null."
                        }
                      }
                    },
                    "competitorAggregates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "The same figures per competitor, each with its name."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "resultType": "ai-rank",
                      "provider": "chatgpt",
                      "requestedUrl": "https://chatgpt.com/",
                      "transport": "chatgpt",
                      "notes": [],
                      "answersGenerated": 2,
                      "pagesScraped": 2,
                      "scrapedAt": "2026-09-16T02:22:36.665Z",
                      "prompt": "best reddit api alternatives",
                      "target": {
                        "name": "FetchLayer",
                        "aliases": [],
                        "domains": [
                          "fetchlayer.dev"
                        ]
                      },
                      "competitors": [
                        {
                          "name": "Apify",
                          "aliases": [],
                          "domains": []
                        }
                      ],
                      "runsRequested": 2,
                      "runs": [
                        {
                          "run": 1,
                          "rank": null,
                          "mentioned": false,
                          "citedAsSource": false,
                          "citationRank": null,
                          "method": "table",
                          "recommendations": [
                            {
                              "rank": 1,
                              "name": "Arctic Shift"
                            },
                            {
                              "rank": 2,
                              "name": "PullPush"
                            },
                            {
                              "rank": 3,
                              "name": "Managed Reddit REST APIs"
                            },
                            {
                              "rank": 4,
                              "name": "Apify Reddit scrapers"
                            },
                            {
                              "rank": 5,
                              "name": "Official Reddit API"
                            }
                          ],
                          "competitorRanks": [
                            {
                              "name": "Apify",
                              "rank": 4,
                              "mentioned": true
                            }
                          ],
                          "usedWebSearch": true,
                          "answeredAt": "2026-09-16T02:22:36.614Z",
                          "answer": null
                        },
                        {
                          "run": 2,
                          "rank": null,
                          "mentioned": false,
                          "citedAsSource": false,
                          "citationRank": null,
                          "method": "table",
                          "recommendations": [
                            {
                              "rank": 1,
                              "name": "Apify"
                            },
                            {
                              "rank": 2,
                              "name": "PRAW (Python Reddit API Wrapper)"
                            },
                            {
                              "rank": 3,
                              "name": "Pushshift Reddit Dataset"
                            }
                          ],
                          "competitorRanks": [
                            {
                              "name": "Apify",
                              "rank": 1,
                              "mentioned": true
                            }
                          ],
                          "usedWebSearch": true,
                          "answeredAt": "2026-09-16T02:22:20.565Z",
                          "answer": null
                        }
                      ],
                      "aggregate": {
                        "runs": 2,
                        "mentionRate": 0,
                        "averageRank": null,
                        "bestRank": null,
                        "worstRank": null,
                        "citationRate": 0,
                        "averageCitationRank": null
                      },
                      "competitorAggregates": [
                        {
                          "name": "Apify",
                          "runs": 2,
                          "mentionRate": 100,
                          "averageRank": 2.5,
                          "bestRank": 1,
                          "worstRank": 4,
                          "citationRate": 0,
                          "averageCitationRank": null
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/ask": {
      "post": {
        "operationId": "ask",
        "tags": [
          "Answers"
        ],
        "summary": "Ask ChatGPT and get the answer with its sources",
        "description": "The answer ChatGPT gives a prompt, with everything behind it: the answer as Markdown and as plain text, the pages it cites (each with the sentence that cites it), every inline citation, the web searches it actually ran, and every page it looked at while searching — each flagged cited, because a page can be read and never cited. This is what an anonymous visitor sees, not an API completion: there is no model, temperature or system prompt to choose. null means the answer did not show a field, not zero: searchQueries and retrievedPages are null when it did not list them, [] when it listed none, and model is null when the answer did not name one. Answers vary between runs, so one answer is an anecdote — use ai-rank to track a brand across several. Billing: 1 credit — one answer.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "The prompt, exactly as a person would type it into ChatGPT (1–4000 characters)."
                  },
                  "provider": {
                    "type": "string",
                    "description": "The assistant to ask. chatgpt is the only one available today; the field exists so the same request serves further assistants as they are added.",
                    "example": "chatgpt"
                  },
                  "country": {
                    "type": "string",
                    "description": "Two-letter country the answer should come from, such as US, GB or DE. Answers differ by country. When that country cannot be served, the answer comes from the default one and notes says so.",
                    "example": "us"
                  },
                  "language": {
                    "type": "string",
                    "description": "Language of ChatGPT’s own interface, such as en, de or pt-BR. The answer itself follows the language of your prompt.",
                    "example": "en"
                  },
                  "webSearch": {
                    "type": "string",
                    "description": "auto lets ChatGPT decide whether to search the web; on asks it to search before answering, and answer.usedWebSearch reports what it did. There is no \"off\": an anonymous visitor has no such setting.",
                    "example": "auto"
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown.",
                    "example": "json"
                  }
                },
                "additionalProperties": false,
                "required": [
                  "prompt"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "prompt": "reddit api alternatives"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "resultType": {
                      "type": "string",
                      "description": "ask, mentions, ai-rank, prompt-discovery or visibility-report."
                    },
                    "provider": {
                      "type": "string",
                      "description": "The assistant that was asked. Always \"chatgpt\" today."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The assistant page the answers correspond to."
                    },
                    "transport": {
                      "type": "string",
                      "description": "The upstream source. Always \"chatgpt\"."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats you can act on — a country that could not be served, runs that could not be completed, details the answer did not show. Empty when there are none. Read it on every call."
                    },
                    "answersGenerated": {
                      "type": "number",
                      "description": "Answers ChatGPT produced for this request."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Billable units, which is the same number: one credit per answer. An answer that could not be produced is never billed."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of when the data was collected."
                    },
                    "prompt": {
                      "type": "string",
                      "description": "The prompt that was asked."
                    },
                    "country": {
                      "type": "string",
                      "description": "The country the answer came from."
                    },
                    "language": {
                      "type": "string",
                      "description": "The interface language used."
                    },
                    "webSearch": {
                      "type": "string",
                      "description": "The web-search mode requested, auto or on."
                    },
                    "answer": {
                      "type": "object",
                      "properties": {
                        "markdown": {
                          "type": "string",
                          "description": "The answer as Markdown. Citations appear inline as ([label](url))."
                        },
                        "text": {
                          "type": "string",
                          "description": "The answer as plain text: no formatting, no citation labels. Every character offset in this response points into this string."
                        },
                        "sources": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true,
                            "properties": {
                              "position": {
                                "type": "number",
                                "description": "1-based position in the citation order."
                              },
                              "url": {
                                "type": "string",
                                "description": "The destination URL, with the assistant’s own tracking parameter removed."
                              },
                              "title": {
                                "type": "string",
                                "description": "The page title."
                              },
                              "domain": {
                                "type": "string",
                                "description": "Hostname of url."
                              },
                              "attribution": {
                                "type": "string",
                                "description": "The label shown on the citation, e.g. \"Reddit Help\"."
                              },
                              "publishedAt": {
                                "type": "string",
                                "description": "When the page was published, or null when the answer did not show it."
                              },
                              "citedText": {
                                "type": "string",
                                "description": "The sentence that first cites this page. null for a page listed only in the answer’s closing \"Sources\" list, which comes after the cited ones."
                              },
                              "citationCount": {
                                "type": "number",
                                "description": "How many citations in the answer point at this page."
                              }
                            }
                          },
                          "description": "The pages the answer cites, in the order it first cites them."
                        },
                        "inlineCitations": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Each citation in the answer: index, citedText (the sentence it is attached to) and sourcePositions (into sources)."
                        },
                        "searchQueries": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          },
                          "description": "The web searches ChatGPT ran for this answer, in order. [] when it did not search, null when the answer did not show them."
                        },
                        "retrievedPages": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "additionalProperties": true
                          },
                          "description": "Every page it looked at while searching — url, title, domain, snippet, publishedAt and cited. A page can be read and never cited, which is worth knowing on its own. null when the answer did not show them."
                        },
                        "sitesConsulted": {
                          "type": "number",
                          "description": "How many sites ChatGPT said it consulted, or null."
                        },
                        "usedWebSearch": {
                          "type": "boolean",
                          "description": "Whether this answer used the web."
                        },
                        "model": {
                          "type": "string",
                          "description": "The model the answer reported, or null when it did not say. It is never guessed."
                        },
                        "answeredAt": {
                          "type": "string",
                          "description": "ISO 8601 timestamp of when the answer finished."
                        }
                      },
                      "additionalProperties": false
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "resultType": "ask",
                      "provider": "chatgpt",
                      "requestedUrl": "https://chatgpt.com/",
                      "transport": "chatgpt",
                      "notes": [],
                      "answersGenerated": 1,
                      "pagesScraped": 1,
                      "scrapedAt": "2026-09-16T01:57:30.208Z",
                      "prompt": "reddit api alternatives",
                      "country": "us",
                      "language": "en",
                      "webSearch": "auto",
                      "answer": {
                        "markdown": "For **Reddit API alternatives in 2026**, the main options are:\n\n- **Arctic Shift** — free historical Reddit dumps; best for bulk research/archive data, not real-time. ([Reddit APIs](https://www.redditapis.com/blogs/reddit-api-ai-training-data-2026))\n…",
                        "text": "For Reddit API alternatives in 2026, the main options are:\n\nArctic Shift — free historical Reddit dumps; best for bulk research/archive data, not real-time.\n…",
                        "sources": [
                          {
                            "position": 1,
                            "url": "https://www.redditapis.com/blogs/reddit-api-ai-training-data-2026",
                            "title": "Arctic Shift for Reddit 2026: AI Training Data, JSONL, APIs",
                            "domain": "redditapis.com",
                            "attribution": "Reddit APIs",
                            "publishedAt": "2026-06-25T00:00:00.000Z",
                            "citedText": "Arctic Shift — free historical Reddit dumps; best for bulk research/archive data, not real-time.",
                            "citationCount": 2
                          }
                        ],
                        "inlineCitations": [
                          {
                            "index": 1,
                            "citedText": "Arctic Shift — free historical Reddit dumps; best for bulk research/archive data, not real-time.",
                            "sourcePositions": [
                              1
                            ]
                          }
                        ],
                        "searchQueries": [
                          "Reddit API alternatives Reddit data API Pushshift Arctic Shift PullPush 2026"
                        ],
                        "retrievedPages": [
                          {
                            "url": "https://www.redditapis.com/pushshift-alternative",
                            "title": "Pushshift Alternative: The Maintained Reddit Data API",
                            "domain": "redditapis.com",
                            "snippet": null,
                            "publishedAt": null,
                            "cited": false
                          }
                        ],
                        "sitesConsulted": 8,
                        "usedWebSearch": true,
                        "model": "gpt-5-6",
                        "answeredAt": "2026-09-16T01:57:30.206Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/prompt-discovery": {
      "post": {
        "operationId": "prompt-discovery",
        "tags": [
          "Prompt research"
        ],
        "summary": "Find the prompts and searches that lead to a topic",
        "description": "Which prompts and searches lead to a topic or a brand inside ChatGPT — the input to the rest of the tracking: find the prompts worth watching, then watch them with ai-rank. From a seed it asks a few prompts and returns promptsAsked, then two lists that are different kinds of evidence and are labelled as such. observedSearchQueries (source \"observed_search_query\") are the web searches ChatGPT actually ran while answering, each with its text, how many answers produced it (occurrences) and the fromPrompts it came from — these are the queries your pages have to rank for to be readable by it, and these prompts are always asked with web search on. suggestedPrompts (source \"generated_prompt\") are prompts ChatGPT wrote when asked which questions people type about the seed: suggestions, not observations. Both lists hold objects whose text field is the wording. citedDomains is the sites that came back across those answers. The field names are exact: the seed is seed and the count is maxPrompts — brand, domain, topic or promptCount are a 400 naming the field. maxPrompts is 1–5. Timing: every answer is a real ChatGPT session, and a request’s answers are generated alongside each other rather than one after the other — asking for more answers costs credits, not proportionally more time. Measured against the live service, the largest request this route accepts finishes inside a minute. For tracking wider than one request allows, run several smaller requests on a schedule and store the results, rather than trying to fit everything into one call. Billing: 1 credit per prompt asked, plus 1 more while includeSuggestedPrompts is on.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "seed": {
                    "type": "string",
                    "description": "A topic (\"reddit api alternatives\") or a brand (\"FetchLayer\"), 1–200 characters."
                  },
                  "seedType": {
                    "type": "string",
                    "description": "Whether the seed is a topic or a brand.",
                    "example": "topic"
                  },
                  "prompts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "description": "Your own prompts to ask instead of the ones built from the seed, 1–5."
                  },
                  "maxPrompts": {
                    "type": "number",
                    "description": "How many prompts built from the seed to ask, 1–5. Each is billed.",
                    "example": "3"
                  },
                  "includeSuggestedPrompts": {
                    "type": "boolean",
                    "description": "Also ask ChatGPT which prompts people use to research the seed. Costs one more answer.",
                    "example": "true"
                  },
                  "provider": {
                    "type": "string",
                    "description": "The assistant to ask. chatgpt is the only one available today; the field exists so the same request serves further assistants as they are added.",
                    "example": "chatgpt"
                  },
                  "country": {
                    "type": "string",
                    "description": "Two-letter country the answer should come from, such as US, GB or DE. Answers differ by country. When that country cannot be served, the answer comes from the default one and notes says so.",
                    "example": "us"
                  },
                  "language": {
                    "type": "string",
                    "description": "Language of ChatGPT’s own interface, such as en, de or pt-BR. The answer itself follows the language of your prompt.",
                    "example": "en"
                  },
                  "webSearch": {
                    "type": "string",
                    "description": "auto lets ChatGPT decide whether to search the web; on asks it to search before answering, and answer.usedWebSearch reports what it did. There is no \"off\": an anonymous visitor has no such setting.",
                    "example": "auto"
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown.",
                    "example": "json"
                  }
                },
                "additionalProperties": false,
                "required": [
                  "seed"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "seed": "reddit api alternatives",
                    "maxPrompts": 2
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "resultType": {
                      "type": "string",
                      "description": "ask, mentions, ai-rank, prompt-discovery or visibility-report."
                    },
                    "provider": {
                      "type": "string",
                      "description": "The assistant that was asked. Always \"chatgpt\" today."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The assistant page the answers correspond to."
                    },
                    "transport": {
                      "type": "string",
                      "description": "The upstream source. Always \"chatgpt\"."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats you can act on — a country that could not be served, runs that could not be completed, details the answer did not show. Empty when there are none. Read it on every call."
                    },
                    "answersGenerated": {
                      "type": "number",
                      "description": "Answers ChatGPT produced for this request."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Billable units, which is the same number: one credit per answer. An answer that could not be produced is never billed."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of when the data was collected."
                    },
                    "seed": {
                      "type": "string",
                      "description": "The seed that was given."
                    },
                    "promptsAsked": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The prompts that were actually asked, as strings."
                    },
                    "observedSearchQueries": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "The search as ChatGPT ran it. This is the display field: the entries are objects, not strings."
                          },
                          "source": {
                            "type": "string",
                            "description": "Always \"observed_search_query\" — it was observed, not suggested."
                          },
                          "fromPrompts": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "The prompts whose answers produced it."
                          },
                          "occurrences": {
                            "type": "number",
                            "description": "How many answers produced it."
                          }
                        }
                      },
                      "description": "Searches ChatGPT ran while answering. When an answer does not show its searches, notes says the list may be incomplete."
                    },
                    "suggestedPrompts": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "text": {
                            "type": "string",
                            "description": "The suggested prompt. Again the display field."
                          },
                          "source": {
                            "type": "string",
                            "description": "Always \"generated_prompt\" — a suggestion, not an observation."
                          },
                          "occurrences": {
                            "type": "number",
                            "description": "0: nothing was observed for it."
                          }
                        }
                      },
                      "description": "Prompts ChatGPT wrote when asked which questions people type about the seed."
                    },
                    "citedDomains": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "The domains cited across those answers, with how often each was cited."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "resultType": "prompt-discovery",
                      "provider": "chatgpt",
                      "transport": "chatgpt",
                      "notes": [],
                      "answersGenerated": 3,
                      "pagesScraped": 3,
                      "scrapedAt": "2026-09-16T01:46:11.000Z",
                      "seed": "reddit api alternatives",
                      "promptsAsked": [
                        "reddit api alternatives",
                        "what are the best reddit api alternatives"
                      ],
                      "observedSearchQueries": [
                        {
                          "text": "Reddit API alternatives 2026 Reddit JSON API alternatives Arctic Shift PullPush Teddit Libreddit",
                          "source": "observed_search_query",
                          "fromPrompts": [
                            "reddit api alternatives"
                          ],
                          "occurrences": 1
                        }
                      ],
                      "suggestedPrompts": [
                        {
                          "text": "What are the best alternatives to the Reddit API?",
                          "source": "generated_prompt",
                          "fromPrompts": [],
                          "occurrences": 0
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    },
    "/visibility-report": {
      "post": {
        "operationId": "visibility-report",
        "tags": [
          "Share of voice"
        ],
        "summary": "Share of voice across prompts and brands",
        "description": "Share of voice for a set of brands across a set of prompts, in one request: who ChatGPT puts forward for the questions your buyers ask, and how often it cites them. Each target comes back with shareOfVoice — its share of all mentions of the brands you gave, 0–100 — plus mentions and the same aggregate figures as a rank check, and byPrompt breaks mention rate, average rank and citation rate down per prompt per brand. failedRuns counts answers that could not be produced; they are not billed. The size is bounded by answers, not by prompts: prompts × runs must be at most 10, so 10 prompts at 1 run each is allowed and 4 prompts at 3 runs each (12) is a 400. Within that, up to 10 prompts, 5 targets and 3 runs. Targets cost nothing extra: every brand is read out of the same answers, so widening the brand list is free and lengthening the prompt list is not. Timing: every answer is a real ChatGPT session, and a request’s answers are generated alongside each other rather than one after the other — asking for more answers costs credits, not proportionally more time. Measured against the live service, the largest request this route accepts finishes inside a minute. For tracking wider than one request allows, run several smaller requests on a schedule and store the results, rather than trying to fit everything into one call. Billing: 1 credit per answer, so prompts × runs.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "description": "The prompts to ask, 1–10 strings. prompts × runs must be at most 10."
                  },
                  "targets": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    },
                    "description": "The brands to compare, 1–5. A brand to look for: a name such as \"FetchLayer\", or an object { name, aliases[], domains[] }. Names and aliases match on whole words, case-insensitively — \"Twenty\" matches \"twenty's\" and \"(TWENTY)\", not \"Twentyfold\". Domains match when the answer writes them out, subdomains included and look-alikes excluded. Give aliases and domains when the name is an ordinary word."
                  },
                  "runs": {
                    "type": "number",
                    "description": "Answers per prompt, 1–3. More runs steady the figures, at one credit each.",
                    "example": "1"
                  },
                  "provider": {
                    "type": "string",
                    "description": "The assistant to ask. chatgpt is the only one available today; the field exists so the same request serves further assistants as they are added.",
                    "example": "chatgpt"
                  },
                  "country": {
                    "type": "string",
                    "description": "Two-letter country the answer should come from, such as US, GB or DE. Answers differ by country. When that country cannot be served, the answer comes from the default one and notes says so.",
                    "example": "us"
                  },
                  "language": {
                    "type": "string",
                    "description": "Language of ChatGPT’s own interface, such as en, de or pt-BR. The answer itself follows the language of your prompt.",
                    "example": "en"
                  },
                  "webSearch": {
                    "type": "string",
                    "description": "auto lets ChatGPT decide whether to search the web; on asks it to search before answering, and answer.usedWebSearch reports what it did. There is no \"off\": an anonymous visitor has no such setting.",
                    "example": "auto"
                  },
                  "format": {
                    "type": "string",
                    "description": "json or markdown.",
                    "example": "json"
                  }
                },
                "additionalProperties": false,
                "required": [
                  "prompts",
                  "targets"
                ]
              },
              "examples": {
                "default": {
                  "value": {
                    "prompts": [
                      "reddit api alternatives"
                    ],
                    "targets": [
                      "FetchLayer",
                      "Apify"
                    ],
                    "runs": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "resultType": {
                      "type": "string",
                      "description": "ask, mentions, ai-rank, prompt-discovery or visibility-report."
                    },
                    "provider": {
                      "type": "string",
                      "description": "The assistant that was asked. Always \"chatgpt\" today."
                    },
                    "requestedUrl": {
                      "type": "string",
                      "description": "The assistant page the answers correspond to."
                    },
                    "transport": {
                      "type": "string",
                      "description": "The upstream source. Always \"chatgpt\"."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "Caveats you can act on — a country that could not be served, runs that could not be completed, details the answer did not show. Empty when there are none. Read it on every call."
                    },
                    "answersGenerated": {
                      "type": "number",
                      "description": "Answers ChatGPT produced for this request."
                    },
                    "pagesScraped": {
                      "type": "number",
                      "description": "Billable units, which is the same number: one credit per answer. An answer that could not be produced is never billed."
                    },
                    "scrapedAt": {
                      "type": "string",
                      "description": "ISO 8601 timestamp of when the data was collected."
                    },
                    "prompts": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "The prompts that were asked."
                    },
                    "targets": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true,
                        "properties": {
                          "name": {
                            "type": "string",
                            "description": "The brand name."
                          },
                          "shareOfVoice": {
                            "type": "number",
                            "description": "Its share of all mentions of the brands you gave, in percent. It is relative to your list, not to every brand that exists."
                          },
                          "mentions": {
                            "type": "number",
                            "description": "Total mentions across the answers."
                          },
                          "runs": {
                            "type": "number",
                            "description": "Completed answers the figures are over."
                          },
                          "mentionRate": {
                            "type": "number",
                            "description": "Percentage of runs that mentioned the brand at all (0–100)."
                          },
                          "averageRank": {
                            "type": "number",
                            "description": "Mean rank over the runs where it was ranked, or null when it never was. Runs where it was not ranked are left out rather than counted as last."
                          },
                          "bestRank": {
                            "type": "number",
                            "description": "Its best rank across the runs, or null."
                          },
                          "worstRank": {
                            "type": "number",
                            "description": "Its worst rank across the runs, or null."
                          },
                          "citationRate": {
                            "type": "number",
                            "description": "Percentage of runs whose answer cited one of its pages (0–100). This is a different measure from mentionRate: an answer can name a brand without citing it, and cite it without recommending it."
                          },
                          "averageCitationRank": {
                            "type": "number",
                            "description": "Mean position among the cited sources over the runs that cited it, or null."
                          }
                        }
                      },
                      "description": "One entry per brand, with its figures across every prompt."
                    },
                    "byPrompt": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": true
                      },
                      "description": "Per prompt: the prompt, and per brand its mentionRate, averageRank and citationRate."
                    },
                    "failedRuns": {
                      "type": "number",
                      "description": "Answers that could not be produced. They are not billed, and notes says what happened."
                    }
                  },
                  "additionalProperties": false
                },
                "examples": {
                  "default": {
                    "value": {
                      "resultType": "visibility-report",
                      "provider": "chatgpt",
                      "transport": "chatgpt",
                      "notes": [],
                      "answersGenerated": 1,
                      "pagesScraped": 1,
                      "scrapedAt": "2026-09-16T01:46:30.000Z",
                      "prompts": [
                        "reddit api alternatives"
                      ],
                      "targets": [
                        {
                          "name": "FetchLayer",
                          "shareOfVoice": 0,
                          "mentions": 0,
                          "runs": 1,
                          "mentionRate": 0,
                          "averageRank": null,
                          "bestRank": null,
                          "worstRank": null,
                          "citationRate": 0,
                          "averageCitationRank": null
                        },
                        {
                          "name": "Apify",
                          "shareOfVoice": 100,
                          "mentions": 1,
                          "runs": 1,
                          "mentionRate": 100,
                          "averageRank": null,
                          "bestRank": null,
                          "worstRank": null,
                          "citationRate": 0,
                          "averageCitationRank": null
                        }
                      ],
                      "byPrompt": [
                        {
                          "prompt": "reddit api alternatives",
                          "targets": [
                            {
                              "name": "FetchLayer",
                              "mentionRate": 0,
                              "averageRank": null,
                              "citationRate": 0
                            },
                            {
                              "name": "Apify",
                              "mentionRate": 100,
                              "averageRank": null,
                              "citationRate": 0
                            }
                          ]
                        }
                      ],
                      "failedRuns": 0
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Invalid or missing Bearer token"
          }
        },
        "security": [
          {
            "BearerAuth": []
          }
        ]
      }
    }
  }
}