Content Studio
234 endpoints from the published OpenAPI import.
List Pages
List all content pages (including drafts). Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
status | query | any | false | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/pages' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/pages",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/pages", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Page
Create a new content page. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: preview the create and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the create. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"slug": "string",
"title": "string",
"description": "string",
"agent_strategy": "string",
"agent_flow_id": "string",
"geo_ai_summary": "string",
"geo_ai_crawlers": "string",
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"blocks": [
{
"id": "string",
"type": "hero",
"data": {},
"component_slug": "string",
"component_version": "string",
"props": {},
"layout": "string",
"data_binding": {}
}
],
"template": "default"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"slug": "string", "title": "string", "description": "string", "agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "default"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"slug": "string", "title": "string", "description": "string", "agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "default"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"slug": "string", "title": "string", "description": "string", "agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "default"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Page
Get a page by ID. Use ?format=json|yaml|md|llm for agent-friendly responses.
P5: pass ?audit_level=off|errors|warnings|all to control the _page_audit decoration. Default 'warnings' returns errors + warnings in the audit block.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
audit_level | query | string | false | P5: include a _page_audit block on the response. 'off' skips the auditor entirely (cheapest). 'errors' / 'warnings' / 'all' filter by severity. Default 'warnings' — agent-friendly. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Page
Update a page. Phase 11+12 dry_run/confirm_token gated. P4 lock-aware.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the update and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the update. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"agent_strategy": "string",
"agent_flow_id": "string",
"geo_ai_summary": "string",
"geo_ai_crawlers": "string",
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"title": "string",
"description": "string",
"blocks": [
{
"id": "string",
"type": "hero",
"data": {},
"component_slug": "string",
"component_version": "string",
"props": {},
"layout": "string",
"data_binding": {}
}
],
"template": "string",
"collection_type": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "title": "string", "description": "string", "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "string", "collection_type": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "title": "string", "description": "string", "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "string", "collection_type": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "title": "string", "description": "string", "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "string", "collection_type": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Page
Archive a page (soft delete). Phase 11+12 dry_run/confirm_token gated. P4 lock-aware.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the delete. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Page Preview
Issue a short-lived iframe preview URL for the in-flight blocks the editor is currently showing. The URL is loaded by the Page Editor iframe; the Liquid renderer reads the token via __spideriq_preview_token query param and substitutes page.blocks with the supplied draft before rendering.
Tokens expire in 15 minutes — the editor will refetch on focus/edit. Lock 1 ↔ Lock 5: tenancy is enforced by validating the page belongs to the caller's resolved client_id; the snapshot stored in Redis carries the resolved client_id, not anything from the URL.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/preview' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"blocks": [
{
"type": "string",
"data": {}
}
],
"draft_mode": true
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/preview",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"blocks": [{"type": "string", "data": {}}], "draft_mode": true},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"blocks": [{"type": "string", "data": {}}], "draft_mode": true})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"blocks": [{"type": "string", "data": {}}], "draft_mode": true}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/preview", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Post Preview
Issue a short-lived, token-gated preview URL for a DRAFT blog post.
Draft posts 404 at /blog/<slug> on the live site (the public API serves published-only), so a human reviewer can't see one before publish. This mints an opaque 15-minute token bound to (client_id, slug); the returned URL proxies the tenant's deployed Liquid renderer at /blog/<slug> with the token, and the renderer substitutes the fresh draft post (noindex, no-store).
Lock 1 ↔ Lock 5: the post is fetched scoped to the caller's resolved client_id; the Redis snapshot stores that client_id, never anything from the URL. Works for any status (draft/published) — most useful for drafts.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/preview' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/preview",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/preview", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Publish Page
Publish a page (creates version snapshot). Phase 11+12 dry_run/confirm_token gated. P4 lock-aware.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the publish. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/publish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/publish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/publish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/publish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Duplicate Page
Duplicate a page. New row: status='draft', fresh UUIDs on every block, auto-generated slug (or caller-provided new_slug). The copy is always owned by the caller's client — no cross-tenant duplication via this endpoint.
Enables the Apr-24 catalog-triage follow-on work (template gallery, section library, import adapters all build on this primitive).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/duplicate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/duplicate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/duplicate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/duplicate", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Duplicate Page Block
Insert a deep copy of one block into the same page. Fresh UUID on the new block; same data/props/component_slug as the source.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
block_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/blocks/{block_id}/duplicate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"position": "after"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/blocks/{block_id}/duplicate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"position": "after"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/blocks/{block_id}/duplicate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"position": "after"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"position": "after"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/blocks/{block_id}/duplicate", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Insert Section Into Page Endpoint
Insert a marketplace section into an existing page (Phase C).
Request body matches InsertSectionRequest: { component_slug, component_version?, props?, position?, anchor_block_id?, data_binding?, layout_id? }
Phase 11+12 gated. dry_run=true returns the preview envelope; confirm_token consumes it and performs the mutation.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the insertion and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and apply the insertion. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
audit_level | query | string | false | P5: include an _audit block on the success response. Default 'all' for mutations so agents see every finding immediately. 'off' is available for tight-loop scripts that bulk-insert and audit later. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/insert-section' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/insert-section",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/insert-section", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/insert-section", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unpublish Page
Revert page to draft status. Phase 11+12 dry_run/confirm_token gated. P4 lock-aware.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the unpublish. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/unpublish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/unpublish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/unpublish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/unpublish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Page Versions
List version snapshots for a page (newest first).
P4: each row reports block_count + blocks_size so the editor can summarise without round-tripping the full snapshot. Use GET /pages/{id}/versions/{version_number} to fetch a single snapshot in full (with blocks).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/versions' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/versions",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/versions", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/versions", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Page Version
Fetch a single page version snapshot in full (includes blocks).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
version_number | path | integer | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/versions/{version_number}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/versions/{version_number}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/versions/{version_number}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/versions/{version_number}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Lock Page Endpoint
Lock a page against further mutations.
P4 — agent-surface hardening. Idempotent: re-locking refreshes the reason/timestamp. Any role with content-scoped access can lock; unlock authorisation is more restrictive (lock-holder OR force=true with super_admin / brand_admin).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/lock' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/lock",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/lock", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/lock", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
423 | Page already locked |
422 | Validation Error |
Unlock Page Endpoint
Unlock a page.
Authorisation:
- Anyone whose
user_idmatcheslocked_by_actor_idcan unlock. - super_admin / brand_admin can unlock with
?force=true. - Otherwise: 403 (force gate) or "Page not found / not authorised" (200 with the unchanged row would be a misleading response — we 404 so the caller distinguishes "the page doesn't exist" from "it's locked by someone else", since the latter is itself the answer to the permission question).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
force | query | boolean | false | super_admin / brand_admin override — unlock regardless of who locked. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/unlock' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/unlock",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/unlock", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/unlock", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Restore Page Version Endpoint
Restore a page to a historical version snapshot.
Phase 11+12 gated. dry_run=true returns a preview envelope with the snapshot summary. The page lock is enforced — call with force=true (super_admin / brand_admin) to override.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
version_number | query | integer | true | Which version to restore (1-indexed). |
dry_run | query | boolean | false | Phase 11+12: preview the restore + receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the restore. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/restore' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/restore",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/restore", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/restore", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Page
Self-contained page export with audit (P2 — agent-surface hardening).
Returns the page row + every component referenced by page.blocks (full body inlined: html_template / js / css / props_schema / dependencies / agent_meta / kind / layouts) + site-level settings + domains + a PageAuditor walk over the same data.
Three formats:
format=json(default) — flat JSON envelopeformat=md— human-readable Markdown (text/markdown)format=archive— ZIP byte stream (application/zip), VSCode-extension-compatible
The page must belong to the caller's client_id (Lock 5 — same multi-tenant scope as GET /pages/{id}).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
format | query | any | false | json (default) and llm return the flat JSON envelope; md returns human-readable Markdown; archive returns a ZIP whose layout matches the VSCode extension's local format. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/export' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/export",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/export", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/export", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Posts
List all blog posts (including drafts). Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
status | query | any | false | |
tag | query | any | false | |
category | query | any | false | Filter by category id |
author_id | query | any | false | Filter by author (byline) id |
created_by | query | any | false | Filter by record creator / agent id |
created_after | query | any | false | Only posts published-or-created on/after this ISO timestamp (time-window filter) |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/posts' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/posts",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/posts", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Post
Create a new blog post. Phase 11+12 dry_run/confirm_token gated.
Unknown fields in the request body are silently dropped by Pydantic (extra='ignore' default) but surfaced in warnings[] on the response with a "Did you mean X?" hint. Catches the common cover_image vs cover_image_url / category_id vs category_ids / featured vs is_featured confusions that AI agents fall into.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: preview the create and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the create. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"slug": "string",
"title": "string",
"excerpt": "string",
"agent_strategy": "string",
"agent_flow_id": "string",
"body": {},
"cover_image_url": "string",
"author_name": "string",
"author_id": "00000000-0000-0000-0000-000000000000",
"tags": [
"string"
],
"tag_ids": [
"00000000-0000-0000-0000-000000000000"
],
"category_ids": [
"00000000-0000-0000-0000-000000000000"
],
"is_featured": false,
"featured_image_alt": "string",
"tldr_summary": "string",
"related_post_ids": [
"00000000-0000-0000-0000-000000000000"
],
"seo_title": "string",
"seo_description": "string",
"og_image_url": "string",
"custom_fields": {}
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"slug": "string", "title": "string", "excerpt": "string", "agent_strategy": "string", "agent_flow_id": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": false, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"slug": "string", "title": "string", "excerpt": "string", "agent_strategy": "string", "agent_flow_id": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": false, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"slug": "string", "title": "string", "excerpt": "string", "agent_strategy": "string", "agent_flow_id": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": false, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Post
Get a post by ID. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Post
Update a blog post. Phase 11+12 dry_run/confirm_token gated.
Unknown fields in the request body are silently dropped by Pydantic but surfaced in warnings[] on the response with a "Did you mean X?" hint. Catches the common cover_image vs cover_image_url / category_id vs category_ids / featured vs is_featured confusions.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the update and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the update. |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"agent_strategy": "string",
"agent_flow_id": "string",
"title": "string",
"slug": "string",
"excerpt": "string",
"body": {},
"cover_image_url": "string",
"author_name": "string",
"author_id": "00000000-0000-0000-0000-000000000000",
"tags": [
"string"
],
"tag_ids": [
"00000000-0000-0000-0000-000000000000"
],
"category_ids": [
"00000000-0000-0000-0000-000000000000"
],
"is_featured": true,
"featured_image_alt": "string",
"tldr_summary": "string",
"related_post_ids": [
"00000000-0000-0000-0000-000000000000"
],
"seo_title": "string",
"seo_description": "string",
"og_image_url": "string",
"custom_fields": {}
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"agent_strategy": "string", "agent_flow_id": "string", "title": "string", "slug": "string", "excerpt": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": true, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"agent_strategy": "string", "agent_flow_id": "string", "title": "string", "slug": "string", "excerpt": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": true, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"agent_strategy": "string", "agent_flow_id": "string", "title": "string", "slug": "string", "excerpt": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": true, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Post
Delete a blog post. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the delete and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the delete. |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Publish Post
Publish a blog post.
Body is OPTIONAL. published_at backdates the publication (archive import); for a FUTURE go-live use POST /posts/{id}/schedule instead.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/publish' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/publish",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/publish", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/publish", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unpublish Post
Unpublish a blog post (set to draft).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/unpublish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/unpublish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/unpublish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/unpublish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Schedule Post
Schedule a post to auto-publish at a future time (status='scheduled').
The scheduler sidecar flips it to 'published' once the time arrives. Public surfaces gate on status='published', so a scheduled post stays private until then. A non-future time is rejected — use /publish for immediate publish.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/schedule' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/schedule",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/schedule", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/schedule", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unschedule Post
Cancel a scheduled publish — revert the post to draft.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/unschedule' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/unschedule",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/unschedule", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/unschedule", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Duplicate Post
Duplicate a blog post. Returns the new draft with a fresh slug + UUID.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/duplicate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/duplicate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/duplicate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/duplicate", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Post Status
Update post status (draft, pending_review, published, archived).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/status' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"status": "draft"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/status",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"status": "draft"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/status", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"status": "draft"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"status": "draft"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/status", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Post Related
Set related posts for a post.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X PUT 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/related' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '[
"string"
]'Python
import httpx
resp = httpx.put(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/related",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json=["string"],
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/related", {
method: "PUT",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify(["string"])
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`["string"]`)
req, _ := http.NewRequest("PUT", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/related", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Authors
List all authors. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
agent_type | query | any | false | |
is_active | query | any | false | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/authors' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/authors",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/authors", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/authors", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Author
Create a new author.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/authors' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"full_name": "string",
"slug": "string",
"avatar_url": "string",
"bio": "string",
"email": "string",
"role": "author",
"agent_type": "human",
"country": "string",
"city": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/authors",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/authors", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/authors", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Get Author
Get an author by ID. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
author_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Author
Update an author.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
author_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"full_name": "string",
"slug": "string",
"avatar_url": "string",
"bio": "string",
"email": "string",
"role": "author",
"agent_type": "human",
"country": "string",
"city": "string",
"is_active": true
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string", "is_active": true},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string", "is_active": true})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string", "is_active": true}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Author
Deactivate an author (soft-delete).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
author_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/authors/{author_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Tags
List all tags. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/tags' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/tags",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/tags", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/tags", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Tag
Create a new tag.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/tags' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"slug": "string",
"description": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/tags",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "slug": "string", "description": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/tags", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "slug": "string", "description": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "slug": "string", "description": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/tags", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Tag
Update a tag.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tag_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/tags/{tag_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"slug": "string",
"description": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/tags/{tag_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "slug": "string", "description": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/tags/{tag_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "slug": "string", "description": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "slug": "string", "description": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/tags/{tag_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Tag
Delete a tag.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tag_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/tags/{tag_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/tags/{tag_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/tags/{tag_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/tags/{tag_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Categories
List blog categories. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/categories' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/categories",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/categories", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/categories", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Category
Create a new category.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/categories' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"slug": "string",
"description": "string",
"parent_id": "00000000-0000-0000-0000-000000000000",
"sort_order": 0
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/categories",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/categories", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/categories", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Category
Update a category.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/categories/{category_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"slug": "string",
"description": "string",
"parent_id": "00000000-0000-0000-0000-000000000000",
"sort_order": 0
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/categories/{category_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/categories/{category_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/categories/{category_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Category
Delete a category.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/categories/{category_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/categories/{category_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/categories/{category_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/categories/{category_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Docs Tree
Get full docs tree (including drafts).
Docs Platform v2 · 3.4 — ?version= scopes the editor tree to one docs version (omit → default). Response carries all versions (every status, for management) + the resolved current_version.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
version | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/docs/tree' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/docs/tree",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/tree", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/docs/tree", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Docs
Flat list of docs (metadata only, no body) — complements GET /docs/tree.
Agents use this to discover a doc's UUID by title/status before fetching or mutating it via GET /docs/{doc_id}.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | any | false | Filter by status (draft / published / archived). |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/docs' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/docs",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/docs", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Doc
Create a documentation page.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/docs' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"agent_strategy": "string",
"agent_flow_id": "string",
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"parent_id": "00000000-0000-0000-0000-000000000000",
"slug": "string",
"title": "string",
"body": {},
"is_section": false,
"sort_order": 0,
"version": "default"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/docs",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "body": {}, "is_section": false, "sort_order": 0, "version": "default"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "body": {}, "is_section": false, "sort_order": 0, "version": "default"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "body": {}, "is_section": false, "sort_order": 0, "version": "default"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/docs", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Doc Versions
List the tenant's docs versions (all statuses, for management).
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/docs/versions' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/docs/versions",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/versions", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/docs/versions", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Create Doc Version
Register a new docs version label. is_default demotes the prior default.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/docs/versions' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"label": "string",
"title": "string",
"is_default": false,
"sort_order": 0,
"status": "published"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/docs/versions",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"label": "string", "title": "string", "is_default": false, "sort_order": 0, "status": "published"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/versions", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"label": "string", "title": "string", "is_default": false, "sort_order": 0, "status": "published"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"label": "string", "title": "string", "is_default": false, "sort_order": 0, "status": "published"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/docs/versions", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Doc Version
Update a docs version (title / order / status / default flag).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
version_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/docs/versions/{version_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"title": "string",
"is_default": true,
"sort_order": 0,
"status": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/docs/versions/{version_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"title": "string", "is_default": true, "sort_order": 0, "status": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/versions/{version_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"title": "string", "is_default": true, "sort_order": 0, "status": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"title": "string", "is_default": true, "sort_order": 0, "status": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/docs/versions/{version_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Doc Version
Delete a docs version. Refuses the default version or one still in use.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
version_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/docs/versions/{version_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/docs/versions/{version_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/versions/{version_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/docs/versions/{version_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Docs Analytics
Server-side docs analytics overview (views / searches / asks) for the tenant over the last days. Degrades to an empty rollup, never 500s.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
days | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/docs/analytics' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/docs/analytics",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/analytics", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/docs/analytics", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Doc
Get a doc by ID (drafts included).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Doc
Update a doc (title, body, SEO, hierarchy). Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the update and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the update. |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"agent_strategy": "string",
"agent_flow_id": "string",
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"parent_id": "00000000-0000-0000-0000-000000000000",
"title": "string",
"body": {},
"is_section": true,
"sort_order": 0
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "title": "string", "body": {}, "is_section": true, "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "title": "string", "body": {}, "is_section": true, "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "title": "string", "body": {}, "is_section": true, "sort_order": 0}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Doc
Archive a doc (soft delete). Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the delete. |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Duplicate Doc
Duplicate a doc page. Copy lives as a sibling of the original under the same parent_id with a fresh slug. Status: draft.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/duplicate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/duplicate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/duplicate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/duplicate", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Publish Doc
Publish a draft doc. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the publish. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/publish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/publish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/publish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/publish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unpublish Doc
Revert a doc to draft status. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the unpublish. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/unpublish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/unpublish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/unpublish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/unpublish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Doc
Self-contained doc export. Returns the doc row + site settings + domains.
Docs are prose-first, so there are no component bodies to inline (unlike page export). The doc must belong to the caller's client_id.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; md returns text/markdown. This route has no YAML renderer, so yaml is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/export' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/export",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/export", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/export", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Import Doc Markdown
Import a doc from a Markdown body. Create a new doc (omit doc_id, provide slug + title) or replace an existing doc's body (set doc_id). :::component{...} directives become embedded component nodes.
Create delegates to create_doc (ungated); update delegates to the Phase 11+12 dry_run/confirm_token-gated update_doc.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12 (update path): preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12 (update path): consume a prior preview token and perform the update. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/docs/import' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"markdown": "string",
"doc_id": "00000000-0000-0000-0000-000000000000",
"slug": "string",
"title": "string",
"parent_id": "00000000-0000-0000-0000-000000000000",
"is_section": true,
"sort_order": 0
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/docs/import",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "doc_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "is_section": true, "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/import", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "doc_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "is_section": true, "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "doc_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "is_section": true, "sort_order": 0}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/docs/import", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Import Openapi
Import an OpenAPI/Swagger spec into the docs tree. dry_run=true returns the planned section + pages without writing (powers the wizard preview); otherwise the reference is generated idempotently and (if publish) published.
Errors map to 422 (bad/oversized/unfetchable spec — message is client-safe) or 500 (logged, generic) — never leak the spec URL or upstream detail.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/docs/import-openapi' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"source_url": "string",
"spec_content": "string",
"spec_format": "auto",
"section": "api-reference",
"publish": false,
"dry_run": false
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/docs/import-openapi",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"source_url": "string", "spec_content": "string", "spec_format": "auto", "section": "api-reference", "publish": false, "dry_run": false},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/import-openapi", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"source_url": "string", "spec_content": "string", "spec_format": "auto", "section": "api-reference", "publish": false, "dry_run": false})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"source_url": "string", "spec_content": "string", "spec_format": "auto", "section": "api-reference", "publish": false, "dry_run": false}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/docs/import-openapi", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Doc Markdown
Export a doc's body as pure Markdown (round-trips with POST /docs/import).
:::component{...} directives are preserved (render_tiptap_markdown emits them via serialize_component_node). The title is prepended as an H1. Distinct from /docs/{id}/export?format=md, which wraps the same body in a JSON envelope.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/markdown' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/markdown",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/markdown", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/markdown", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Import Page Markdown
Import a page from a Markdown body — the markdown→page converter. Create a new page (omit page_id, provide slug + title) or replace an existing page's blocks (set page_id). Prose runs become rich_text blocks; :::component{...} directives become component blocks.
Delegates to the Phase 11+12 dry_run/confirm_token-gated create_page / update_page (the converter handler only does the markdown→blocks mapping).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the create/update. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/import' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"markdown": "string",
"page_id": "00000000-0000-0000-0000-000000000000",
"slug": "string",
"title": "string",
"template": "string",
"parent_id": "00000000-0000-0000-0000-000000000000",
"sort_order": 0
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/import",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "page_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "template": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/import", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "page_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "template": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "page_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "template": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/import", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Page Markdown
Export a page's blocks as pure Markdown (round-trips with POST /pages/import).
Component blocks serialize to :::component{...} directives (the converter contract — render_page_markdown(serialize_components=True)). This differs from /pages/{id}/export?format=md, which renders each component as a labelled human-readable section inside a JSON envelope (not round-trippable).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/markdown' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/markdown",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/markdown", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/markdown", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reorder Docs
Reorder documentation tree.
Try it
Examples
cURL
curl -X PUT 'https://spideriq.ai/api/v1/dashboard/content/docs/reorder' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"items": [
{}
]
}'Python
import httpx
resp = httpx.put(
"https://spideriq.ai/api/v1/dashboard/content/docs/reorder",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"items": [{}]},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/reorder", {
method: "PUT",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"items": [{}]})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"items": [{}]}`)
req, _ := http.NewRequest("PUT", "https://spideriq.ai/api/v1/dashboard/content/docs/reorder", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Navigation
Get navigation menu.
D4 — the editor reads the RAW menu (expand=False, the service default). A folder-bound item must round-trip as its BINDING; expanding here would make the next save bake a frozen snapshot of the page tree into the JSONB.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
location | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/navigation/{location}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/navigation/{location}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/navigation/{location}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/navigation/{location}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Navigation
Update navigation menu.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
location | path | string | true |
Try it
Examples
cURL
curl -X PUT 'https://spideriq.ai/api/v1/dashboard/content/navigation/{location}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"items": [
{
"label": "string",
"url": "string",
"icon": "string",
"children": [],
"is_external": false,
"badge": "string",
"source": {
"kind": "site",
"folder_id": {},
"depth": 2
}
}
]
}'Python
import httpx
resp = httpx.put(
"https://spideriq.ai/api/v1/dashboard/content/navigation/{location}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"items": [{"label": "string", "url": "string", "icon": "string", "children": [], "is_external": false, "badge": "string", "source": {"kind": "site", "folder_id": {}, "depth": 2}}]},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/navigation/{location}", {
method: "PUT",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"items": [{"label": "string", "url": "string", "icon": "string", "children": [], "is_external": false, "badge": "string", "source": {"kind": "site", "folder_id": {}, "depth": 2}}]})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"items": [{"label": "string", "url": "string", "icon": "string", "children": [], "is_external": false, "badge": "string", "source": {"kind": "site", "folder_id": {}, "depth": 2}}]}`)
req, _ := http.NewRequest("PUT", "https://spideriq.ai/api/v1/dashboard/content/navigation/{location}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash List Directory Categories
List all directory categories for this client (includes drafts/empty ones).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/directory/categories' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/directory/categories", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Create Directory Category
Create a directory category.
Body: {name, slug?, description?, icon?, seo_title_template?, seo_description_template?, template?, data_source?, sort_order?}
seo_*_template strings accept {category}, {city}, {listing} placeholders — rendered server-side on the public read endpoints.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/directory/categories' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/directory/categories", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Dash Get Directory Category
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Update Directory Category
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Delete Directory Category
Delete a category (cascades to its listings).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Bulk Upsert Listings
Bulk upsert listings. Body: {listings: [{name, slug?, city, state?, ...}, ...]}.
Upsert semantics: slug unique per category. Missing slug auto-generated from name. Refreshes the materialized view + category counts on success.
Typical use: agent dumps the results of a SpiderMaps campaign into a category via a single call. Supports source_job_id so listings can be traced back to the job that produced them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings/bulk' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings/bulk",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings/bulk", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings/bulk", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash List Directory Listings
List listings across categories. Filters: category_slug, city, status.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | query | any | false | |
city | query | any | false | |
status | query | string | false | |
page | query | integer | false | |
page_size | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/directory/listings' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/directory/listings",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/listings", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/directory/listings", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Upsert Listing
Create or update a single listing in a category. Slug-based upsert.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Dash Delete Listing
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true | |
listing_slug | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings/{listing_slug}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings/{listing_slug}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings/{listing_slug}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/listings/{listing_slug}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Import From Idap
Populate a directory category from the tenant's IDAP data (norm_cli_*.businesses).
One call replaces the "run SpiderMaps → transform results → bulk_upsert" loop. The norm_cli_* schema is already the canonical store for every business SpiderIQ has seen for this tenant — this reads directly from it.
Every column the IDAP column manifest declares reaches the listing — typed columns land in typed columns, the rest land in the data jsonb under their frozen public field id.
Body (all optional): {category_filter: "Plumber", country_code: "US", city: "Miami", rating_min: 4.0, limit: 5000, prune: false}
prune: true ARCHIVES (never deletes) listings in this category whose source row no longer matches the filter — that is what makes a re-import honest, since the upsert is keyed on (category, slug) and a business deleted or renamed in IDAP otherwise leaves a stale published listing forever. It is OFF by default, and it refuses to run when the import hit its limit (a truncated result set cannot tell "gone" from "on the next page") — the refusal comes back as prune_skipped_reason.
Returns {upserted, inserted, updated, pruned, failed, source_rows, affected_cities, source_schema, fields_mapped, filter, sync_log_id, ...}.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/import-from-idap' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/import-from-idap",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/import-from-idap", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/directory/categories/{category_slug}/import-from-idap", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Refresh Directory Stats
Manually refresh the city_stats materialized view. Normally auto-refreshed on bulk upsert.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/directory/refresh-stats' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/directory/refresh-stats",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/directory/refresh-stats", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/directory/refresh-stats", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
List Media
List media files for the current client, newest first.
Filters: folder (exact match), mime_type (prefix match — image/ catches all image MIME types).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
folder | query | any | false | |
mime_type | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/media' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/media",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/media", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/media", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Upload Media
Upload an image to Cloudflare R2.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/media/upload' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"file": "string",
"folder": "/",
"alt_text": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/media/upload",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"file": "string", "folder": "/", "alt_text": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/media/upload", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"file": "string", "folder": "/", "alt_text": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"file": "string", "folder": "/", "alt_text": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/media/upload", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Upload Media From Url
Host a remote image URL on Cloudflare R2 — the agent-callable, JSON-only twin of POST /media/upload.
Agents reaching the content platform via skill_call can't send multipart, and a generated hero image lives at a provider URL (kie.* etc.) that the cover_image_url allowlist rejects. This fetches the URL SSRF-safely and runs the same validate → WebP-transcode → R2 → content_media → catalog pipeline as /media/upload; the returned media.r2_url is on our allowlisted host, so it then passes straight into createPost / content_update_page with no allowlist change.
201 + {success, media, asset}. A bad/unreachable URL or non-image body is a 400; an oversized body (>5 MB) is a 413.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/media/upload-from-url' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"media_url": "string",
"folder": "/",
"alt_text": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/media/upload-from-url",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"media_url": "string", "folder": "/", "alt_text": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/media/upload-from-url", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"media_url": "string", "folder": "/", "alt_text": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"media_url": "string", "folder": "/", "alt_text": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/media/upload-from-url", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Upload Media Batch
Upload one or many files to SpiderMedia (SeaweedFS).
Weight policy — scroll-sequence folders (scroll-sequences/* or is_scroll_sequence=true): 500 KB per-file hard, 20 MB batch total hard, 200 KB / 10 MB soft warnings. Everything else: 20 MB per-file (500 MB for video/*), 500 MB batch total. Hard ceilings return 400 with the offending file(s); soft warnings come back in warnings[] with the upload succeeding.
Returns {uploaded: [...], failed: [...], warnings: [...], totals}.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/media/upload-batch' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"files": [
"string"
],
"folder": "string",
"preserve_filename": false,
"is_scroll_sequence": false
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/media/upload-batch",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"files": ["string"], "folder": "string", "preserve_filename": false, "is_scroll_sequence": false},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/media/upload-batch", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"files": ["string"], "folder": "string", "preserve_filename": false, "is_scroll_sequence": false})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"files": ["string"], "folder": "string", "preserve_filename": false, "is_scroll_sequence": false}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/media/upload-batch", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Media
Update a legacy R2 media file's metadata (folder / alt_text / caption).
Targets the content_media table (the dashboard R2 uploader surface), NOT the per-tenant media_assets catalog. True PATCH — only supplied fields change. 200 + the updated row; 404 if no such media for this client.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
media_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/media/{media_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"folder": "string",
"alt_text": "string",
"caption": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/media/{media_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"folder": "string", "alt_text": "string", "caption": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/media/{media_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"folder": "string", "alt_text": "string", "caption": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"folder": "string", "alt_text": "string", "caption": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/media/{media_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Media
Delete a legacy R2 media file (content_media row + best-effort R2 object cleanup). 204 on success, 404 if no such media for this client.
The DB row delete is authoritative; the R2 object removal is best-effort and non-blocking — an orphaned R2 object never fails the request (the row is already gone, so the asset no longer appears in the library).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
media_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/media/{media_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/media/{media_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/media/{media_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/media/{media_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
204 | Successful Response |
422 | Validation Error |
Get Settings
Get content settings.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/settings' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/settings",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/settings", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/settings", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Update Settings
Update content settings. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the update. |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/settings' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"site_name": "string",
"site_tagline": "string",
"favicon_url": "string",
"primary_color": "string",
"surface_color": "string",
"surface_elevated_color": "string",
"subtle_color": "string",
"body_text_color": "string",
"heading_color": "string",
"logo_dark_url": "string",
"logo_light_url": "string",
"copyright_text": "string",
"social_links": {},
"google_analytics_id": "string",
"plausible_domain": "string",
"default_meta_title": "string",
"default_meta_description": "string",
"default_og_image_url": "string",
"default_seo_title_suffix": "string",
"default_agent_strategy": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/settings",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"site_name": "string", "site_tagline": "string", "favicon_url": "string", "primary_color": "string", "surface_color": "string", "surface_elevated_color": "string", "subtle_color": "string", "body_text_color": "string", "heading_color": "string", "logo_dark_url": "string", "logo_light_url": "string", "copyright_text": "string", "social_links": {}, "google_analytics_id": "string", "plausible_domain": "string", "default_meta_title": "string", "default_meta_description": "string", "default_og_image_url": "string", "default_seo_title_suffix": "string", "default_agent_strategy": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/settings", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"site_name": "string", "site_tagline": "string", "favicon_url": "string", "primary_color": "string", "surface_color": "string", "surface_elevated_color": "string", "subtle_color": "string", "body_text_color": "string", "heading_color": "string", "logo_dark_url": "string", "logo_light_url": "string", "copyright_text": "string", "social_links": {}, "google_analytics_id": "string", "plausible_domain": "string", "default_meta_title": "string", "default_meta_description": "string", "default_og_image_url": "string", "default_seo_title_suffix": "string", "default_agent_strategy": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"site_name": "string", "site_tagline": "string", "favicon_url": "string", "primary_color": "string", "surface_color": "string", "surface_elevated_color": "string", "subtle_color": "string", "body_text_color": "string", "heading_color": "string", "logo_dark_url": "string", "logo_light_url": "string", "copyright_text": "string", "social_links": {}, "google_analytics_id": "string", "plausible_domain": "string", "default_meta_title": "string", "default_meta_description": "string", "default_og_image_url": "string", "default_seo_title_suffix": "string", "default_agent_strategy": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/settings", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Redirects
List all redirects.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/redirects' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/redirects",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/redirects", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/redirects", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Create Redirect
Create a redirect.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/redirects' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"from_path": "string",
"to_path": "string",
"status_code": 301
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/redirects",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"from_path": "string", "to_path": "string", "status_code": 301},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/redirects", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"from_path": "string", "to_path": "string", "status_code": 301})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"from_path": "string", "to_path": "string", "status_code": 301}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/redirects", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Redirect
Delete a redirect.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
redirect_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/redirects/{redirect_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/redirects/{redirect_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/redirects/{redirect_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/redirects/{redirect_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Domains
List all custom domains for this client plus the auto-provisioned platform preview URL when the client has ever deployed.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/domains' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/domains",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/domains", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Add Domain
Register a new custom domain.
Drives BOTH Cloudflare onboarding paths and surfaces the outcome of each so the dashboard can render an actionable banner instead of silently masking failures:
- CF for SaaS custom hostname — for domains whose zone is NOT in our CF account. The client adds a CNAME to the fallback origin and CF handles SSL + dispatch.
- Worker Route on the domain's own zone — for domains whose zone IS in our CF account (incl. subdomains of zones we own). Without this, KV mappings exist but CF returns 522 because no Worker handles the inbound request.
Each helper detects which path it owns and no-ops on the other (see register_custom_hostname skipping in-account zones, and ensure_worker_route skipping zones in other accounts). Both are called unconditionally; their structured return values populate worker_route_status and custom_hostname_status on the response.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/domains' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"domain": "acme.com"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/domains",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"domain": "acme.com"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"domain": "acme.com"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"domain": "acme.com"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/domains", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Add Subdomain
Register a free {label}.sites.spideriq.ai subdomain.
The zero-cost counterpart to add_domain: sites.spideriq.ai is a zone we own with a wildcard Worker Route already configured, so this path makes NO Cloudflare custom-hostname call and needs NO DNS verification — it writes the DOMAIN_MAP KV entry and the dispatch Worker routes the hostname to the client's tenant script. Available on every tier; the free tier's single slot is one of these.
Counts against the same max_domains quota as a custom domain.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/domains/subdomain' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"label": "acme"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/domains/subdomain",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"label": "acme"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains/subdomain", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"label": "acme"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"label": "acme"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/domains/subdomain", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Check Subdomain Availability
Check whether a {label}.sites.spideriq.ai subdomain is free.
Powers the live availability check in the dashboard subdomain editor. Returns {available, host, reason}. available=false with a reason when the label is malformed; otherwise reflects global host uniqueness (content_domains.domain is globally unique).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
label | query | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/domains/subdomain/availability' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/domains/subdomain/availability",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains/subdomain/availability", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/domains/subdomain/availability", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Domain
Update a domain (SD1): set its start page and/or rename the host.
A rename remaps Cloudflare so the new host serves the same tenant site — the new DOMAIN_MAP KV entry (and, for an out-of-account custom domain, a fresh custom hostname + Worker Route) is created and the old host's mapping is torn down. Subdomains on *.sites.spideriq.ai route via the existing wildcard, so they only need the KV swap. The change goes live on the next deploy.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/domains/{domain}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"homepage_slug": "promo",
"new_domain": "go.acme.com"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/domains/{domain}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"homepage_slug": "promo", "new_domain": "go.acme.com"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains/{domain}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"homepage_slug": "promo", "new_domain": "go.acme.com"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"homepage_slug": "promo", "new_domain": "go.acme.com"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/domains/{domain}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Remove Domain
Remove a custom domain.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/domains/{domain}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/domains/{domain}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains/{domain}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/domains/{domain}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Verify Domain
Verify a domain (checks DNS TXT record).
Surfaces needs_deploy=True when the client has no live deploy yet so the dashboard can prompt "Click to deploy your site" — without that, a freshly verified domain will return CF 522 because the per-client tenant Worker script doesn't exist in the dispatch namespace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/verify' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/verify",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/verify", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/verify", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Recheck Domain Ssl
Re-query Cloudflare for this domain's live SSL state and persist it.
The on-demand, customer-triggered counterpart to the background reconciliation poll: powers the dashboard "Re-check" button so a customer who just fixed their DNS doesn't have to wait for the next poll tick. Does exactly ONE Cloudflare custom-hostname read for the one domain (not a fan-out over the whole list — that stays cheap and rate-limit-safe), maps the CF SSL lifecycle onto our ssl_status enum, and returns the refreshed row with the live CF status echoed in custom_hostname_status.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/recheck' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/recheck",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/recheck", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/recheck", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Set Primary Domain
Set a domain as the primary domain for this client.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/primary' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/primary",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/primary", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/primary", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Domain Project
Move a domain to a different project (website) in the same workspace.
Projects 4a migration helper: every existing domain was backfilled to the workspace DEFAULT project, so a multi-project workspace needs this to assign a domain to its real website (e.g. docs.example.com → the docs project). Workspace-scoped on purpose — the move targets a domain regardless of the currently-selected project, because the point is to move it OUT of its current one. The target project is validated to belong to this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/domains/{domain}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Page Project
Move a page (and its folder subtree) to another project in this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/pages/{page_id}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Post Project
Move a blog post to another project in this workspace (clears project-scoped categories/tags/relationships; free-text tags + pins ride along).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/posts/{post_id}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Doc Project
Move a doc (and its subtree) to another project in this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/docs/{doc_id}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Changelog Project
Move a changelog entry to another project in this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Deploy Site
Deploy the client's tenant site to Workers for Platforms.
Phase 11+12: pass dry_run=true to receive a preview URL and confirm_token without deploying; pass confirm_token=<cft_…> to consume the prior preview and deploy to production. Calls without either flag keep today's immediate behaviour (back-compat until Stage 4 rollout flips the default).
domain=<host> (Bug #4) scopes which of the workspace's domains get their CF DOMAIN_MAP entry + Worker Route refreshed, so a deploy no longer silently re-touches a sibling domain's routing. Unknown host → 400.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: issue a preview + confirm_token without deploying. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and deploy to production. |
domain | query | any | false | Bug #4: scope the DOMAIN_MAP/route fan-out to a single host of this workspace (else all of the active project's domains). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/deploy' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/deploy",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/deploy", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/deploy", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Deploy Site Preview
Phase 11+12 Stage 2 — issue a preview URL + confirm_token for the proposed deploy. No CF production script upload, no DNS flip. Caller reviews the preview, then calls POST /deploy/production with the confirm_token to actually deploy.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/deploy/preview' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/deploy/preview",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/deploy/preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/deploy/preview", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Deploy Site Production
Phase 11+12 Stage 2 — consume a prior preview's confirm_token (Lock 4) and run the real deploy. 403 on tenant/action/resource mismatch, 410 on expired, 409 on already-consumed replay.
domain=<host> (Bug #4) scopes the routing fan-out to a single host.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
confirm_token | query | string | true | Token from a prior /deploy/preview call. |
domain | query | any | false | Bug #4: scope the DOMAIN_MAP/route fan-out to a single host of this workspace (else all of the active project's domains). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/deploy/production' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/deploy/production",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/deploy/production", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/deploy/production", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Deploy Status
Get the most recent deploy status for this client.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/deploy/status' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/deploy/status",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/deploy/status", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/deploy/status", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
List Deploys
List recent deploys for this client.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/deploy/history' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/deploy/history",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/deploy/history", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/deploy/history", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Deploy Readiness
Check if this client's site is ready to deploy.
Returns a checklist of prerequisites (settings, domain, templates, pages) with pass/fail status and actionable fix instructions. Blocking items prevent deploy; warnings are advisory.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/deploy/readiness' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/deploy/readiness",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/deploy/readiness", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/deploy/readiness", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Get Deploy Detail
Full detail for a single deploy — backs the per-deploy detail page.
Client-scoped: returns 404 if the deploy doesn't exist OR belongs to a different tenant (no cross-tenant leakage). Computes duration_ms from deployed_at − created_at. Declared AFTER the static /deploy/* routes so {deploy_id} never shadows status/history/readiness.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
deploy_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/deploy/{deploy_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/deploy/{deploy_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/deploy/{deploy_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/deploy/{deploy_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Changelog
List changelog entries (newest first).
Drafts are included for the editor surface. Paginated — the public feed + timeline read the same service method with include_drafts=False.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | any | false | Filter by status (draft / published / archived). |
page | query | any | false | 1-based page number (house pattern; wins over limit/offset). |
page_size | query | any | false | Entries per page (1-200, default 50). |
limit | query | any | false | Legacy alias for page_size. Kept for back-compat. |
offset | query | any | false | Legacy alias — raw row offset. Kept for back-compat. |
sort | query | string | false | Ordering, newest first. published_at (default) = release date. version = semver compared NUMERICALLY per component, so v2.10.0 sorts above v2.9.0 — use it when the entries were backfilled and their timestamps don't reflect true release order. |
include_body | query | boolean | false | Include each entry's full Tiptap body. Pass false for a light index (id/version/title/status/dates) — 25 entries with bodies is ~128k chars, which blows an agent's tool-output ceiling. Fetch a single body with GET /changelog/{entry_id}. Defaults true so the dashboard editor keeps its one-shot list→edit flow. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/changelog' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/changelog",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/changelog", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/changelog", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Changelog
Create a draft changelog entry (409 on a duplicate version).
published_at is optional and does NOT publish the entry — it pre-stamps the release date so a backfilled history lands in true order on the public timeline (which is ordered by date, never by version string).
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/changelog' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"version": "string",
"title": "string",
"body": {},
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/changelog",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/changelog", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/changelog", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Get Changelog
Get one changelog entry by ID (drafts included).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Changelog
Update a changelog entry's title/body (version is immutable post-create only via this route's schema; pass it through update_changelog if needed).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"version": "string",
"title": "string",
"body": {},
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Changelog
Soft-delete a changelog entry (status → archived). Returns 204.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Publish Changelog
Publish a changelog entry (fires changelog.published on first publish).
The body is OPTIONAL — with none, the entry is stamped NOW() exactly as before. Send {"published_at": "..."} to publish a historical entry with its real release date; it wins over any date already on the entry.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/publish' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/publish",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/publish", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/publish", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unpublish Changelog
Revert a changelog entry to draft.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/unpublish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/unpublish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/unpublish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/changelog/{entry_id}/unpublish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Audit Internal Links
Walk every published page's blocks + navigation menus and validate internal links against the published-page roster + active redirects.
Returns {valid_count, broken: [{path, source, reason}], proposed_redirects, known_redirects}.
Fixes the Unavis-report pain: cleaning up /en/* legacy URLs across nav + blocks used to require manual crawling. One call surfaces every broken link with its exact source so agents can propose redirects in a single pass.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/audit/links' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/audit/links",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/audit/links", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/content/audit/links", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
List Pages
List all content pages (including drafts). Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
status | query | any | false | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Page
Create a new content page. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: preview the create and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the create. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"slug": "string",
"title": "string",
"description": "string",
"agent_strategy": "string",
"agent_flow_id": "string",
"geo_ai_summary": "string",
"geo_ai_crawlers": "string",
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"blocks": [
{
"id": "string",
"type": "hero",
"data": {},
"component_slug": "string",
"component_version": "string",
"props": {},
"layout": "string",
"data_binding": {}
}
],
"template": "default"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"slug": "string", "title": "string", "description": "string", "agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "default"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"slug": "string", "title": "string", "description": "string", "agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "default"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"slug": "string", "title": "string", "description": "string", "agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "default"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Page
Get a page by ID. Use ?format=json|yaml|md|llm for agent-friendly responses.
P5: pass ?audit_level=off|errors|warnings|all to control the _page_audit decoration. Default 'warnings' returns errors + warnings in the audit block.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
audit_level | query | string | false | P5: include a _page_audit block on the response. 'off' skips the auditor entirely (cheapest). 'errors' / 'warnings' / 'all' filter by severity. Default 'warnings' — agent-friendly. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Page
Update a page. Phase 11+12 dry_run/confirm_token gated. P4 lock-aware.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the update and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the update. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"agent_strategy": "string",
"agent_flow_id": "string",
"geo_ai_summary": "string",
"geo_ai_crawlers": "string",
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"title": "string",
"description": "string",
"blocks": [
{
"id": "string",
"type": "hero",
"data": {},
"component_slug": "string",
"component_version": "string",
"props": {},
"layout": "string",
"data_binding": {}
}
],
"template": "string",
"collection_type": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "title": "string", "description": "string", "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "string", "collection_type": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "title": "string", "description": "string", "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "string", "collection_type": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"agent_strategy": "string", "agent_flow_id": "string", "geo_ai_summary": "string", "geo_ai_crawlers": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "title": "string", "description": "string", "blocks": [{"id": "string", "type": "hero", "data": {}, "component_slug": "string", "component_version": "string", "props": {}, "layout": "string", "data_binding": {}}], "template": "string", "collection_type": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Page
Archive a page (soft delete). Phase 11+12 dry_run/confirm_token gated. P4 lock-aware.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the delete. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Page Preview
Issue a short-lived iframe preview URL for the in-flight blocks the editor is currently showing. The URL is loaded by the Page Editor iframe; the Liquid renderer reads the token via __spideriq_preview_token query param and substitutes page.blocks with the supplied draft before rendering.
Tokens expire in 15 minutes — the editor will refetch on focus/edit. Lock 1 ↔ Lock 5: tenancy is enforced by validating the page belongs to the caller's resolved client_id; the snapshot stored in Redis carries the resolved client_id, not anything from the URL.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/preview' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"blocks": [
{
"type": "string",
"data": {}
}
],
"draft_mode": true
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/preview",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"blocks": [{"type": "string", "data": {}}], "draft_mode": true},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"blocks": [{"type": "string", "data": {}}], "draft_mode": true})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"blocks": [{"type": "string", "data": {}}], "draft_mode": true}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/preview", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Post Preview
Issue a short-lived, token-gated preview URL for a DRAFT blog post.
Draft posts 404 at /blog/<slug> on the live site (the public API serves published-only), so a human reviewer can't see one before publish. This mints an opaque 15-minute token bound to (client_id, slug); the returned URL proxies the tenant's deployed Liquid renderer at /blog/<slug> with the token, and the renderer substitutes the fresh draft post (noindex, no-store).
Lock 1 ↔ Lock 5: the post is fetched scoped to the caller's resolved client_id; the Redis snapshot stores that client_id, never anything from the URL. Works for any status (draft/published) — most useful for drafts.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/preview' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/preview",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/preview", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Publish Page
Publish a page (creates version snapshot). Phase 11+12 dry_run/confirm_token gated. P4 lock-aware.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the publish. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/publish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/publish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/publish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/publish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Duplicate Page
Duplicate a page. New row: status='draft', fresh UUIDs on every block, auto-generated slug (or caller-provided new_slug). The copy is always owned by the caller's client — no cross-tenant duplication via this endpoint.
Enables the Apr-24 catalog-triage follow-on work (template gallery, section library, import adapters all build on this primitive).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/duplicate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/duplicate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/duplicate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/duplicate", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Duplicate Page Block
Insert a deep copy of one block into the same page. Fresh UUID on the new block; same data/props/component_slug as the source.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
block_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/blocks/{block_id}/duplicate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"position": "after"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/blocks/{block_id}/duplicate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"position": "after"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/blocks/{block_id}/duplicate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"position": "after"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"position": "after"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/blocks/{block_id}/duplicate", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Insert Section Into Page Endpoint
Insert a marketplace section into an existing page (Phase C).
Request body matches InsertSectionRequest: { component_slug, component_version?, props?, position?, anchor_block_id?, data_binding?, layout_id? }
Phase 11+12 gated. dry_run=true returns the preview envelope; confirm_token consumes it and performs the mutation.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the insertion and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and apply the insertion. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
audit_level | query | string | false | P5: include an _audit block on the success response. Default 'all' for mutations so agents see every finding immediately. 'off' is available for tight-loop scripts that bulk-insert and audit later. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/insert-section' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/insert-section",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/insert-section", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/insert-section", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unpublish Page
Revert page to draft status. Phase 11+12 dry_run/confirm_token gated. P4 lock-aware.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the unpublish. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/unpublish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/unpublish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/unpublish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/unpublish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Page Versions
List version snapshots for a page (newest first).
P4: each row reports block_count + blocks_size so the editor can summarise without round-tripping the full snapshot. Use GET /pages/{id}/versions/{version_number} to fetch a single snapshot in full (with blocks).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/versions' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/versions",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/versions", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/versions", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Page Version
Fetch a single page version snapshot in full (includes blocks).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
version_number | path | integer | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/versions/{version_number}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/versions/{version_number}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/versions/{version_number}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/versions/{version_number}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Lock Page Endpoint
Lock a page against further mutations.
P4 — agent-surface hardening. Idempotent: re-locking refreshes the reason/timestamp. Any role with content-scoped access can lock; unlock authorisation is more restrictive (lock-holder OR force=true with super_admin / brand_admin).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/lock' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/lock",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/lock", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/lock", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
423 | Page already locked |
422 | Validation Error |
Unlock Page Endpoint
Unlock a page.
Authorisation:
- Anyone whose
user_idmatcheslocked_by_actor_idcan unlock. - super_admin / brand_admin can unlock with
?force=true. - Otherwise: 403 (force gate) or "Page not found / not authorised" (200 with the unchanged row would be a misleading response — we 404 so the caller distinguishes "the page doesn't exist" from "it's locked by someone else", since the latter is itself the answer to the permission question).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
force | query | boolean | false | super_admin / brand_admin override — unlock regardless of who locked. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/unlock' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/unlock",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/unlock", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/unlock", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Restore Page Version Endpoint
Restore a page to a historical version snapshot.
Phase 11+12 gated. dry_run=true returns a preview envelope with the snapshot summary. The page lock is enforced — call with force=true (super_admin / brand_admin) to override.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
version_number | query | integer | true | Which version to restore (1-indexed). |
dry_run | query | boolean | false | Phase 11+12: preview the restore + receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the restore. |
force | query | boolean | false | P4: bypass page lock (super_admin / brand_admin only). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/restore' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/restore",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/restore", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/restore", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Page
Self-contained page export with audit (P2 — agent-surface hardening).
Returns the page row + every component referenced by page.blocks (full body inlined: html_template / js / css / props_schema / dependencies / agent_meta / kind / layouts) + site-level settings + domains + a PageAuditor walk over the same data.
Three formats:
format=json(default) — flat JSON envelopeformat=md— human-readable Markdown (text/markdown)format=archive— ZIP byte stream (application/zip), VSCode-extension-compatible
The page must belong to the caller's client_id (Lock 5 — same multi-tenant scope as GET /pages/{id}).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true | |
format | query | any | false | json (default) and llm return the flat JSON envelope; md returns human-readable Markdown; archive returns a ZIP whose layout matches the VSCode extension's local format. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/export' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/export",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/export", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/export", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Posts
List all blog posts (including drafts). Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
status | query | any | false | |
tag | query | any | false | |
category | query | any | false | Filter by category id |
author_id | query | any | false | Filter by author (byline) id |
created_by | query | any | false | Filter by record creator / agent id |
created_after | query | any | false | Only posts published-or-created on/after this ISO timestamp (time-window filter) |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Post
Create a new blog post. Phase 11+12 dry_run/confirm_token gated.
Unknown fields in the request body are silently dropped by Pydantic (extra='ignore' default) but surfaced in warnings[] on the response with a "Did you mean X?" hint. Catches the common cover_image vs cover_image_url / category_id vs category_ids / featured vs is_featured confusions that AI agents fall into.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: preview the create and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the create. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"slug": "string",
"title": "string",
"excerpt": "string",
"agent_strategy": "string",
"agent_flow_id": "string",
"body": {},
"cover_image_url": "string",
"author_name": "string",
"author_id": "00000000-0000-0000-0000-000000000000",
"tags": [
"string"
],
"tag_ids": [
"00000000-0000-0000-0000-000000000000"
],
"category_ids": [
"00000000-0000-0000-0000-000000000000"
],
"is_featured": false,
"featured_image_alt": "string",
"tldr_summary": "string",
"related_post_ids": [
"00000000-0000-0000-0000-000000000000"
],
"seo_title": "string",
"seo_description": "string",
"og_image_url": "string",
"custom_fields": {}
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"slug": "string", "title": "string", "excerpt": "string", "agent_strategy": "string", "agent_flow_id": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": false, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"slug": "string", "title": "string", "excerpt": "string", "agent_strategy": "string", "agent_flow_id": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": false, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"slug": "string", "title": "string", "excerpt": "string", "agent_strategy": "string", "agent_flow_id": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": false, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Post
Get a post by ID. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Post
Update a blog post. Phase 11+12 dry_run/confirm_token gated.
Unknown fields in the request body are silently dropped by Pydantic but surfaced in warnings[] on the response with a "Did you mean X?" hint. Catches the common cover_image vs cover_image_url / category_id vs category_ids / featured vs is_featured confusions.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the update and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the update. |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"agent_strategy": "string",
"agent_flow_id": "string",
"title": "string",
"slug": "string",
"excerpt": "string",
"body": {},
"cover_image_url": "string",
"author_name": "string",
"author_id": "00000000-0000-0000-0000-000000000000",
"tags": [
"string"
],
"tag_ids": [
"00000000-0000-0000-0000-000000000000"
],
"category_ids": [
"00000000-0000-0000-0000-000000000000"
],
"is_featured": true,
"featured_image_alt": "string",
"tldr_summary": "string",
"related_post_ids": [
"00000000-0000-0000-0000-000000000000"
],
"seo_title": "string",
"seo_description": "string",
"og_image_url": "string",
"custom_fields": {}
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"agent_strategy": "string", "agent_flow_id": "string", "title": "string", "slug": "string", "excerpt": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": true, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"agent_strategy": "string", "agent_flow_id": "string", "title": "string", "slug": "string", "excerpt": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": true, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"agent_strategy": "string", "agent_flow_id": "string", "title": "string", "slug": "string", "excerpt": "string", "body": {}, "cover_image_url": "string", "author_name": "string", "author_id": "00000000-0000-0000-0000-000000000000", "tags": ["string"], "tag_ids": ["00000000-0000-0000-0000-000000000000"], "category_ids": ["00000000-0000-0000-0000-000000000000"], "is_featured": true, "featured_image_alt": "string", "tldr_summary": "string", "related_post_ids": ["00000000-0000-0000-0000-000000000000"], "seo_title": "string", "seo_description": "string", "og_image_url": "string", "custom_fields": {}}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Post
Delete a blog post. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the delete and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the delete. |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Publish Post
Publish a blog post.
Body is OPTIONAL. published_at backdates the publication (archive import); for a FUTURE go-live use POST /posts/{id}/schedule instead.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/publish' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/publish",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/publish", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/publish", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unpublish Post
Unpublish a blog post (set to draft).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/unpublish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/unpublish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/unpublish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/unpublish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Schedule Post
Schedule a post to auto-publish at a future time (status='scheduled').
The scheduler sidecar flips it to 'published' once the time arrives. Public surfaces gate on status='published', so a scheduled post stays private until then. A non-future time is rejected — use /publish for immediate publish.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/schedule' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/schedule",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/schedule", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/schedule", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unschedule Post
Cancel a scheduled publish — revert the post to draft.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/unschedule' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/unschedule",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/unschedule", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/unschedule", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Duplicate Post
Duplicate a blog post. Returns the new draft with a fresh slug + UUID.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/duplicate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/duplicate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/duplicate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/duplicate", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Post Status
Update post status (draft, pending_review, published, archived).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/status' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"status": "draft"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/status",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"status": "draft"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/status", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"status": "draft"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"status": "draft"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/status", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Post Related
Set related posts for a post.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X PUT 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/related' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '[
"string"
]'Python
import httpx
resp = httpx.put(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/related",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json=["string"],
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/related", {
method: "PUT",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify(["string"])
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`["string"]`)
req, _ := http.NewRequest("PUT", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/related", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Authors
List all authors. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
agent_type | query | any | false | |
is_active | query | any | false | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Author
Create a new author.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"full_name": "string",
"slug": "string",
"avatar_url": "string",
"bio": "string",
"email": "string",
"role": "author",
"agent_type": "human",
"country": "string",
"city": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Get Author
Get an author by ID. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
author_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Author
Update an author.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
author_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"full_name": "string",
"slug": "string",
"avatar_url": "string",
"bio": "string",
"email": "string",
"role": "author",
"agent_type": "human",
"country": "string",
"city": "string",
"is_active": true
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string", "is_active": true},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string", "is_active": true})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"full_name": "string", "slug": "string", "avatar_url": "string", "bio": "string", "email": "string", "role": "author", "agent_type": "human", "country": "string", "city": "string", "is_active": true}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Author
Deactivate an author (soft-delete).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
author_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/authors/{author_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Tags
List all tags. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Tag
Create a new tag.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"slug": "string",
"description": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "slug": "string", "description": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "slug": "string", "description": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "slug": "string", "description": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Tag
Update a tag.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tag_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags/{tag_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"slug": "string",
"description": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags/{tag_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "slug": "string", "description": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags/{tag_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "slug": "string", "description": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "slug": "string", "description": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags/{tag_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Tag
Delete a tag.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
tag_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags/{tag_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags/{tag_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags/{tag_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/tags/{tag_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Categories
List blog categories. Use ?format=json|yaml|md|llm for agent-friendly responses.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
format | query | any | false | Response format. json (default) and llm return JSON; yaml returns text/yaml; md returns text/markdown. Any other value is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Category
Create a new category.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"slug": "string",
"description": "string",
"parent_id": "00000000-0000-0000-0000-000000000000",
"sort_order": 0
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Category
Update a category.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories/{category_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"slug": "string",
"description": "string",
"parent_id": "00000000-0000-0000-0000-000000000000",
"sort_order": 0
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories/{category_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories/{category_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "slug": "string", "description": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories/{category_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Category
Delete a category.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories/{category_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories/{category_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories/{category_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/categories/{category_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Docs Tree
Get full docs tree (including drafts).
Docs Platform v2 · 3.4 — ?version= scopes the editor tree to one docs version (omit → default). Response carries all versions (every status, for management) + the resolved current_version.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
version | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/tree' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/tree",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/tree", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/tree", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Docs
Flat list of docs (metadata only, no body) — complements GET /docs/tree.
Agents use this to discover a doc's UUID by title/status before fetching or mutating it via GET /docs/{doc_id}.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | any | false | Filter by status (draft / published / archived). |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Doc
Create a documentation page.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"agent_strategy": "string",
"agent_flow_id": "string",
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"parent_id": "00000000-0000-0000-0000-000000000000",
"slug": "string",
"title": "string",
"body": {},
"is_section": false,
"sort_order": 0,
"version": "default"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "body": {}, "is_section": false, "sort_order": 0, "version": "default"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "body": {}, "is_section": false, "sort_order": 0, "version": "default"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "body": {}, "is_section": false, "sort_order": 0, "version": "default"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Doc Versions
List the tenant's docs versions (all statuses, for management).
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Create Doc Version
Register a new docs version label. is_default demotes the prior default.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"label": "string",
"title": "string",
"is_default": false,
"sort_order": 0,
"status": "published"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"label": "string", "title": "string", "is_default": false, "sort_order": 0, "status": "published"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"label": "string", "title": "string", "is_default": false, "sort_order": 0, "status": "published"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"label": "string", "title": "string", "is_default": false, "sort_order": 0, "status": "published"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Doc Version
Update a docs version (title / order / status / default flag).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
version_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions/{version_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"title": "string",
"is_default": true,
"sort_order": 0,
"status": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions/{version_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"title": "string", "is_default": true, "sort_order": 0, "status": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions/{version_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"title": "string", "is_default": true, "sort_order": 0, "status": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"title": "string", "is_default": true, "sort_order": 0, "status": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions/{version_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Doc Version
Delete a docs version. Refuses the default version or one still in use.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
version_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions/{version_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions/{version_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions/{version_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/versions/{version_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Docs Analytics
Server-side docs analytics overview (views / searches / asks) for the tenant over the last days. Degrades to an empty rollup, never 500s.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
days | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/analytics' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/analytics",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/analytics", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/analytics", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Doc
Get a doc by ID (drafts included).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Doc
Update a doc (title, body, SEO, hierarchy). Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the update and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the update. |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"agent_strategy": "string",
"agent_flow_id": "string",
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"parent_id": "00000000-0000-0000-0000-000000000000",
"title": "string",
"body": {},
"is_section": true,
"sort_order": 0
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "title": "string", "body": {}, "is_section": true, "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "title": "string", "body": {}, "is_section": true, "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"agent_strategy": "string", "agent_flow_id": "string", "seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "parent_id": "00000000-0000-0000-0000-000000000000", "title": "string", "body": {}, "is_section": true, "sort_order": 0}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Doc
Archive a doc (soft delete). Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the delete. |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Duplicate Doc
Duplicate a doc page. Copy lives as a sibling of the original under the same parent_id with a fresh slug. Status: draft.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/duplicate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/duplicate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/duplicate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/duplicate", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Publish Doc
Publish a draft doc. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the publish. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/publish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/publish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/publish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/publish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unpublish Doc
Revert a doc to draft status. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the unpublish. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/unpublish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/unpublish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/unpublish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/unpublish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Doc
Self-contained doc export. Returns the doc row + site settings + domains.
Docs are prose-first, so there are no component bodies to inline (unlike page export). The doc must belong to the caller's client_id.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true | |
format | query | any | false | Response format. json (default) and llm return JSON; md returns text/markdown. This route has no YAML renderer, so yaml is a 422. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/export' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/export",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/export", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/export", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Import Doc Markdown
Import a doc from a Markdown body. Create a new doc (omit doc_id, provide slug + title) or replace an existing doc's body (set doc_id). :::component{...} directives become embedded component nodes.
Create delegates to create_doc (ungated); update delegates to the Phase 11+12 dry_run/confirm_token-gated update_doc.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12 (update path): preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12 (update path): consume a prior preview token and perform the update. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/import' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"markdown": "string",
"doc_id": "00000000-0000-0000-0000-000000000000",
"slug": "string",
"title": "string",
"parent_id": "00000000-0000-0000-0000-000000000000",
"is_section": true,
"sort_order": 0
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/import",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "doc_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "is_section": true, "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/import", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "doc_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "is_section": true, "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "doc_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "is_section": true, "sort_order": 0}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/import", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Import Openapi
Import an OpenAPI/Swagger spec into the docs tree. dry_run=true returns the planned section + pages without writing (powers the wizard preview); otherwise the reference is generated idempotently and (if publish) published.
Errors map to 422 (bad/oversized/unfetchable spec — message is client-safe) or 500 (logged, generic) — never leak the spec URL or upstream detail.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/import-openapi' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"source_url": "string",
"spec_content": "string",
"spec_format": "auto",
"section": "api-reference",
"publish": false,
"dry_run": false
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/import-openapi",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"source_url": "string", "spec_content": "string", "spec_format": "auto", "section": "api-reference", "publish": false, "dry_run": false},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/import-openapi", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"source_url": "string", "spec_content": "string", "spec_format": "auto", "section": "api-reference", "publish": false, "dry_run": false})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"source_url": "string", "spec_content": "string", "spec_format": "auto", "section": "api-reference", "publish": false, "dry_run": false}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/import-openapi", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Doc Markdown
Export a doc's body as pure Markdown (round-trips with POST /docs/import).
:::component{...} directives are preserved (render_tiptap_markdown emits them via serialize_component_node). The title is prepended as an H1. Distinct from /docs/{id}/export?format=md, which wraps the same body in a JSON envelope.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/markdown' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/markdown",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/markdown", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/markdown", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Import Page Markdown
Import a page from a Markdown body — the markdown→page converter. Create a new page (omit page_id, provide slug + title) or replace an existing page's blocks (set page_id). Prose runs become rich_text blocks; :::component{...} directives become component blocks.
Delegates to the Phase 11+12 dry_run/confirm_token-gated create_page / update_page (the converter handler only does the markdown→blocks mapping).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the create/update. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/import' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"seo_title": "string",
"seo_description": "string",
"og_title": "string",
"og_description": "string",
"og_image_url": "string",
"twitter_card": "string",
"twitter_image_url": "string",
"canonical_url": "string",
"robots": "string",
"keywords": "string",
"json_ld": {},
"markdown": "string",
"page_id": "00000000-0000-0000-0000-000000000000",
"slug": "string",
"title": "string",
"template": "string",
"parent_id": "00000000-0000-0000-0000-000000000000",
"sort_order": 0
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/import",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "page_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "template": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/import", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "page_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "template": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"seo_title": "string", "seo_description": "string", "og_title": "string", "og_description": "string", "og_image_url": "string", "twitter_card": "string", "twitter_image_url": "string", "canonical_url": "string", "robots": "string", "keywords": "string", "json_ld": {}, "markdown": "string", "page_id": "00000000-0000-0000-0000-000000000000", "slug": "string", "title": "string", "template": "string", "parent_id": "00000000-0000-0000-0000-000000000000", "sort_order": 0}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/import", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Page Markdown
Export a page's blocks as pure Markdown (round-trips with POST /pages/import).
Component blocks serialize to :::component{...} directives (the converter contract — render_page_markdown(serialize_components=True)). This differs from /pages/{id}/export?format=md, which renders each component as a labelled human-readable section inside a JSON envelope (not round-trippable).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/markdown' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/markdown",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/markdown", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/markdown", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reorder Docs
Reorder documentation tree.
Try it
Examples
cURL
curl -X PUT 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/reorder' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"items": [
{}
]
}'Python
import httpx
resp = httpx.put(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/reorder",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"items": [{}]},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/reorder", {
method: "PUT",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"items": [{}]})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"items": [{}]}`)
req, _ := http.NewRequest("PUT", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/reorder", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Navigation
Get navigation menu.
D4 — the editor reads the RAW menu (expand=False, the service default). A folder-bound item must round-trip as its BINDING; expanding here would make the next save bake a frozen snapshot of the page tree into the JSONB.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
location | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/navigation/{location}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/navigation/{location}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/navigation/{location}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/navigation/{location}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Navigation
Update navigation menu.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
location | path | string | true |
Try it
Examples
cURL
curl -X PUT 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/navigation/{location}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"items": [
{
"label": "string",
"url": "string",
"icon": "string",
"children": [],
"is_external": false,
"badge": "string",
"source": {
"kind": "site",
"folder_id": {},
"depth": 2
}
}
]
}'Python
import httpx
resp = httpx.put(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/navigation/{location}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"items": [{"label": "string", "url": "string", "icon": "string", "children": [], "is_external": false, "badge": "string", "source": {"kind": "site", "folder_id": {}, "depth": 2}}]},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/navigation/{location}", {
method: "PUT",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"items": [{"label": "string", "url": "string", "icon": "string", "children": [], "is_external": false, "badge": "string", "source": {"kind": "site", "folder_id": {}, "depth": 2}}]})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"items": [{"label": "string", "url": "string", "icon": "string", "children": [], "is_external": false, "badge": "string", "source": {"kind": "site", "folder_id": {}, "depth": 2}}]}`)
req, _ := http.NewRequest("PUT", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/navigation/{location}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash List Directory Categories
List all directory categories for this client (includes drafts/empty ones).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Create Directory Category
Create a directory category.
Body: {name, slug?, description?, icon?, seo_title_template?, seo_description_template?, template?, data_source?, sort_order?}
seo_*_template strings accept {category}, {city}, {listing} placeholders — rendered server-side on the public read endpoints.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Dash Get Directory Category
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Update Directory Category
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Delete Directory Category
Delete a category (cascades to its listings).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Bulk Upsert Listings
Bulk upsert listings. Body: {listings: [{name, slug?, city, state?, ...}, ...]}.
Upsert semantics: slug unique per category. Missing slug auto-generated from name. Refreshes the materialized view + category counts on success.
Typical use: agent dumps the results of a SpiderMaps campaign into a category via a single call. Supports source_job_id so listings can be traced back to the job that produced them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings/bulk' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings/bulk",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings/bulk", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings/bulk", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash List Directory Listings
List listings across categories. Filters: category_slug, city, status.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | query | any | false | |
city | query | any | false | |
status | query | string | false | |
page | query | integer | false | |
page_size | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/listings' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/listings",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/listings", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/listings", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Upsert Listing
Create or update a single listing in a category. Slug-based upsert.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Dash Delete Listing
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true | |
listing_slug | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings/{listing_slug}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings/{listing_slug}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings/{listing_slug}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/listings/{listing_slug}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Import From Idap
Populate a directory category from the tenant's IDAP data (norm_cli_*.businesses).
One call replaces the "run SpiderMaps → transform results → bulk_upsert" loop. The norm_cli_* schema is already the canonical store for every business SpiderIQ has seen for this tenant — this reads directly from it.
Every column the IDAP column manifest declares reaches the listing — typed columns land in typed columns, the rest land in the data jsonb under their frozen public field id.
Body (all optional): {category_filter: "Plumber", country_code: "US", city: "Miami", rating_min: 4.0, limit: 5000, prune: false}
prune: true ARCHIVES (never deletes) listings in this category whose source row no longer matches the filter — that is what makes a re-import honest, since the upsert is keyed on (category, slug) and a business deleted or renamed in IDAP otherwise leaves a stale published listing forever. It is OFF by default, and it refuses to run when the import hit its limit (a truncated result set cannot tell "gone" from "on the next page") — the refusal comes back as prune_skipped_reason.
Returns {upserted, inserted, updated, pruned, failed, source_rows, affected_cities, source_schema, fields_mapped, filter, sync_log_id, ...}.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category_slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/import-from-idap' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/import-from-idap",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/import-from-idap", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/categories/{category_slug}/import-from-idap", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Dash Refresh Directory Stats
Manually refresh the city_stats materialized view. Normally auto-refreshed on bulk upsert.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/refresh-stats' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/refresh-stats",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/refresh-stats", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/directory/refresh-stats", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
List Media
List media files for the current client, newest first.
Filters: folder (exact match), mime_type (prefix match — image/ catches all image MIME types).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
folder | query | any | false | |
mime_type | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Upload Media
Upload an image to Cloudflare R2.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"file": "string",
"folder": "/",
"alt_text": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"file": "string", "folder": "/", "alt_text": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"file": "string", "folder": "/", "alt_text": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"file": "string", "folder": "/", "alt_text": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Upload Media From Url
Host a remote image URL on Cloudflare R2 — the agent-callable, JSON-only twin of POST /media/upload.
Agents reaching the content platform via skill_call can't send multipart, and a generated hero image lives at a provider URL (kie.* etc.) that the cover_image_url allowlist rejects. This fetches the URL SSRF-safely and runs the same validate → WebP-transcode → R2 → content_media → catalog pipeline as /media/upload; the returned media.r2_url is on our allowlisted host, so it then passes straight into createPost / content_update_page with no allowlist change.
201 + {success, media, asset}. A bad/unreachable URL or non-image body is a 400; an oversized body (>5 MB) is a 413.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload-from-url' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"media_url": "string",
"folder": "/",
"alt_text": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload-from-url",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"media_url": "string", "folder": "/", "alt_text": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload-from-url", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"media_url": "string", "folder": "/", "alt_text": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"media_url": "string", "folder": "/", "alt_text": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload-from-url", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Upload Media Batch
Upload one or many files to SpiderMedia (SeaweedFS).
Weight policy — scroll-sequence folders (scroll-sequences/* or is_scroll_sequence=true): 500 KB per-file hard, 20 MB batch total hard, 200 KB / 10 MB soft warnings. Everything else: 20 MB per-file (500 MB for video/*), 500 MB batch total. Hard ceilings return 400 with the offending file(s); soft warnings come back in warnings[] with the upload succeeding.
Returns {uploaded: [...], failed: [...], warnings: [...], totals}.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload-batch' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"files": [
"string"
],
"folder": "string",
"preserve_filename": false,
"is_scroll_sequence": false
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload-batch",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"files": ["string"], "folder": "string", "preserve_filename": false, "is_scroll_sequence": false},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload-batch", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"files": ["string"], "folder": "string", "preserve_filename": false, "is_scroll_sequence": false})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"files": ["string"], "folder": "string", "preserve_filename": false, "is_scroll_sequence": false}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/upload-batch", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Update Media
Update a legacy R2 media file's metadata (folder / alt_text / caption).
Targets the content_media table (the dashboard R2 uploader surface), NOT the per-tenant media_assets catalog. True PATCH — only supplied fields change. 200 + the updated row; 404 if no such media for this client.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
media_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/{media_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"folder": "string",
"alt_text": "string",
"caption": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/{media_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"folder": "string", "alt_text": "string", "caption": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/{media_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"folder": "string", "alt_text": "string", "caption": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"folder": "string", "alt_text": "string", "caption": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/{media_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Media
Delete a legacy R2 media file (content_media row + best-effort R2 object cleanup). 204 on success, 404 if no such media for this client.
The DB row delete is authoritative; the R2 object removal is best-effort and non-blocking — an orphaned R2 object never fails the request (the row is already gone, so the asset no longer appears in the library).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
media_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/{media_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/{media_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/{media_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/media/{media_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
204 | Successful Response |
422 | Validation Error |
Get Settings
Get content settings.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/settings' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/settings",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/settings", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/settings", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Update Settings
Update content settings. Phase 11+12 dry_run/confirm_token gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: preview the change and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the update. |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/settings' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"site_name": "string",
"site_tagline": "string",
"favicon_url": "string",
"primary_color": "string",
"surface_color": "string",
"surface_elevated_color": "string",
"subtle_color": "string",
"body_text_color": "string",
"heading_color": "string",
"logo_dark_url": "string",
"logo_light_url": "string",
"copyright_text": "string",
"social_links": {},
"google_analytics_id": "string",
"plausible_domain": "string",
"default_meta_title": "string",
"default_meta_description": "string",
"default_og_image_url": "string",
"default_seo_title_suffix": "string",
"default_agent_strategy": "string"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/settings",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"site_name": "string", "site_tagline": "string", "favicon_url": "string", "primary_color": "string", "surface_color": "string", "surface_elevated_color": "string", "subtle_color": "string", "body_text_color": "string", "heading_color": "string", "logo_dark_url": "string", "logo_light_url": "string", "copyright_text": "string", "social_links": {}, "google_analytics_id": "string", "plausible_domain": "string", "default_meta_title": "string", "default_meta_description": "string", "default_og_image_url": "string", "default_seo_title_suffix": "string", "default_agent_strategy": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/settings", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"site_name": "string", "site_tagline": "string", "favicon_url": "string", "primary_color": "string", "surface_color": "string", "surface_elevated_color": "string", "subtle_color": "string", "body_text_color": "string", "heading_color": "string", "logo_dark_url": "string", "logo_light_url": "string", "copyright_text": "string", "social_links": {}, "google_analytics_id": "string", "plausible_domain": "string", "default_meta_title": "string", "default_meta_description": "string", "default_og_image_url": "string", "default_seo_title_suffix": "string", "default_agent_strategy": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"site_name": "string", "site_tagline": "string", "favicon_url": "string", "primary_color": "string", "surface_color": "string", "surface_elevated_color": "string", "subtle_color": "string", "body_text_color": "string", "heading_color": "string", "logo_dark_url": "string", "logo_light_url": "string", "copyright_text": "string", "social_links": {}, "google_analytics_id": "string", "plausible_domain": "string", "default_meta_title": "string", "default_meta_description": "string", "default_og_image_url": "string", "default_seo_title_suffix": "string", "default_agent_strategy": "string"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/settings", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Redirects
List all redirects.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Create Redirect
Create a redirect.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"from_path": "string",
"to_path": "string",
"status_code": 301
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"from_path": "string", "to_path": "string", "status_code": 301},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"from_path": "string", "to_path": "string", "status_code": 301})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"from_path": "string", "to_path": "string", "status_code": 301}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Redirect
Delete a redirect.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
redirect_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects/{redirect_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects/{redirect_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects/{redirect_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/redirects/{redirect_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Domains
List all custom domains for this client plus the auto-provisioned platform preview URL when the client has ever deployed.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Add Domain
Register a new custom domain.
Drives BOTH Cloudflare onboarding paths and surfaces the outcome of each so the dashboard can render an actionable banner instead of silently masking failures:
- CF for SaaS custom hostname — for domains whose zone is NOT in our CF account. The client adds a CNAME to the fallback origin and CF handles SSL + dispatch.
- Worker Route on the domain's own zone — for domains whose zone IS in our CF account (incl. subdomains of zones we own). Without this, KV mappings exist but CF returns 522 because no Worker handles the inbound request.
Each helper detects which path it owns and no-ops on the other (see register_custom_hostname skipping in-account zones, and ensure_worker_route skipping zones in other accounts). Both are called unconditionally; their structured return values populate worker_route_status and custom_hostname_status on the response.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"domain": "acme.com"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"domain": "acme.com"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"domain": "acme.com"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"domain": "acme.com"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Add Subdomain
Register a free {label}.sites.spideriq.ai subdomain.
The zero-cost counterpart to add_domain: sites.spideriq.ai is a zone we own with a wildcard Worker Route already configured, so this path makes NO Cloudflare custom-hostname call and needs NO DNS verification — it writes the DOMAIN_MAP KV entry and the dispatch Worker routes the hostname to the client's tenant script. Available on every tier; the free tier's single slot is one of these.
Counts against the same max_domains quota as a custom domain.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/subdomain' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"label": "acme"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/subdomain",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"label": "acme"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/subdomain", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"label": "acme"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"label": "acme"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/subdomain", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Check Subdomain Availability
Check whether a {label}.sites.spideriq.ai subdomain is free.
Powers the live availability check in the dashboard subdomain editor. Returns {available, host, reason}. available=false with a reason when the label is malformed; otherwise reflects global host uniqueness (content_domains.domain is globally unique).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
label | query | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/subdomain/availability' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/subdomain/availability",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/subdomain/availability", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/subdomain/availability", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Domain
Update a domain (SD1): set its start page and/or rename the host.
A rename remaps Cloudflare so the new host serves the same tenant site — the new DOMAIN_MAP KV entry (and, for an out-of-account custom domain, a fresh custom hostname + Worker Route) is created and the old host's mapping is torn down. Subdomains on *.sites.spideriq.ai route via the existing wildcard, so they only need the KV swap. The change goes live on the next deploy.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"homepage_slug": "promo",
"new_domain": "go.acme.com"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"homepage_slug": "promo", "new_domain": "go.acme.com"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"homepage_slug": "promo", "new_domain": "go.acme.com"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"homepage_slug": "promo", "new_domain": "go.acme.com"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Remove Domain
Remove a custom domain.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Verify Domain
Verify a domain (checks DNS TXT record).
Surfaces needs_deploy=True when the client has no live deploy yet so the dashboard can prompt "Click to deploy your site" — without that, a freshly verified domain will return CF 522 because the per-client tenant Worker script doesn't exist in the dispatch namespace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/verify' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/verify",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/verify", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/verify", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Recheck Domain Ssl
Re-query Cloudflare for this domain's live SSL state and persist it.
The on-demand, customer-triggered counterpart to the background reconciliation poll: powers the dashboard "Re-check" button so a customer who just fixed their DNS doesn't have to wait for the next poll tick. Does exactly ONE Cloudflare custom-hostname read for the one domain (not a fan-out over the whole list — that stays cheap and rate-limit-safe), maps the CF SSL lifecycle onto our ssl_status enum, and returns the refreshed row with the live CF status echoed in custom_hostname_status.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/recheck' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/recheck",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/recheck", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/recheck", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Set Primary Domain
Set a domain as the primary domain for this client.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/primary' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/primary",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/primary", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/primary", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Domain Project
Move a domain to a different project (website) in the same workspace.
Projects 4a migration helper: every existing domain was backfilled to the workspace DEFAULT project, so a multi-project workspace needs this to assign a domain to its real website (e.g. docs.example.com → the docs project). Workspace-scoped on purpose — the move targets a domain regardless of the currently-selected project, because the point is to move it OUT of its current one. The target project is validated to belong to this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
domain | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/domains/{domain}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Page Project
Move a page (and its folder subtree) to another project in this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/pages/{page_id}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Post Project
Move a blog post to another project in this workspace (clears project-scoped categories/tags/relationships; free-text tags + pins ride along).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
post_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/posts/{post_id}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Doc Project
Move a doc (and its subtree) to another project in this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
doc_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/docs/{doc_id}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Reassign Changelog Project
Move a changelog entry to another project in this workspace.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/reassign-project' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"project_id": "proj_6c76213060eb"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/reassign-project",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"project_id": "proj_6c76213060eb"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/reassign-project", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"project_id": "proj_6c76213060eb"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"project_id": "proj_6c76213060eb"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/reassign-project", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Deploy Site
Deploy the client's tenant site to Workers for Platforms.
Phase 11+12: pass dry_run=true to receive a preview URL and confirm_token without deploying; pass confirm_token=<cft_…> to consume the prior preview and deploy to production. Calls without either flag keep today's immediate behaviour (back-compat until Stage 4 rollout flips the default).
domain=<host> (Bug #4) scopes which of the workspace's domains get their CF DOMAIN_MAP entry + Worker Route refreshed, so a deploy no longer silently re-touches a sibling domain's routing. Unknown host → 400.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
dry_run | query | boolean | false | Phase 11+12: issue a preview + confirm_token without deploying. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and deploy to production. |
domain | query | any | false | Bug #4: scope the DOMAIN_MAP/route fan-out to a single host of this workspace (else all of the active project's domains). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Deploy Site Preview
Phase 11+12 Stage 2 — issue a preview URL + confirm_token for the proposed deploy. No CF production script upload, no DNS flip. Caller reviews the preview, then calls POST /deploy/production with the confirm_token to actually deploy.
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/preview' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/preview",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/preview", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Deploy Site Production
Phase 11+12 Stage 2 — consume a prior preview's confirm_token (Lock 4) and run the real deploy. 403 on tenant/action/resource mismatch, 410 on expired, 409 on already-consumed replay.
domain=<host> (Bug #4) scopes the routing fan-out to a single host.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
confirm_token | query | string | true | Token from a prior /deploy/preview call. |
domain | query | any | false | Bug #4: scope the DOMAIN_MAP/route fan-out to a single host of this workspace (else all of the active project's domains). |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/production' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/production",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/production", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/production", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Deploy Status
Get the most recent deploy status for this client.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/status' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/status",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/status", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/status", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
List Deploys
List recent deploys for this client.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/history' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/history",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/history", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/history", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Deploy Readiness
Check if this client's site is ready to deploy.
Returns a checklist of prerequisites (settings, domain, templates, pages) with pass/fail status and actionable fix instructions. Blocking items prevent deploy; warnings are advisory.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/readiness' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/readiness",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/readiness", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/readiness", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Get Deploy Detail
Full detail for a single deploy — backs the per-deploy detail page.
Client-scoped: returns 404 if the deploy doesn't exist OR belongs to a different tenant (no cross-tenant leakage). Computes duration_ms from deployed_at − created_at. Declared AFTER the static /deploy/* routes so {deploy_id} never shadows status/history/readiness.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
deploy_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/{deploy_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/{deploy_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/{deploy_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/deploy/{deploy_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
List Changelog
List changelog entries (newest first).
Drafts are included for the editor surface. Paginated — the public feed + timeline read the same service method with include_drafts=False.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
status | query | any | false | Filter by status (draft / published / archived). |
page | query | any | false | 1-based page number (house pattern; wins over limit/offset). |
page_size | query | any | false | Entries per page (1-200, default 50). |
limit | query | any | false | Legacy alias for page_size. Kept for back-compat. |
offset | query | any | false | Legacy alias — raw row offset. Kept for back-compat. |
sort | query | string | false | Ordering, newest first. published_at (default) = release date. version = semver compared NUMERICALLY per component, so v2.10.0 sorts above v2.9.0 — use it when the entries were backfilled and their timestamps don't reflect true release order. |
include_body | query | boolean | false | Include each entry's full Tiptap body. Pass false for a light index (id/version/title/status/dates) — 25 entries with bodies is ~128k chars, which blows an agent's tool-output ceiling. Fetch a single body with GET /changelog/{entry_id}. Defaults true so the dashboard editor keeps its one-shot list→edit flow. |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Create Changelog
Create a draft changelog entry (409 on a duplicate version).
published_at is optional and does NOT publish the entry — it pre-stamps the release date so a backfilled history lands in true order on the public timeline (which is ordered by date, never by version string).
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"version": "string",
"title": "string",
"body": {},
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
201 | Successful Response |
422 | Validation Error |
Get Changelog
Get one changelog entry by ID (drafts included).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Update Changelog
Update a changelog entry's title/body (version is immutable post-create only via this route's schema; pass it through update_changelog if needed).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X PATCH 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"version": "string",
"title": "string",
"body": {},
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"version": "string", "title": "string", "body": {}, "published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Delete Changelog
Soft-delete a changelog entry (status → archived). Returns 204.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X DELETE 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}", {
method: "DELETE",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("DELETE", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Publish Changelog
Publish a changelog entry (fires changelog.published on first publish).
The body is OPTIONAL — with none, the entry is stamped NOW() exactly as before. Send {"published_at": "..."} to publish a historical entry with its real release date; it wins over any date already on the entry.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/publish' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"published_at": "2026-01-01T00:00:00Z"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/publish",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"published_at": "2026-01-01T00:00:00Z"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/publish", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"published_at": "2026-01-01T00:00:00Z"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"published_at": "2026-01-01T00:00:00Z"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/publish", body)
req.Header.Set("Authorization", "Bearer <token>")
req.Header.Set("Content-Type", "application/json")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Unpublish Changelog
Revert a changelog entry to draft.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entry_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/unpublish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/unpublish",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/unpublish", {
method: "POST",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/changelog/{entry_id}/unpublish", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Audit Internal Links
Walk every published page's blocks + navigation menus and validate internal links against the published-page roster + active redirects.
Returns {valid_count, broken: [{path, source, reason}], proposed_redirects, known_redirects}.
Fixes the Unavis-report pain: cleaning up /en/* legacy URLs across nav + blocks used to require manual crawling. One call surfaces every broken link with its exact source so agents can propose redirects in a single pass.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/audit/links' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/audit/links",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/audit/links", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/audit/links", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |