CrawlGraph · OpenAPI Overlay 1.0.0
API Evangelist enhancements for the CrawlGraph REST API v1
16 actions
16 updates
servers
extends
https://crawlgraph.com/api/v1/openapi.json
Generated by API Evangelist
Written by API Evangelist tooling for CrawlGraph's API. It is a proposal applied on top of the contract, not a document CrawlGraph publishes.
What the actions change
responsesx-quota-costsecuritytagsserverscontacttermsOfServicesecuritySchemes
Targets 9
$
$.info
$.components
$.paths['/api/v1/free-key'].post
$.paths['/api/v1/backlinks'].post
$.paths['/api/v1/gap-analysis'].post
$.paths['/api/v1/gap-analysis/{job_id}'].get
$.paths['/api/v1/changes'].get
$.paths['/api/v1/releases'].get
OpenAPI Overlay
# authorship: generated by API Evangelist tooling. Stamped 2026-08-18
# on the file's own generator header (roadmap#64). An unmarked file is
# NOT assumed to be ours -- absence of evidence was never stamped.
x-method: generated
overlay: 1.0.0
info:
title: API Evangelist enhancements for the CrawlGraph REST API v1
version: 1.0.0
extends: https://crawlgraph.com/api/v1/openapi.json
x-generated: '2026-09-02'
x-method: generated
x-source: >-
Generated by the API Evangelist enrichment pipeline against the live upstream spec at
https://crawlgraph.com/api/v1/openapi.json (OpenAPI 3.1.0, info.version 1.2.2 as re-harvested 2026-09-02; 1.2.0 at first harvest — only info.version changed, 6 operations both times),
using facts published by CrawlGraph itself at https://crawlgraph.com/docs/api. Every action
below adds something the FastAPI-generated spec omits but the provider's own documentation
states. Nothing here is invented, and the original spec is never mutated — the verbatim copy
lives at openapi/_original/crawlgraph-openapi.json.
x-summary: >-
The upstream spec is auto-generated by FastAPI and is therefore accurate about shapes but
silent about operation. It declares no servers, no securitySchemes, and none of the seven
documented error codes. An agent handed this spec alone cannot authenticate, cannot resolve a
base URL, and cannot recognise a single real failure mode.
actions:
- target: $
description: >-
Add the servers block. The upstream spec has no servers[] at all, so every path is
relative and unresolvable. The host is stated throughout the docs and in every curl
example: https://crawlgraph.com (paths carry their own /api/v1 prefix).
update:
servers:
- url: https://crawlgraph.com
description: CrawlGraph production API
- target: $.info
description: >-
Add contact and terms. Taken from the published security.txt contact address and the
terms page.
update:
contact:
name: CrawlGraph support
email: petteri@searchenginewizards.fi
url: https://crawlgraph.com/docs/api
termsOfService: https://crawlgraph.com/terms
- target: $.components
description: >-
Add the bearer security scheme. Documented in section 2 of the API reference and confirmed
by probe (anonymous GET /api/v1/releases returns 401), but entirely absent upstream.
update:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
description: >-
Bearer token. Keys are prefixed cg_live_ and are roughly 52 characters long. Sent as
`Authorization: Bearer cg_live_<key>`. Up to 10 active keys per user; the full key is
shown once at creation with no recovery path.
- target: $
description: Apply the bearer scheme as the default security requirement for the whole API.
update:
security:
- bearerAuth: []
- target: $.paths['/api/v1/free-key'].post
description: >-
Exempt the free-key route from the default security requirement. It is the one
unauthenticated operation — its whole purpose is issuing a first credential.
update:
security: []
- target: $.paths['/api/v1/free-key'].post
description: De-duplicate the tags array, which upstream lists "v1" twice.
update:
tags: [v1]
- target: $
description: >-
Declare the single tag with a description. Upstream tags every operation "v1" but never
declares the tag.
update:
tags:
- name: v1
description: >-
CrawlGraph public REST API v1 — backlink lookups, Common Crawl release discovery,
async gap analysis, and cross-release change comparison.
- target: $.paths['/api/v1/backlinks'].post
description: >-
Add the documented error responses. Upstream declares only 200 and a generic 422; the docs
publish a seven-code catalog with a stable envelope. See errors/crawlgraph-problem-types.yml.
update:
responses:
'400':
description: 'validation_error — malformed domain, unknown release_id, or out-of-range limit. Does not consume quota.'
'401':
description: 'auth_missing or auth_invalid — Authorization header absent/malformed, or key unknown/revoked.'
'409':
description: 'release_unavailable — the release id is known but its query artifact is not loaded. Checked before quota is charged.'
'429':
description: 'quota_exceeded — monthly backlinks quota exhausted. Read Retry-After.'
'500':
description: 'internal_error — quote the request_id to support.'
- target: $.paths['/api/v1/gap-analysis'].post
description: Add the documented error responses for the gap submission route.
update:
responses:
'400':
description: 'validation_error — malformed domains, or more than 5 competitors.'
'401':
description: 'auth_missing or auth_invalid.'
'429':
description: 'quota_exceeded — monthly gap-job quota exhausted (50/mo on the lifetime tier). Free keys cannot call this route at all.'
'500':
description: internal_error.
- target: $.paths['/api/v1/gap-analysis/{job_id}'].get
description: >-
Add the 404 the docs describe. It is deliberately ambiguous: a job that does not exist and
a job owned by another user both return 404, so ids cannot be enumerated.
update:
responses:
'401':
description: 'auth_missing or auth_invalid.'
'404':
description: "not_found — the job does not exist, or is not yours. The two cases are intentionally indistinguishable so job ids cannot be enumerated."
- target: $.paths['/api/v1/changes'].get
description: Add the documented error responses for the change-comparison route.
update:
responses:
'400':
description: 'validation_error — unknown release ids, equal from/to ids, or a malformed domain. Does not consume quota.'
'401':
description: 'auth_missing or auth_invalid.'
'429':
description: 'quota_exceeded — counts against the same monthly backlinks bucket as POST /api/v1/backlinks.'
'500':
description: internal_error.
- target: $.paths['/api/v1/releases'].get
description: Add the 401 and record that this operation is quota-free.
update:
responses:
'401':
description: 'auth_missing or auth_invalid.'
x-quota-cost: none
- target: $.paths['/api/v1/backlinks'].post
description: >-
Record the quota cost and the rate-limit response headers, which the docs publish but the
spec does not declare. See rate-limits/crawlgraph-rate-limits.yml.
update:
x-quota-cost: 1 backlinks call
x-rate-limit-headers:
- X-RateLimit-Limit-Backlinks
- X-RateLimit-Remaining-Backlinks
- X-RateLimit-Reset
- X-Request-ID
- Retry-After
- target: $.paths['/api/v1/gap-analysis'].post
description: Record the quota cost and the async contract.
update:
x-quota-cost: 1 gap job
x-async: submit-and-poll
x-poll-operation: v1_gap_poll_api_v1_gap_analysis__job_id__get
x-job-retention: 7 days
x-tier-required: lifetime
- target: $.paths['/api/v1/changes'].get
description: >-
Record that this route bills against the backlinks bucket, and carry the provider's own
snapshot caveat onto the operation.
update:
x-quota-cost: 1 backlinks call
x-snapshot-caveat: >-
Common Crawl snapshots are periodic observations, not live link monitoring. Absence from
a newer snapshot does not prove a page removed a link.
- target: $
description: >-
Link the agent surfaces. The hosted MCP server is a thin client over these same operations;
the crosswalk binds each tool to its backing operationId.
update:
x-mcp-server: https://crawlgraph.com/mcp
x-tool-crosswalk: mcp/crawlgraph-tool-crosswalk.yml
x-llms-txt: https://crawlgraph.com/llms.txt