Content Studio - Components
30 endpoints from the published OpenAPI import.
List Components
List components for the current client. Supports filtering by category, marketplace_category, status, and the universal browse-by-intent axes (mood / palette / brand_fit / scene_type) plus agent_meta role/surface.
Audit nav-shell page-07 Q4 (2026-05-05): super_admin can call this without selecting a tenant scope — the dependency returns user.client_id=None, and the service treats None as "admin view" (no client_id filter, returns global rows + every per-tenant copy across all clients).
CRO bug-fix bundle (2026-05-08, Antigravity report Bug 3): the service layer has supported marketplace_category filtering since Phase A, but the API layer wasn't forwarding the query param — ?marketplace_category=... was silently ignored. Agent Embed M3 (2026-06-27) extends the same wiring to the universal axes + agent_meta role/surface so agents are browsable by intent.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category | query | any | false | Filter by category |
marketplace_category | query | any | false | Filter by marketplace_category (e.g. 'urgency-scarcity', 'capture-popups', 'social-proof', 'agent') |
status | query | any | false | Filter by status (draft/published/archived) |
include_global | query | boolean | false | Include system (global) components |
mood | query | any | false | Universal mood axis — repeatable (?mood=calm&mood=warm). OR-match (overlap). |
palette | query | any | false | Universal palette axis — repeatable. OR-match (overlap). |
brand_fit | query | any | false | Universal brand-fit/industry axis — repeatable (?brand_fit=wellness). OR-match. |
scene_type | query | any | false | Universal scene_type axis — single value, equality. |
agent_role | query | any | false | agent_meta.role for marketplace_category='agent' listings (sdr|support|concierge|booking). |
agent_surface | query | any | false | agent_meta.surface for agent listings (flow|inline|concierge). |
agent_form_factor | query | any | false | agent_meta.form_factor mount taxonomy for agent listings (section|widget|concierge|headless). |
page | query | integer | false | |
page_size | query | integer | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/components' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/components",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components", {
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/components", 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 Component
Create a new UI component. 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/components' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"slug": "string",
"name": "string",
"description": "string",
"version": "1.0.0",
"category": "custom",
"html_template": "string",
"css": "string",
"js": "string",
"dependencies": [
"string"
],
"props_schema": {},
"default_props": {},
"thumbnail_url": "string",
"tags": [
"string"
],
"is_global": false,
"framework": "string",
"source_code": "string",
"auto_extract_css": false,
"preview_thumbnail_url": "string",
"replication_prompt": "string",
"marketplace_category": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/components",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"slug": "string", "name": "string", "description": "string", "version": "1.0.0", "category": "custom", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "is_global": false, "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"slug": "string", "name": "string", "description": "string", "version": "1.0.0", "category": "custom", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "is_global": false, "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"slug": "string", "name": "string", "description": "string", "version": "1.0.0", "category": "custom", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "is_global": false, "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/components", 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 Component By Slug
Get a component by slug. Returns latest published version if no version specified.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | true | |
version | query | any | false | Specific version (default: latest) |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/components/by-slug/{slug}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/components/by-slug/{slug}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/by-slug/{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/components/by-slug/{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 |
Get Component
Get a component by ID.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/components/{component_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{component_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/components/{component_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 Component
Update a component. Only provided fields are changed. Phase 11+12 dry_run/confirm_token gated.
Unknown fields in the request body are ignored (Pydantic default) but surfaced in the response's warnings array with a "Did you mean X?" hint when a close field name exists. This catches css_styles (should be css) silent-drops.
Phase E (2026-05-05) — accepts Phase A 4-class taxonomy (kind, block_type, js_runtime, layouts, sources, extension_spec) + agent-discovery axes (mood, palette, brand_fit_tags, scene_type, agent_meta). Strict enum validation at the boundary; cross-field invariants are backstopped by DB CHECK constraints (migration 174).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_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/components/{component_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"description": "string",
"category": "hero",
"html_template": "string",
"css": "string",
"js": "string",
"dependencies": [
"string"
],
"props_schema": {},
"default_props": {},
"thumbnail_url": "string",
"tags": [
"string"
],
"framework": "string",
"source_code": "string",
"auto_extract_css": false,
"preview_thumbnail_url": "string",
"replication_prompt": "string",
"marketplace_category": "string",
"marketplace_featured": true,
"marketplace_description": "string",
"kind": "static"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "description": "string", "category": "hero", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string", "marketplace_featured": true, "marketplace_description": "string", "kind": "static"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{component_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "description": "string", "category": "hero", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string", "marketplace_featured": true, "marketplace_description": "string", "kind": "static"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "description": "string", "category": "hero", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string", "marketplace_featured": true, "marketplace_description": "string", "kind": "static"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/content/components/{component_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 |
400 | DB CHECK constraint violation (e.g. PATCH leaves row with kind='dynamic' but block_type=NULL — Phase A invariant in migration 174). |
403 | Cannot edit a global component you don't own; or confirm_token mismatch (Phase 11+12). |
404 | Component not found. |
409 | confirm_token already consumed (Phase 11+12). |
410 | confirm_token expired (Phase 11+12). |
422 | Body failed validation: unknown enum (kind/block_type/js_runtime/scene_type/mood/brand_fit_tag), agent_meta with unknown key (extra='forbid'), invalid Literal (interaction_pattern, trigger_kind), or layouts/sources length cap. |
Delete Component
Delete a component. Only the owning client can delete (not global components). Phase 11+12 gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_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/components/{component_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{component_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/components/{component_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 |
Preview Component
Render a single component in isolation for dashboard iframe preview.
Closes the BrokerZ-report pain: Shadow DOM layout issues were only visible after a full site preview deploy (~60-90 seconds). This endpoint returns the component's html_template + css + js + merged props so the dashboard can iframe-srcdoc it instantly for quick styling checks.
Note: v1 returns the raw html_template — Liquid {{ props.x }} tokens are NOT interpolated here (the Liquid runtime lives in the Worker bundle). The response exposes merged_props so the dashboard's own renderer can interpolate client-side if needed. Full-fidelity preview still ships via the existing /deploy/preview flow.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/preview' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"props": {},
"viewport": "desktop"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/preview",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"props": {}, "viewport": "desktop"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"props": {}, "viewport": "desktop"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"props": {}, "viewport": "desktop"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/components/{component_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 |
Upload Component Preview
Upload a preview image (PNG/JPG/GIF/WEBP/MP4) for a component to R2 at components/<slug>.<ext>, then PATCH preview_thumbnail_url on the row.
Single round-trip — the editor doesn't need a separate PATCH after upload.
Phase E (2026-05-05) — Content-Type and magic-number are now validated alongside the extension. Capped at 5 MB; for larger assets, use the SpiderMedia /files/upload endpoint and reference the URL via PATCH.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/upload-preview' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"ext": "string",
"file": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/upload-preview",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"ext": "string", "file": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/upload-preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"ext": "string", "file": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"ext": "string", "file": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/upload-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 |
413 | Upload exceeds 5 MB size limit. Use SpiderMedia for larger assets. |
415 | Unsupported extension, Content-Type/extension mismatch, or magic-number mismatch. |
422 | Validation Error |
Publish Component
Publish a component (makes it available for rendering on live sites). For framework components (Tier 4), returns 202 — build runs async. Phase 11+12 gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the publish 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/components/{component_id}/publish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_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/components/{component_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/components/{component_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 |
Archive Component
Archive a component (removes from rendering but preserves data). Phase 11+12 gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the archive and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the archive. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/archive' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/archive",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/archive", {
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/components/{component_id}/archive", 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 Build Status
Get the build status of a framework component (Tier 4).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/build-status' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/build-status",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/build-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/components/{component_id}/build-status", 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 |
Rebuild Component
Trigger a rebuild for a framework component (Tier 4). Returns 202.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/rebuild' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/rebuild",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{component_id}/rebuild", {
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/components/{component_id}/rebuild", 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 Component Versions
List all versions of a component by slug.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/content/components/{slug}/versions' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/content/components/{slug}/versions",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{slug}/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/components/{slug}/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 |
Component Rollback
Restore a component to an earlier version by creating a new published version with the target version's content, and repointing consuming pages.
One confirm_token covers the whole rollback. Gate action is component_rollback (distinct from component_update_and_propagate), so a forward-update token can't accidentally be consumed against this path.
Never auto-deploys the tenant KV. Block-level updates render live on next request.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/components/{slug}/rollback' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"target_version": "string",
"bump": "patch",
"pages": [
"string"
],
"dry_run": false,
"confirm_token": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/components/{slug}/rollback",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"target_version": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{slug}/rollback", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"target_version": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"target_version": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/components/{slug}/rollback", 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 |
Component Update And Propagate
One-shot: bump a component to a new version AND propagate the pin to every (or selected) consuming page, gated by a single confirm_token.
Replaces the 5-step agent choreography (PATCH component → iterate pages → update block versions → publish each → deploy) with one call.
Never auto-deploys. The new component version is published and each affected page's blocks are updated in-place; block-level content renders live via the content API on next request. If you also changed templates or theme, run deploy_site_preview → deploy_site_production as usual.
Phase 11+12 Lock 4. A single confirm_token covers the whole composite mutation (component + all affected pages). Issue with dry_run=true, inspect the affected_pages preview, then send the token back on the real call.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/content/components/{slug}/update-and-propagate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"html_template": "string",
"css": "string",
"js": "string",
"props_schema": {},
"default_props": {},
"dependencies": [
"string"
],
"name": "string",
"description": "string",
"bump": "patch",
"pages": [
"string"
],
"dry_run": false,
"confirm_token": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/content/components/{slug}/update-and-propagate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"html_template": "string", "css": "string", "js": "string", "props_schema": {}, "default_props": {}, "dependencies": ["string"], "name": "string", "description": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/content/components/{slug}/update-and-propagate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"html_template": "string", "css": "string", "js": "string", "props_schema": {}, "default_props": {}, "dependencies": ["string"], "name": "string", "description": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"html_template": "string", "css": "string", "js": "string", "props_schema": {}, "default_props": {}, "dependencies": ["string"], "name": "string", "description": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/content/components/{slug}/update-and-propagate", 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 Components
List components for the current client. Supports filtering by category, marketplace_category, status, and the universal browse-by-intent axes (mood / palette / brand_fit / scene_type) plus agent_meta role/surface.
Audit nav-shell page-07 Q4 (2026-05-05): super_admin can call this without selecting a tenant scope — the dependency returns user.client_id=None, and the service treats None as "admin view" (no client_id filter, returns global rows + every per-tenant copy across all clients).
CRO bug-fix bundle (2026-05-08, Antigravity report Bug 3): the service layer has supported marketplace_category filtering since Phase A, but the API layer wasn't forwarding the query param — ?marketplace_category=... was silently ignored. Agent Embed M3 (2026-06-27) extends the same wiring to the universal axes + agent_meta role/surface so agents are browsable by intent.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
category | query | any | false | Filter by category |
marketplace_category | query | any | false | Filter by marketplace_category (e.g. 'urgency-scarcity', 'capture-popups', 'social-proof', 'agent') |
status | query | any | false | Filter by status (draft/published/archived) |
include_global | query | boolean | false | Include system (global) components |
mood | query | any | false | Universal mood axis — repeatable (?mood=calm&mood=warm). OR-match (overlap). |
palette | query | any | false | Universal palette axis — repeatable. OR-match (overlap). |
brand_fit | query | any | false | Universal brand-fit/industry axis — repeatable (?brand_fit=wellness). OR-match. |
scene_type | query | any | false | Universal scene_type axis — single value, equality. |
agent_role | query | any | false | agent_meta.role for marketplace_category='agent' listings (sdr|support|concierge|booking). |
agent_surface | query | any | false | agent_meta.surface for agent listings (flow|inline|concierge). |
agent_form_factor | query | any | false | agent_meta.form_factor mount taxonomy for agent listings (section|widget|concierge|headless). |
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/components' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components",
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/components", {
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/components", 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 Component
Create a new UI component. 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/components' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"slug": "string",
"name": "string",
"description": "string",
"version": "1.0.0",
"category": "custom",
"html_template": "string",
"css": "string",
"js": "string",
"dependencies": [
"string"
],
"props_schema": {},
"default_props": {},
"thumbnail_url": "string",
"tags": [
"string"
],
"is_global": false,
"framework": "string",
"source_code": "string",
"auto_extract_css": false,
"preview_thumbnail_url": "string",
"replication_prompt": "string",
"marketplace_category": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"slug": "string", "name": "string", "description": "string", "version": "1.0.0", "category": "custom", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "is_global": false, "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"slug": "string", "name": "string", "description": "string", "version": "1.0.0", "category": "custom", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "is_global": false, "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"slug": "string", "name": "string", "description": "string", "version": "1.0.0", "category": "custom", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "is_global": false, "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components", 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 Component By Slug
Get a component by slug. Returns latest published version if no version specified.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | true | |
version | query | any | false | Specific version (default: latest) |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/by-slug/{slug}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/by-slug/{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/components/by-slug/{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/components/by-slug/{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 |
Get Component
Get a component by ID.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_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/components/{component_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/components/{component_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 Component
Update a component. Only provided fields are changed. Phase 11+12 dry_run/confirm_token gated.
Unknown fields in the request body are ignored (Pydantic default) but surfaced in the response's warnings array with a "Did you mean X?" hint when a close field name exists. This catches css_styles (should be css) silent-drops.
Phase E (2026-05-05) — accepts Phase A 4-class taxonomy (kind, block_type, js_runtime, layouts, sources, extension_spec) + agent-discovery axes (mood, palette, brand_fit_tags, scene_type, agent_meta). Strict enum validation at the boundary; cross-field invariants are backstopped by DB CHECK constraints (migration 174).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_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/components/{component_id}' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"name": "string",
"description": "string",
"category": "hero",
"html_template": "string",
"css": "string",
"js": "string",
"dependencies": [
"string"
],
"props_schema": {},
"default_props": {},
"thumbnail_url": "string",
"tags": [
"string"
],
"framework": "string",
"source_code": "string",
"auto_extract_css": false,
"preview_thumbnail_url": "string",
"replication_prompt": "string",
"marketplace_category": "string",
"marketplace_featured": true,
"marketplace_description": "string",
"kind": "static"
}'Python
import httpx
resp = httpx.patch(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"name": "string", "description": "string", "category": "hero", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string", "marketplace_featured": true, "marketplace_description": "string", "kind": "static"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}", {
method: "PATCH",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"name": "string", "description": "string", "category": "hero", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string", "marketplace_featured": true, "marketplace_description": "string", "kind": "static"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"name": "string", "description": "string", "category": "hero", "html_template": "string", "css": "string", "js": "string", "dependencies": ["string"], "props_schema": {}, "default_props": {}, "thumbnail_url": "string", "tags": ["string"], "framework": "string", "source_code": "string", "auto_extract_css": false, "preview_thumbnail_url": "string", "replication_prompt": "string", "marketplace_category": "string", "marketplace_featured": true, "marketplace_description": "string", "kind": "static"}`)
req, _ := http.NewRequest("PATCH", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_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 |
400 | DB CHECK constraint violation (e.g. PATCH leaves row with kind='dynamic' but block_type=NULL — Phase A invariant in migration 174). |
403 | Cannot edit a global component you don't own; or confirm_token mismatch (Phase 11+12). |
404 | Component not found. |
409 | confirm_token already consumed (Phase 11+12). |
410 | confirm_token expired (Phase 11+12). |
422 | Body failed validation: unknown enum (kind/block_type/js_runtime/scene_type/mood/brand_fit_tag), agent_meta with unknown key (extra='forbid'), invalid Literal (interaction_pattern, trigger_kind), or layouts/sources length cap. |
Delete Component
Delete a component. Only the owning client can delete (not global components). Phase 11+12 gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_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/components/{component_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.delete(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_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/components/{component_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/components/{component_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 |
Preview Component
Render a single component in isolation for dashboard iframe preview.
Closes the BrokerZ-report pain: Shadow DOM layout issues were only visible after a full site preview deploy (~60-90 seconds). This endpoint returns the component's html_template + css + js + merged props so the dashboard can iframe-srcdoc it instantly for quick styling checks.
Note: v1 returns the raw html_template — Liquid {{ props.x }} tokens are NOT interpolated here (the Liquid runtime lives in the Worker bundle). The response exposes merged_props so the dashboard's own renderer can interpolate client-side if needed. Full-fidelity preview still ships via the existing /deploy/preview flow.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/preview' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"props": {},
"viewport": "desktop"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/preview",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"props": {}, "viewport": "desktop"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"props": {}, "viewport": "desktop"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"props": {}, "viewport": "desktop"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_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 |
Upload Component Preview
Upload a preview image (PNG/JPG/GIF/WEBP/MP4) for a component to R2 at components/<slug>.<ext>, then PATCH preview_thumbnail_url on the row.
Single round-trip — the editor doesn't need a separate PATCH after upload.
Phase E (2026-05-05) — Content-Type and magic-number are now validated alongside the extension. Capped at 5 MB; for larger assets, use the SpiderMedia /files/upload endpoint and reference the URL via PATCH.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/upload-preview' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"ext": "string",
"file": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/upload-preview",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"ext": "string", "file": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/upload-preview", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"ext": "string", "file": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"ext": "string", "file": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/upload-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 |
413 | Upload exceeds 5 MB size limit. Use SpiderMedia for larger assets. |
415 | Unsupported extension, Content-Type/extension mismatch, or magic-number mismatch. |
422 | Validation Error |
Publish Component
Publish a component (makes it available for rendering on live sites). For framework components (Tier 4), returns 202 — build runs async. Phase 11+12 gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the publish 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/components/{component_id}/publish' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_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/components/{component_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/components/{component_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 |
Archive Component
Archive a component (removes from rendering but preserves data). Phase 11+12 gated.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true | |
dry_run | query | boolean | false | Phase 11+12: preview the archive and receive a confirm_token without mutating. |
confirm_token | query | any | false | Phase 11+12: consume a prior preview token and perform the archive. |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/archive' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/archive",
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/components/{component_id}/archive", {
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/components/{component_id}/archive", 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 Build Status
Get the build status of a framework component (Tier 4).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/build-status' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/build-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/components/{component_id}/build-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/components/{component_id}/build-status", 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 |
Rebuild Component
Trigger a rebuild for a framework component (Tier 4). Returns 202.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
component_id | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/rebuild' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{component_id}/rebuild",
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/components/{component_id}/rebuild", {
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/components/{component_id}/rebuild", 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 Component Versions
List all versions of a component by slug.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/versions' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/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/components/{slug}/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/components/{slug}/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 |
Component Rollback
Restore a component to an earlier version by creating a new published version with the target version's content, and repointing consuming pages.
One confirm_token covers the whole rollback. Gate action is component_rollback (distinct from component_update_and_propagate), so a forward-update token can't accidentally be consumed against this path.
Never auto-deploys the tenant KV. Block-level updates render live on next request.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/rollback' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"target_version": "string",
"bump": "patch",
"pages": [
"string"
],
"dry_run": false,
"confirm_token": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/rollback",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"target_version": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/rollback", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"target_version": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"target_version": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/rollback", 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 |
Component Update And Propagate
One-shot: bump a component to a new version AND propagate the pin to every (or selected) consuming page, gated by a single confirm_token.
Replaces the 5-step agent choreography (PATCH component → iterate pages → update block versions → publish each → deploy) with one call.
Never auto-deploys. The new component version is published and each affected page's blocks are updated in-place; block-level content renders live via the content API on next request. If you also changed templates or theme, run deploy_site_preview → deploy_site_production as usual.
Phase 11+12 Lock 4. A single confirm_token covers the whole composite mutation (component + all affected pages). Issue with dry_run=true, inspect the affected_pages preview, then send the token back on the real call.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
slug | path | string | true |
Try it
Examples
cURL
curl -X POST 'https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/update-and-propagate' \
-H 'Authorization: Bearer <token>' \
-H 'Content-Type: application/json' \
-d '{
"html_template": "string",
"css": "string",
"js": "string",
"props_schema": {},
"default_props": {},
"dependencies": [
"string"
],
"name": "string",
"description": "string",
"bump": "patch",
"pages": [
"string"
],
"dry_run": false,
"confirm_token": "string"
}'Python
import httpx
resp = httpx.post(
"https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/update-and-propagate",
headers={"Authorization": "Bearer <token>", "Content-Type": "application/json"},
json={"html_template": "string", "css": "string", "js": "string", "props_schema": {}, "default_props": {}, "dependencies": ["string"], "name": "string", "description": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/update-and-propagate", {
method: "POST",
headers: { "Authorization": "Bearer <token>", "Content-Type": "application/json" },
body: JSON.stringify({"html_template": "string", "css": "string", "js": "string", "props_schema": {}, "default_props": {}, "dependencies": ["string"], "name": "string", "description": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"})
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
"strings"
)
func main() {
body := strings.NewReader(`{"html_template": "string", "css": "string", "js": "string", "props_schema": {}, "default_props": {}, "dependencies": ["string"], "name": "string", "description": "string", "bump": "patch", "pages": ["string"], "dry_run": false, "confirm_token": "string"}`)
req, _ := http.NewRequest("POST", "https://spideriq.ai/api/v1/dashboard/projects/{project_id}/content/components/{slug}/update-and-propagate", 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 |