> ## Documentation Index
> Fetch the complete documentation index at: https://docs.querying.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# GEO Score

> Score how much of one page ChatGPT search keeps and ChatGPT reads when it opens it, and what keeps the rest from it.



## OpenAPI

````yaml POST /v1/geo-score
openapi: 3.1.0
info:
  title: querying.ai
  description: >-
    One API for every AI answer engine. Every task is asynchronous: submit, then
    collect the result via webhook or polling.
  version: 1.0.0
servers:
  - url: https://api.querying.ai
    description: Production
security:
  - bearerAuth: []
paths:
  /v1/geo-score:
    post:
      tags:
        - Research
      summary: Score how much of a page ChatGPT search keeps
      description: >-
        Queues a task that scores one page on how much of what a person reads on
        it ChatGPT search keeps, beside how much ChatGPT receives when it opens
        the page itself, and names what keeps the rest out: robots.txt, refused
        requests, content loaded after the page opens, text inside images. The
        reference is the page rendered in a browser in country, with the text in
        its images. 10 credits a page, 5 for each image whose text is read
        (images.read) and 2 for each image the account read in the last 90 days
        (images.reused), at most 12 images: submitting holds 70 credits and
        completion charges what the task used; a failed task releases its hold.
        Most tasks complete in 2-5 minutes; poll /v1/async/task/{id} or use a
        webhook. A page no browser can show, as a person or as ChatGPT search's
        crawler, fails with PAGE_UNAVAILABLE, and a task whose questions ChatGPT
        answered none of fails with CHATGPT_UNAVAILABLE.
      operationId: createGeoScore
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GeoScoreRequest'
            examples:
              product:
                summary: A product page read from the US
                value:
                  url: https://www.allbirds.com/products/mens-tree-runners
                  country: US
              korea:
                summary: A Korean page read from KR, with a webhook
                value:
                  url: https://www.musinsa.com/products/6247370
                  country: KR
                  idempotencyKey: musinsa-6247370
                  webhook:
                    url: https://example.com/hooks/geo-score
      responses:
        '200':
          description: >-
            Queued; poll /v1/async/task/{id}. Its response follows
            GeoScoreResult.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AsyncResponse'
              examples:
                queued:
                  summary: Queued GEO Score
                  value:
                    success: true
                    task:
                      id: 0b6c1f7e-2d4a-4c55-9a0e-3f1d2b7c8e91
                      taskType: GEO_SCORE
                      status: QUEUED
                      priority: 1
                      createdAt: '2026-10-21T09:00:00.000Z'
                    credits:
                      creditsToCharge: 0
                      creditsCharged: 0
        '400':
          description: >-
            VALIDATION_ERROR: the body is not a JSON object, has a field other
            than url, country, idempotencyKey, priority and webhook, or one of
            the last three has the wrong type.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '402':
          description: Not enough credits.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: The API key is not allowed to use GEO_SCORE.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: A task with this idempotencyKey already exists.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '413':
          description: Request rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: >-
            VALIDATION_ERROR for a url that is missing, not http or https, or on
            a private host or port, or REGION_UNSUPPORTED when country is not US
            or KR.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Request rejected; retry after Retry-After.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Request rejected; retry after Retry-After.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    GeoScoreRequest:
      type: object
      required:
        - url
      additionalProperties: false
      properties:
        url:
          type: string
          format: uri
          maxLength: 2048
          description: >-
            The page to score: an http or https URL on a public host, on the
            default port.
        country:
          type: string
          enum:
            - US
            - KR
          default: US
          description: >-
            Where the person reading the page is. The page is rendered from an
            address in that country, in its language and time zone. Any other
            value is a 422 REGION_UNSUPPORTED.
        idempotencyKey:
          type: string
          description: Optional. Deduplicates submissions; a duplicate is a 409.
        priority:
          type: integer
          minimum: 1
          maximum: 10
          default: 1
          description: >-
            Optional. Echoed in task metadata; values outside 1-10 are clamped.
            It does not guarantee execution order.
        webhook:
          type: object
          description: Optional. Omit to collect the result by polling instead.
          required:
            - url
          properties:
            url:
              type: string
              format: uri
              description: Receives a POST when the task reaches a terminal state.
    AsyncResponse:
      type: object
      required:
        - success
        - task
        - credits
      properties:
        success:
          type: boolean
          const: true
        task:
          $ref: '#/components/schemas/TaskMeta'
        credits:
          $ref: '#/components/schemas/Credits'
    ErrorResponse:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          const: false
        error:
          $ref: '#/components/schemas/ErrorDetail'
    TaskMeta:
      type: object
      required:
        - id
        - taskType
        - status
        - priority
        - createdAt
      properties:
        id:
          type: string
          format: uuid
        taskType:
          $ref: '#/components/schemas/TaskType'
        status:
          $ref: '#/components/schemas/TaskStatus'
        priority:
          type: integer
        createdAt:
          type: string
          format: date-time
        idempotencyKey:
          type: string
          description: >-
            Echoed back verbatim. **Omitted** — not null — when the caller
            supplied none.
    Credits:
      type: object
      description: >-
        Credits, with up to two decimals (for example `1.25`). The submit
        response always shows `0`: a hold is placed on your balance, but nothing
        is charged yet. Polling shows `0` until the task is terminal, then the
        settled charge: the task's price for COMPLETED, `0` for FAILED. A task
        webhook reports the same charge in `creditsCharged`; on a FAILED task it
        reports the task's price in `creditsToCharge` and `0` in
        `creditsCharged`. CITATION_ANALYSIS and WEB_CRAWL are charged by usage,
        up to the hold placed at submit.
      properties:
        creditsToCharge:
          type: number
        creditsCharged:
          type:
            - number
            - 'null'
    ErrorDetail:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Stable, safe to branch on. See the Errors guide for the full list.
        message:
          type: string
          description: For humans. May change.
        details:
          description: >-
            Context for the error. An array of `{field, message}` on most
            `VALIDATION_ERROR`s; an object elsewhere (for example `{id}` on
            `RESOURCE_NOT_FOUND`, `retryAfterSec` on 429 and 503 codes). Omitted
            when there is nothing to add.
          oneOf:
            - type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                  message:
                    type: string
            - type: object
              additionalProperties: true
        timestamp:
          type: string
          format: date-time
    TaskType:
      type: string
      description: >-
        The engine to query. `NAVER` is a deprecated alias for `NAVER_AI_BRIEF`.
        GOOGLE_AIO and GOOGLE_AIMODE are the unified names for GOOGLE and
        AIMODE; both spellings are accepted and responses echo the canonical
        GOOGLE / AIMODE. `NAVER_AI_MODE` is accepted as an earlier spelling of
        `NAVER_AI_TAB`. `GOOGLE_SERP` returns the Google results page without
        the AI Overview; `payload.page` selects pages 1-10. `NAVER_SERP` returns
        Naver's web results, 15 per page (`payload.page` 1-10), and with
        `payload.action` `page` reads one naver.com page by `payload.url`.
        `REDDIT` searches Reddit posts by `query` (optionally within one
        `subreddit`), reads one post with its first page of comments by `url`,
        or lists posts with `action` `feed` or `user_posts`. `WEB_SCRAPE` reads
        one web page by `payload.url` and returns its main content as Markdown
        with its images. `WEB_MAP` lists a site's addresses from its start page
        links and sitemaps. `WEB_CRAWL` reads a site's pages under a start
        address, each as WEB_SCRAPE reads it, at 1 credit per page returned.
        `KEYWORD_VOLUME` returns the monthly search volume of `payload.keywords`
        (1-100) in `payload.country`: Naver for KR and Google for 216 other
        countries. `META_AI` returns the meta.ai chat answer with its cited
        sources, search queries and the products it shows (`shoppingCards`,
        `inlineProducts`); a prompt Meta refuses completes with an empty text
        and a `notice` quoting Meta. `QWEN` returns the answer of Qwen's China
        web chat (qianwen.com) with its web search, sources and search queries;
        `payload.country` sets the exit and the answer locale. `DOUBAO` returns
        the answer of Doubao's China web chat (doubao.com) with its web search,
        sources and search queries; it always asks from mainland China, whatever
        `payload.country` is. `BING` and `BING_COPILOT_SEARCH` are accepted as
        earlier spellings of `BING_SEARCH`, and `COPILOT` as the earlier
        spelling of `BING_COPILOT`; responses echo the new names. Private
        engines (for example CLAUDE) are rejected with 403 ENGINE_PRIVATE.
        CITATION_ANALYSIS, PROMPT_RESEARCH and GEO_SCORE tasks are created
        through their own endpoints (POST /v1/citation-analysis, POST
        /v1/prompt-research, POST /v1/geo-score) and are rejected here with 400
        USE_DEDICATED_ENDPOINT; they appear in this list because their tasks
        report them. GEO_AUDIT, SOURCE_INFLUENCE and CITATION_ATTRIBUTION are
        accepted as earlier names of CITATION_ANALYSIS; responses echo
        CITATION_ANALYSIS.
      enum:
        - CHATGPT
        - PERPLEXITY
        - GEMINI
        - AIMODE
        - GOOGLE_AIMODE
        - GOOGLE
        - GOOGLE_AIO
        - GOOGLE_SERP
        - NAVER_AI_BRIEF
        - NAVER_AI_TAB
        - NAVER_AI_MODE
        - NAVER
        - NAVER_SERP
        - COMMERCE_SERP
        - COMMERCE_PRODUCT
        - BING_SEARCH
        - BING
        - BING_COPILOT_SEARCH
        - BING_COPILOT
        - COPILOT
        - META_AI
        - QWEN
        - DOUBAO
        - REDDIT
        - WEB_SCRAPE
        - WEB_MAP
        - WEB_CRAWL
        - KEYWORD_VOLUME
        - CITATION_ANALYSIS
        - GEO_AUDIT
        - SOURCE_INFLUENCE
        - CITATION_ATTRIBUTION
        - PROMPT_RESEARCH
        - GEO_SCORE
    TaskStatus:
      type: string
      description: >-
        `PROCESSING` means a worker holds the task. `COMPLETED` and `FAILED` are
        terminal.
      enum:
        - QUEUED
        - PROCESSING
        - COMPLETED
        - FAILED
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Your API key, sent as `Authorization: Bearer <key>`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.