API Reference Generator (OpenAPI)
Point the importer at an OpenAPI 3.x or Swagger 2.0 spec and it writes a complete API reference into your docs tree — one page per tag, every operation with its parameters, request and response shapes, and code samples in four languages. The docs theme then renders that reference as a three-column layout with an interactive request panel and an AI answer box.
Every write route below is a dashboard route and takes a bearer PAT:
https://spideriq.ai/api/v1/dashboard/content/docs/import-openapi
Authorization: Bearer $SPIDERIQ_PATDashboard routes are also available project-scoped as /api/v1/dashboard/projects/{project_id}/content/.... Use that form when one workspace runs more than one site. The reader-facing routes (/content/docs/...) need no auth and resolve the site from the request host.
Warning: The generator, the Try-it panel and Ask-AI are Docs Pro surfaces. Without a paid Docs plan every one of them returns
402 docs_pro_required, including thedry_runpreview. See Errors across the whole surface.
The adoption order is load-bearing
Run these two in this order, always:
1. content_import_openapi # re-import — this is what populates the structured data
2. template_apply_theme docs # then switch the design onThe three-column reference renders from a structured endpoints array that only an OpenAPI import writes. A doc page authored before the structured-reference release carries endpoints: null, so applying the theme to it renders the prose body instead — the graceful fallback. The page is correct and it looks broken.
If you apply the theme first and get a wall of prose where you expected endpoint cards, you have not hit a bug. Re-import the spec and the same page becomes the structured reference.
Tip: Re-importing is idempotent and safe to repeat. The importer owns the section subtree: it updates the tag pages that still exist in the spec, adds new ones, and archives the ones the spec dropped.
What the importer generates
For a spec with tags Payments and Refunds, under the default section slug api-reference:
a section page at
/docs/api-referencecarrying the API title, version and endpoint countone tag page per tag —
/docs/api-reference/payments,/docs/api-reference/refundsfor each operation: method, path, summary, description, parameters, a request example and the documented responses
code samples in curl, Python, JavaScript and Go, emitted as a
:::codegroupblock that renders as a tabbed panelthe spec's declared server URL, persisted on every generated page — this is what enables the Try-it panel
Pages are created as drafts unless you pass publish: true.
POST /dashboard/content/docs/import-openapi
Generate or refresh an API reference from a spec.
Parameters
Name | Type | Required | Description |
|---|---|---|---|
| string | one of | URL of the spec. Fetched server-side with SSRF protection. Max 2048 chars. |
| string | one of | The raw spec text, JSON or YAML. Max 5 MB. |
| string | no |
|
| string | no | Slug of the docs section to generate under. Default |
| boolean | no | Publish immediately. Default |
| boolean | no | Return the plan without writing anything. Default |
Supply exactly one of source_url or spec_content. Supplying both, or neither, is a validation error.
Example
curl -X POST "https://spideriq.ai/api/v1/dashboard/content/docs/import-openapi" \
-H "Authorization: Bearer $SPIDERIQ_PAT" \
-H "Content-Type: application/json" \
-d '{
"source_url": "https://api.example.com/openapi.json",
"section": "api-reference",
"publish": true
}'import { SpiderIQClient } from "@spideriq/core";
const client = new SpiderIQClient({ token: process.env.SPIDERIQ_PAT });
const res = await client.contentImportOpenApi({
source_url: "https://api.example.com/openapi.json",
section: "api-reference",
publish: true,
});
console.log(res.total_endpoints); // → 47
console.log(res.created); // → ["payments", "refunds"]Agents call the same surface as content_import_openapi.
Response — 200 OK. A write returns:
{
"dry_run": false,
"api_title": "Example API",
"api_version": "2.1.0",
"base_url": "https://api.example.com",
"section": "api-reference",
"section_id": "0f2c…",
"total_endpoints": 47,
"created": ["payments"],
"updated": ["refunds"],
"archived": ["legacy-tokens"],
"published": true
}created, updated and archived are tag-page slugs, so a re-import tells you exactly what the spec changed. A dry_run returns the same envelope shape minus the write fields: dry_run: true, plus pages[] with each planned slug, title and endpoint_count.
Errors
Status | When | Resolution |
|---|---|---|
| the workspace is not on a paid Docs plan | upgrade the Docs plan; the |
| both or neither of | send exactly one |
| the spec cannot be fetched, parsed, or exceeds the size cap | check the URL is publicly reachable and the body is valid OpenAPI 3.x or Swagger 2.0; the message names the reason |
| an unexpected failure while writing the tree | retry; if it persists, the spec URL is not echoed back for safety — capture the spec and contact support |
Note: The spec is untrusted input. It is size-capped, parsed defensively, and fetched through an SSRF-safe client, so a
source_urlpointing at a private address is refused rather than followed.
POST /dashboard/templates/apply-theme
Install the docs theme for the workspace. This is the second half of the adoption order.
Parameters
Name | Type | Required | Description |
|---|---|---|---|
| string | yes | Theme name. Use |
| query, boolean | no | Preview the change and receive a |
| query, string | no | Consume a prior preview token and apply the theme. |
Applying a theme is a gated operation — it overwrites your template files, so it runs through the dry-run and confirm flow.
Example
# Step 1 — preview
curl -X POST "https://spideriq.ai/api/v1/dashboard/templates/apply-theme?dry_run=true" \
-H "Authorization: Bearer $SPIDERIQ_PAT" \
-H "Content-Type: application/json" \
-d '{"theme": "docs"}'
# → { "dry_run": true, "confirm_token": "cft_…", "preview": { … } }
# Step 2 — confirm
curl -X POST "https://spideriq.ai/api/v1/dashboard/templates/apply-theme?confirm_token=cft_…" \
-H "Authorization: Bearer $SPIDERIQ_PAT" \
-H "Content-Type: application/json" \
-d '{"theme": "docs"}'Agents call this as template_apply_theme; template_list_themes lists what is installable.
Response — 200 OK, { "theme": "docs", "templates_written": <count> }.
Errors
Status | When | Resolution |
|---|---|---|
| unknown theme name | list the installable themes first |
| the confirm token belongs to another workspace or action | re-run the |
| the token was already consumed | re-run the |
| the token expired | re-run the |
A theme applies to the workspace, not to a single site inside it. If one workspace runs both a marketing site and a docs site, they share the applied theme — keep the docs site in its own workspace when the two designs need to differ.
Applying a theme changes stored templates. Your site changes when you deploy.
Reading the structured reference
GET /content/docs/{path} returns the doc, and for a generated reference page it carries the structured operations alongside the prose body.
curl "https://spideriq.ai/api/v1/content/docs/api-reference/payments" \
-H "X-Content-Domain: docs.example.com"Response — the usual doc fields plus endpoints, an array of operations. Each entry carries method, path, full_path, summary, description, params[], request_example, responses[] and samples (keyed curl, python, javascript, go).
endpoints is null on any page that was not produced by an OpenAPI import. That is the flag to check when a page renders as prose.
The prose body is always populated too, so a theme that does not read endpoints still renders a readable page.
POST /content/docs/playground/request
Back the Try it panel: relay one reader-composed request to the documented API and return the response. Public — no bearer token; the site is resolved from the request host.
Parameters
Name | Type | Required | Description |
|---|---|---|---|
| string | yes | Full path of the reference page the panel is on, e.g. |
| string | yes |
|
| string | yes | Endpoint path relative to the API base, e.g. |
| object | no | Query parameters. Max 50. |
| object | no | Request headers. Max 25, each value up to 4096 chars. |
| string | no | Request body. Max 64 KB. |
The target host is fixed server-side to the base URL the import persisted on the page. A caller cannot point the relay somewhere else — path is relative by contract, and the host never comes from the request.
Example
curl -X POST "https://spideriq.ai/api/v1/content/docs/playground/request" \
-H "Content-Type: application/json" \
-H "X-Content-Domain: docs.example.com" \
-d '{
"doc_path": "api-reference/payments",
"method": "GET",
"path": "/v1/payments",
"query": {"limit": "3"}
}'Response — 200 OK, { status, headers, body, elapsed_ms }. status is the documented API's status code, not this call's. headers is filtered to a safe display set (content type and length, cache control, ETag, rate-limit headers, Retry-After, request id); cookies and auth challenges are dropped. body is text, capped at 2 MB.
Errors
Status | When | Resolution |
|---|---|---|
| the site owner is not on a paid Docs plan | upgrade the Docs plan |
| the page has no persisted API base URL | re-import the spec — pages imported before the panel shipped carry none |
| the relay was refused: host not allowed, unsupported method, body too large, or a timeout | the message names which; requests time out at 15 seconds |
| more than 30 requests a minute from one reader | wait and retry |
POST /content/docs/ask
Back the Ask AI box: answer a question using only the site's published docs, and return the sources it used. Public.
Parameters
Name | Type | Required | Description |
|---|---|---|---|
| string | yes | The question. 3–500 characters. |
| integer | no | How many passages to ground the answer in. 1–12, default 6. |
Example
curl -X POST "https://spideriq.ai/api/v1/content/docs/ask" \
-H "Content-Type: application/json" \
-H "X-Content-Domain: docs.example.com" \
-d '{"query": "How do I paginate the payments list?"}'Response — 200 OK:
{
"query": "How do I paginate the payments list?",
"answer": "Pass `page` and `page_size` … [1]",
"sources": [
{"n": 1, "title": "Payments", "full_path": "api-reference/payments",
"url": "/docs/api-reference/payments", "score": 0.8213}
],
"grounded": true
}The [n] markers in answer line up with sources[].n, so every claim is traceable to a page. When nothing relevant is found the call still returns 200 with grounded: false, an empty sources array and a plain "I couldn't find anything about that" answer — it does not invent one, and it is not an error.
Errors
Status | When | Resolution |
|---|---|---|
| the site owner is not on a paid Docs plan | upgrade the Docs plan |
| the monthly AI token allowance is spent | the allowance resets at the billing period boundary; there is no |
|
| shorten or lengthen the question |
| answering is temporarily unavailable | transient; retry |
GET /content/docs/semantic
The retrieval half on its own, for callers that want passages rather than a written answer. Takes q (3–500 chars) and top_k (1–12, default 6), returns { query, results[], total } where each result carries title, full_path, url, a 300-character snippet and a score. Rate-limited per reader.
Errors across the whole surface
Status | Meaning |
|---|---|
| a Docs Pro surface, and this workspace is not entitled — or the AI token allowance is spent |
| the request body failed validation; the message names the field |
| rate-limited; the reader-facing relay and Ask-AI are both capped per reader |
| a dependency is temporarily unavailable; retry |
Errors carry the standard envelope described in Overview.
Known constraints
Real limits worth knowing before you commit a design:
The
docstheme ships a dark palette. Its text colours are fixed, so a site whose surface colour is white will render light text on a light background. Use it on a dark site, or override the docs templates.A theme is per workspace, not per site. Two sites in one workspace share the applied theme.
The theme brings no header or footer of its own. It inherits your site chrome; a site with an empty header section gets none on
/docs.Many-language samples come from the spec. Operations the spec documents thinly generate thin pages — the importer does not invent examples.
Next steps
Organise the generated tree and write around it in Documentation.
Push the reference live with Deploy.
Drive the whole flow from an agent with the MCP content tools.