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_PAT

Dashboard 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 the dry_run preview. 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 on

The 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-reference carrying the API title, version and endpoint count

  • one tag page per tag — /docs/api-reference/payments, /docs/api-reference/refunds

  • for 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 :::codegroup block that renders as a tabbed panel

  • the 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

source_url

string

one of

URL of the spec. Fetched server-side with SSRF protection. Max 2048 chars.

spec_content

string

one of

The raw spec text, JSON or YAML. Max 5 MB.

spec_format

string

no

auto, json or yaml. Default auto.

section

string

no

Slug of the docs section to generate under. Default api-reference.

publish

boolean

no

Publish immediately. Default false — drafts, for review.

dry_run

boolean

no

Return the plan without writing anything. Default false.

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.

Response200 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

402 docs_pro_required

the workspace is not on a paid Docs plan

upgrade the Docs plan; the dry_run preview is gated too

422

both or neither of source_url / spec_content supplied

send exactly one

422

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

500

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_url pointing 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

theme

string

yes

Theme name. Use docs for the API-reference layout.

dry_run

query, boolean

no

Preview the change and receive a confirm_token. Nothing is written.

confirm_token

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.

Response200 OK, { "theme": "docs", "templates_written": <count> }.

Errors

Status

When

Resolution

400

unknown theme name

list the installable themes first

403

the confirm token belongs to another workspace or action

re-run the dry_run and use the token it returns

409

the token was already consumed

re-run the dry_run

410

the token expired

re-run the dry_run

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

doc_path

string

yes

Full path of the reference page the panel is on, e.g. api-reference/payments. Resolves the allowed host.

method

string

yes

GET, POST, PUT, PATCH, DELETE, HEAD or OPTIONS.

path

string

yes

Endpoint path relative to the API base, e.g. /v1/payments. Absolute URLs are rejected.

query

object

no

Query parameters. Max 50.

headers

object

no

Request headers. Max 25, each value up to 4096 chars.

body

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"}
      }'

Response200 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

402 docs_pro_required

the site owner is not on a paid Docs plan

upgrade the Docs plan

400

the page has no persisted API base URL

re-import the spec — pages imported before the panel shipped carry none

400

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

429

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

query

string

yes

The question. 3–500 characters.

top_k

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?"}'

Response200 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

402 docs_pro_required

the site owner is not on a paid Docs plan

upgrade the Docs plan

402 docs_ai_tokens_per_month_exceeded

the monthly AI token allowance is spent

the allowance resets at the billing period boundary; there is no Retry-After

422

query shorter than 3 or longer than 500 characters

shorten or lengthen the question

503

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

402

a Docs Pro surface, and this workspace is not entitled — or the AI token allowance is spent

422

the request body failed validation; the message names the field

429

rate-limited; the reader-facing relay and Ask-AI are both capped per reader

503

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 docs theme 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

Publish