Skip to main content

Content Platform Guide

Overview

The SpiderIQ Content Platform is a headless, multi-tenant CMS built for developers and AI agents. Every client gets isolated content (posts, pages, authors, categories, tags) accessible via two API layers:

  • Public API (/api/v1/content/*) -- Read-only, no authentication. Designed for external frontends.
  • Dashboard API (/api/v1/dashboard/content/*) -- Full CRUD, requires Bearer authentication. Designed for content management.

Content is stored per-tenant in PostgreSQL. The public API resolves the tenant from the X-Content-Domain header, while the Dashboard API resolves it from the Bearer token.

AI Agent Integration

For MCP tools (146+), CLI commands, Claude Code setup, and deploying sites from code, see the Site Builder docs. The Site Builder section has a complete AGENTS.md integration guide and a drop-in CLAUDE.md for your project.

info

Multi-tenant isolation -- Clients can never read or modify another client's content. Tenant isolation is enforced at the database query level.


Authentication

All Dashboard (CRUD) endpoints require a Bearer token in the format:

Authorization: Bearer <client_id>:<api_key>:<api_secret>

You receive these credentials when your SpiderIQ account is created. The same token is used across all SpiderIQ APIs (jobs, content, gate, etc.).

Public (read-only) endpoints require no authentication. Instead, the client is resolved from the X-Content-Domain header, which maps a domain name to a client account.


Architecture

                    ┌─────────────────────────┐
│ External Frontend │
│ (WeWeb, Next.js, etc.) │
└────────────┬────────────┘

X-Content-Domain: your-domain.com

┌────────────▼────────────┐
│ Public Content API │
│ /api/v1/content/* │
│ (read-only, no auth) │
└────────────┬────────────┘

┌──────────────┐ ┌────────────▼────────────┐
│ Dashboard │ │ │
│ (CRUD API) ├───►│ PostgreSQL (tenant) │
│ Bearer auth │ │ │
└──────────────┘ └─────────────────────────┘

│ Authorization: Bearer <client_id>:<api_key>:<api_secret>

┌──────▼──────────────────┐
│ Dashboard Content API │
│ /api/v1/dashboard/ │
│ content/* │
│ (full CRUD) │
└──────────────────────────┘

Quick Start

This walkthrough creates an author, a category, a tag, a post, publishes it, and then reads it via the public API.

Step 1: Create an Author

curl -X POST "https://spideriq.ai/api/v1/dashboard/content/authors" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"full_name": "Sarah Chen",
"bio": "Technical writer covering APIs and developer tools.",
"role": "author",
"agent_type": "human"
}'

Step 2: Create a Category

curl -X POST "https://spideriq.ai/api/v1/dashboard/content/categories" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Tutorials",
"description": "Step-by-step guides"
}'

Step 3: Create a Tag

curl -X POST "https://spideriq.ai/api/v1/dashboard/content/tags" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "getting-started" }'

Step 4: Create a Post

curl -X POST "https://spideriq.ai/api/v1/dashboard/content/posts" \
-H "Authorization: Bearer $CLIENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "hello-world",
"title": "Hello World",
"body": {
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [{ "type": "text", "text": "Welcome to our blog!" }]
}
]
},
"excerpt": "Our first post.",
"author_id": "<AUTHOR_ID>",
"category_ids": ["<CATEGORY_ID>"],
"tags": ["getting-started"]
}'

Step 5: Publish the Post

curl -X POST "https://spideriq.ai/api/v1/dashboard/content/posts/<POST_ID>/publish" \
-H "Authorization: Bearer $CLIENT_TOKEN"

Step 6: Read via Public API

curl -s "https://spideriq.ai/api/v1/content/posts/hello-world" \
-H "X-Content-Domain: your-domain.com"

Content Types

SpiderIQ's Content Platform supports three content types:

Posts (Blog)

Blog posts use Tiptap JSON for rich text content. Posts support:

  • Authors -- human or AI agent authors
  • Categories -- hierarchical grouping (Tutorials > API Guides)
  • Tags -- flat labels for cross-cutting topics
  • Related posts -- manual or auto-linked related content
  • Featured flag -- mark posts for homepage prominence
  • SEO fields -- custom title, description, OG image
  • View tracking -- automatic view count on each public read
  • Full-text search -- search across title, body, excerpt, tags

Pages (Marketing)

Pages use a block-based content model for structured layouts. Block types include:

Block TypeUse Case
heroLanding page hero with heading, subheading, CTA
textRich text paragraphs
ctaCall-to-action buttons and sections
faqFrequently asked questions
pricingPricing plan grids
featuresFeature lists or grids
imageImage with optional caption
videoEmbedded video
testimonialsCustomer testimonial carousel

Pages are ideal for About, Pricing, Contact, and Landing pages.

Docs (Documentation)

Documentation pages are organized in a tree structure with parent-child relationships. Each doc has:

  • slug -- URL path segment
  • title -- Page title
  • body -- Tiptap JSON content
  • parent_id -- For nesting (Docs > Getting Started > Installation)
  • sort_order -- Display order within parent

Use the Get Doc and Doc Tree endpoints to read documentation.


Blog System

Authors

Authors represent the people (or AI agents) who create content. Each post has one author.

FieldDescription
full_nameDisplay name
slugURL-friendly identifier (auto-generated)
roleauthor, editor, contributor, or administrator
agent_typehuman or ai -- lets readers know if content was AI-generated
avatar_urlProfile image
bioShort biography

Categories (Hierarchical)

Categories provide a hierarchical taxonomy. Use parent_id to create nested trees:

Tutorials
├── API Guides
├── Scraping Guides
└── Automation
Product Updates
├── Features
└── Bug Fixes

Tags (Flat)

Tags are flat labels that cut across categories. A post about "Scraping Google Maps" might be in the "Tutorials" category with tags google-maps, scraping, seo.

Post Lifecycle

Posts move through a defined status lifecycle:

draft  →  pending_review  →  published  →  archived
StatusVisible on public API?Description
draftNoInitial state, work in progress
pending_reviewNoReady for editorial review
publishedYesLive and publicly accessible
archivedNoRemoved from public, preserved in DB

Use Change Post Status to transition between any states, or the shortcut endpoints Publish and Unpublish.

Mark posts as is_featured: true to highlight them. Query featured posts via the Featured Posts endpoint.

Search across post titles, body content, excerpts, and tags using the Search Posts endpoint:

curl -s "https://spideriq.ai/api/v1/content/posts/search?q=google+maps&limit=10" \
-H "X-Content-Domain: your-domain.com"

Using with External Frontends

The public Content API is designed for headless use with any frontend framework. Set the X-Content-Domain header to your site's domain so SpiderIQ resolves the correct tenant.

How It Works

  1. Register your domain with SpiderIQ (mapped to your client account)
  2. Your frontend sends requests to https://spideriq.ai/api/v1/content/*
  3. Include X-Content-Domain: your-domain.com in every request
  4. SpiderIQ returns only your client's published content

WeWeb / Webflow / Bubble

For no-code tools, configure an API data source:

  • Base URL: https://spideriq.ai/api/v1/content
  • Headers: X-Content-Domain: your-domain.com
  • Endpoints: /posts, /posts/{slug}, /pages/{slug}, /categories, /tags, /authors

Next.js Example

// lib/content.js
const CONTENT_API = "https://spideriq.ai/api/v1/content";
const DOMAIN = "your-domain.com";

export async function getPosts(page = 1, limit = 10) {
const resp = await fetch(
`${CONTENT_API}/posts?page=${page}&limit=${limit}`,
{ headers: { "X-Content-Domain": DOMAIN } }
);
return resp.json();
}

export async function getPost(slug) {
const resp = await fetch(
`${CONTENT_API}/posts/${slug}`,
{ headers: { "X-Content-Domain": DOMAIN } }
);
return resp.json();
}

export async function getCategories() {
const resp = await fetch(
`${CONTENT_API}/categories`,
{ headers: { "X-Content-Domain": DOMAIN } }
);
return resp.json();
}
// app/blog/page.js (Next.js App Router)
import { getPosts, getCategories } from "@/lib/content";

export default async function BlogPage() {
const [postsData, categoriesData] = await Promise.all([
getPosts(),
getCategories(),
]);

return (
<div>
<h1>Blog</h1>
<nav>
{categoriesData.categories.map(cat => (
<a key={cat.id} href={`/blog/category/${cat.slug}`}>
{cat.name}
</a>
))}
</nav>
<div>
{postsData.posts.map(post => (
<article key={post.id}>
<h2><a href={`/blog/${post.slug}`}>{post.title}</a></h2>
<p>{post.excerpt}</p>
<span>By {post.author.full_name}</span>
</article>
))}
</div>
</div>
);
}

Static Site Generation

The Content API works well with SSG frameworks. Fetch content at build time:

// Astro, Eleventy, Hugo, etc.
// Fetch all post slugs for static path generation

const resp = await fetch(
"https://spideriq.ai/api/v1/content/posts?limit=1000",
{ headers: { "X-Content-Domain": "your-domain.com" } }
);
const data = await resp.json();
const slugs = data.posts.map(p => p.slug);

AI Agent Integration

AI agents can manage content entirely through the API, with no human interaction required.

MCP Tools

If your AI agent supports the Model Context Protocol, install the SpiderIQ MCP server:

{
"mcpServers": {
"spideriq": {
"command": "npx",
"args": ["@spideriq/mcp"],
"env": { "SPIDERIQ_FORMAT": "yaml" }
}
}
}

Available content MCP tools:

ToolDescription
content_list_pagesList published pages
content_create_pageCreate a new page
content_get_pageGet page by slug
content_update_pageUpdate a page
content_delete_pageDelete a page
content_publish_pagePublish a page
content_create_postCreate a blog post
content_publish_postPublish a post

CLI Commands

# Create a post via CLI
npx spideriq content create-post \
--slug "ai-generated-post" \
--title "AI Generated Content" \
--body '{"type":"doc","content":[{"type":"paragraph","content":[{"type":"text","text":"Written by AI."}]}]}' \
--tags "ai,automation"

# Publish it
npx spideriq content publish-post --id <post-id>

# List all posts
npx spideriq content list-posts --format yaml

Agent Workflow Example

A typical AI agent content workflow:

import requests

API = "https://spideriq.ai/api/v1/dashboard/content"
HEADERS = {"Authorization": f"Bearer {CLIENT_TOKEN}"}

# 1. Ensure author exists
authors = requests.get(f"{API}/authors", headers=HEADERS).json()
# (or create one if needed)

# 2. Generate content with your LLM
title = "10 Lead Generation Tips for 2026"
body_content = generate_blog_post(title) # your LLM call

# 3. Create the post
post = requests.post(f"{API}/posts", headers=HEADERS, json={
"slug": "lead-generation-tips-2026",
"title": title,
"body": body_content,
"excerpt": "Proven lead generation strategies for the AI era.",
"tags": ["lead-generation", "tips", "2026"],
"author_id": authors[0]["id"],
}).json()

# 4. Review or auto-publish
# Option A: Set to pending_review for human approval
requests.post(f"{API}/posts/{post['id']}/status", headers=HEADERS,
json={"status": "pending_review"})

# Option B: Auto-publish immediately
requests.post(f"{API}/posts/{post['id']}/publish", headers=HEADERS)

API Reference

Public Endpoints (Read-Only, No Auth)

EndpointDescription
List PostsList published posts with pagination
Get PostGet a post by slug
Search PostsFull-text search
Featured PostsList featured posts
List AuthorsList active authors
Get AuthorGet author by slug
List CategoriesList categories with hierarchy
List TagsList tags with post counts
List PagesList published pages
Get PageGet a page by slug
Doc TreeGet documentation tree
Get DocGet a doc by slug
NavigationGet navigation menus
SettingsGet site-wide settings
SitemapAuto-generated sitemap

Dashboard Endpoints (CRUD, Bearer Auth)

Posts:

EndpointDescription
Create PostCreate a new post
Update PostUpdate a post
Delete PostDelete a post
Publish PostPublish a post
Unpublish PostRevert to draft
Change StatusSet any lifecycle status

Authors:

EndpointDescription
Create AuthorCreate an author
Update AuthorUpdate an author
Delete AuthorDeactivate an author

Tags:

EndpointDescription
Create TagCreate a tag
Update TagUpdate a tag
Delete TagDelete a tag

Categories:

EndpointDescription
Create CategoryCreate a category
Update CategoryUpdate a category
Delete CategoryDelete a category

Pages:

EndpointDescription
Create PageCreate a page
Update PageUpdate a page
Delete PageDelete a page
Publish PagePublish a page
Unpublish PageRevert to draft