SpiderPublish — AI Agent Integration Guide
SpiderPublish is SpiderIQ's AI-native headless CMS and site builder. Build entire websites, blogs, landing pages, and personalized outreach pages — all through API, CLI, or MCP tools. No browser needed.
GitHub: github.com/martinshein/SpideriQ-ai/SpiderPublish — starter kit with .mcp.json, CLAUDE.md, templates, and components.
Quick Install
Option A: Clone the Starter Kit (fastest)
npx degit martinshein/SpideriQ-ai/SpiderPublish my-site
cd my-site
# .mcp.json + CLAUDE.md + templates + components are ready
Option B: Manual Setup
Step 1: Add .mcp.json to your project root
Create a file called .mcp.json in your project root:
{
"mcpServers": {
"spideriq": {
"command": "npx",
"args": ["@spideriq/mcp"],
"env": {
"SPIDERIQ_FORMAT": "yaml"
}
}
}
}
Step 2: Add CLAUDE.md to your project root
Create a file called CLAUDE.md — see the complete drop-in CLAUDE.md for the full contents. This gives your AI agent all the context it needs.
Step 3: Restart your IDE
Restart to load the MCP server. You now have 146+ tools available.
Works with any IDE that supports MCP:
- Claude Code (CLI, VS Code extension, JetBrains plugin)
- Cursor
- Windsurf
- Google Antigravity
- VS Code with the Claude Code extension installed
- Any other MCP-compatible editor
Alternative: CLI Only
If you prefer terminal workflows without MCP:
npm install -g @spideriq/cli --registry https://npm.spideriq.ai
Alternative: Direct API
For custom integrations in any language:
# Base URL
https://spideriq.ai/api/v1
# Auth header
Authorization: Bearer <client_id>:<api_key>:<api_secret>
Authentication
AI-Native PAT Flow (recommended for agents)
# 1. Request access (sends approval email to admin)
npx spideriq auth request --email admin@company.com --project "My Landing Pages"
# 2. Check status (polls automatically)
npx spideriq auth whoami
After admin approval, your token is saved to ~/.spideriq/credentials.json. All subsequent commands authenticate automatically.
Bearer Token (for API calls)
Authorization: Bearer <client_id>:<api_key>:<api_secret>
You receive these three values when your account is created.
Environment Variables
| Variable | Purpose | Default |
|---|---|---|
SPIDERIQ_TOKEN | Override auth token | — |
SPIDERIQ_API_URL | Override API URL | https://spideriq.ai |
SPIDERIQ_FORMAT | Response format (json, yaml, md) | json |
Always set SPIDERIQ_FORMAT=yaml — it saves 40-76% tokens compared to JSON.
Multi-Tenant Safety (Phase 11+12)
Before you build anything, bind this directory to a project:
spideriq use <project> # writes ./spideriq.json — one folder, one project
spideriq whoami # verify the binding
From that point, every dashboard call auto-scopes to that project's URL (/api/v1/dashboard/projects/{project_id}/content/...), and the backend enforces tenant isolation across five independent checks. If the CLI/MCP finds no spideriq.json, it falls back to legacy URLs and prints a warning.
Destructive operations are two-step by default. MCP tools like content_delete_page, content_publish_page, content_update_settings, template_apply_theme, and content_deploy_site_preview issue a preview + confirm_token on the first call. You must call again with confirm_token to actually mutate.
content_publish_page({ page_id })
# → { dry_run: true, preview: {...}, confirm_token: "cft_..." }
content_publish_page({ page_id, confirm_token: "cft_..." })
# → real publish
For deploy specifically, use the split tools:
content_deploy_site_preview() # get preview_url + confirm_token
content_deploy_site_production({ confirm_token }) # actually deploy
Full details: Session Binding · Deploy Safely
Build a Website (End-to-End)
Here's the complete workflow to build and deploy a site:
Step 1: Read the Reference
# Get the full content reference (YAML, ~2,867 tokens)
GET /api/v1/content/help
This returns every content type, block type, Liquid filter, template variable, and API endpoint — everything your agent needs.
Step 2: Configure Site Settings
PATCH /api/v1/dashboard/content/settings
{
"site_name": "Acme Corp",
"primary_color": "#2563eb",
"site_tagline": "Building the future",
"logo_dark_url": "https://media.cdn.spideriq.ai/acme-logo.svg",
"google_analytics_id": "G-XXXXXXXXXX"
}
Step 3: Set Up Navigation
PUT /api/v1/dashboard/content/navigation/header
{
"items": [
{ "label": "Home", "url": "/", "order": 0 },
{ "label": "Features", "url": "/features", "order": 1 },
{ "label": "Pricing", "url": "/pricing", "order": 2 },
{ "label": "Blog", "url": "/blog", "order": 3 }
]
}
Step 4: Create Pages
POST /api/v1/dashboard/content/pages
{
"title": "Home",
"slug": "home",
"template": "landing",
"blocks": [
{
"id": "hero-1",
"type": "hero",
"data": {
"headline": "Ship Faster with AI",
"subheadline": "The platform that turns your data into revenue.",
"cta_text": "Get Started",
"cta_url": "/pricing"
}
},
{
"id": "features-1",
"type": "features_grid",
"data": {
"headline": "Why Acme?",
"features": [
{ "title": "Fast", "description": "Deploy in seconds", "icon": "zap" },
{ "title": "Secure", "description": "Enterprise-grade security", "icon": "shield" },
{ "title": "Smart", "description": "AI-powered insights", "icon": "brain" }
]
}
}
]
}
Step 5: Publish
POST /api/v1/dashboard/content/pages/{id}/publish
Step 6: Apply Theme
POST /api/v1/dashboard/templates/apply-theme
{ "theme": "default" }
Step 7: Check Readiness
# Verify all prerequisites pass BEFORE deploying
GET /api/v1/dashboard/content/deploy/readiness
Response tells you exactly what's configured and what's missing:
{
"ready": true,
"checklist": [
{ "item": "settings", "label": "Site Settings", "ok": true, "detail": "site_name: Acme Corp" },
{ "item": "domain", "label": "Verified Domain", "ok": true, "detail": "acme.com" },
{ "item": "theme", "label": "Theme / Templates", "ok": true, "detail": "29 templates" },
{ "item": "pages", "label": "Published Pages", "ok": true, "detail": "3 published" }
],
"blocking": [],
"warnings": []
}
If ready is false, fix the items listed in blocking before deploying. Deploy will reject the request and tell you what's missing.
Step 8: Deploy
POST /api/v1/dashboard/content/deploy
Your site is now live at your custom domain.
Pre-Deploy Checklist
Deploy will reject your request if any of these are missing:
| Requirement | How to Fix | Endpoint |
|---|---|---|
Site settings with site_name | Set site name and branding | PATCH /dashboard/content/settings |
| At least 1 verified domain | Add and verify a domain | POST /dashboard/content/domains |
| At least 1 template (theme applied) | Apply a theme | POST /dashboard/templates/apply-theme |
| At least 1 published page | Publish a page | POST /dashboard/content/pages/{id}/publish |
Warnings (won't block deploy but cause issues):
- No primary domain → deploy status won't show your URL
- No header navigation → site renders without a menu
- No homepage (slug:
home) → visitors see a 404 at/
Call GET /dashboard/content/deploy/readiness before deploying. It's one API call that saves you from deploying a broken site.
Common Mistakes
| Mistake | What Happens | Fix |
|---|---|---|
| Skip settings, go straight to deploy | Deploy rejects: "Missing: Site Settings" | PATCH /dashboard/content/settings first |
| Create components with same slug twice | Second call returns 400: "already exists" | Use update_component() or increment version |
| Create pages but don't publish them | Deploy rejects: "Missing: Published Pages" | POST /dashboard/content/pages/{id}/publish |
Skip apply-theme | Deploy rejects: "Missing: Theme / Templates" | POST /dashboard/templates/apply-theme |
| Forget to add a domain | Deploy rejects: "Missing: Verified Domain" | POST /dashboard/content/domains |
Available Block Types
| Type | Use For | Key Fields |
|---|---|---|
hero | Page headers with headline + CTA | headline, subheadline, cta_text, cta_url, background_image_url |
features_grid | Feature showcase (2-6 items) | headline, features[] (title, description, icon) |
cta_section | Call-to-action banner | headline, description, cta_text, cta_url |
testimonials | Social proof quotes | testimonials[] (quote, author, role, company, avatar) |
pricing_table | Pricing tiers | tiers[] (name, price, period, features[], cta_text) |
faq | FAQ accordion | items[] (question, answer) |
stats_bar | Metric highlights | stats[] (value, label) |
rich_text | Free-form content | content (HTML or Markdown) |
image | Full-width image | url, alt, caption |
video_embed | YouTube/Vimeo embed | url, provider |
code_example | Code snippet | code, language, title |
logo_cloud | Partner/client logos | logos[] (url, alt, link) |
comparison_table | Feature comparison | headers[], rows[] |
spacer | Vertical spacing | height |
component | Custom Shadow DOM component | component_slug, component_version, props |
Blog Management
# Create a post
POST /api/v1/dashboard/content/posts
{
"title": "Our Launch Story",
"slug": "launch-story",
"excerpt": "How we built Acme in 30 days...",
"body": { "type": "doc", "content": [...] },
"cover_image_url": "https://...",
"author_id": "uuid",
"tags": ["launch", "startup"]
}
# Publish
POST /api/v1/dashboard/content/posts/{id}/publish
# List published posts (public, no auth)
GET /api/v1/content/posts?page=1&page_size=10
Dynamic Landing Pages
Personalize landing pages per lead using CRM data. Perfect for outreach campaigns.
URL Pattern
https://yoursite.com/lp/{page_slug}/{salesperson}/{google_place_id}
How It Works
- Create a page with template
dynamic_landing - Use merge tags —
{{ firstname }},{{ company_name }},{{ city }},{{ industry }},{{ email }}, etc. — in your content. Full vocabulary: Merge Tags (~40 flat tags).{{ lead.* }}still works for power-user access to the raw IDAP shape. - Configure salesperson profiles in template config (the
{{ salesperson.* }}shape) - Share the URL with the lead's Google Place ID
- The page renders with their business data automatically
Hit /lp/{your-slug}/demo for a built-in Mario's Pizzeria fixture — every merge tag populated so you can design templates before any scraping happens.
Available Lead Variables
| Variable | Example | Source |
|---|---|---|
{{ lead.name }} | "Mario's Pizzeria" | IDAP (Google Maps) |
{{ lead.city }} | "Paris" | IDAP |
{{ lead.country_code }} | "FR" | IDAP |
{{ lead.rating }} | 4.6 | IDAP |
{{ lead.phone_e164 }} | "+33155501234" | IDAP |
{{ lead.domain }} | "mariospizzeria.com" | IDAP |
{{ lead.related.emails }} | Array of verified emails | IDAP includes |
{{ lead.related.phones }} | Array of phone numbers | IDAP includes |
{{ salesperson.name }} | "Ajay Verma" | Template config |
{{ salesperson.title }} | "VP Sales" | Template config |
{{ salesperson.calendar_url }} | Calendly link | Template config |
Setup
# 1. Create the landing page
POST /api/v1/dashboard/content/pages
{
"title": "WiFi Proposal",
"slug": "wifi-proposal",
"template": "dynamic_landing",
"custom_fields": {
"headline": "Stop Losing Guests Over Wi-Fi at {business}",
"cta_headline": "Ready to Transform {business}?"
},
"blocks": [...]
}
# 2. Configure salesperson profiles
PATCH /api/v1/dashboard/templates/config
{
"salespersons": {
"ajay": {
"name": "Ajay Verma",
"title": "VP Sales",
"location": "Dubai, UAE",
"bio": "25 years in hospitality tech",
"photo_url": "https://media.cdn.spideriq.ai/ajay.jpg",
"calendar_url": "https://calendly.com/ajay"
}
}
}
# 3. Deploy
POST /api/v1/dashboard/content/deploy
# 4. Share URL
# https://yoursite.com/lp/wifi-proposal/ajay/0x47e66fdad6f1cc73:0x341211b3fccd79e1
IDAP — Access Your CRM Data
IDAP (Internet Data Access Protocol) gives you read access to all scraped/enriched business data.
# List businesses
GET /api/v1/idap/businesses?limit=20&include=emails&format=yaml
# Fetch one business with all related data
GET /api/v1/idap/businesses/{id}?include=emails,phones,domains,contacts
# Resolve by Google Place ID
GET /api/v1/idap/businesses/resolve?place_id=0x47e66fdad6f1cc73:0x341211b3fccd79e1
# Search
GET /api/v1/idap/businesses/search?q=pizzeria&limit=10
# Flag a lead
POST /api/v1/idap/businesses/{id}/flags
{ "add": ["qualified"], "flagged_by": "agent:my-agent", "reason": "High rating" }
Resource Types
| Type | Contains | Source |
|---|---|---|
businesses | Google Maps listings | SpiderMaps |
domains | Website crawl results | SpiderSite |
contacts | Team members from websites | SpiderSite |
emails | Verified email addresses | SpiderVerify |
phones | Phone numbers | SpiderMaps/SpiderSite |
MCP Tool Reference (Key Tools)
Content Management
| Tool | What It Does |
|---|---|
template_get_help | Get the full content reference |
content_create_page | Create a new page with blocks |
content_update_page | Update page content |
content_publish_page | Publish a page |
content_create_post | Create a blog post |
content_publish_post | Publish a blog post |
template_apply_theme | Apply a visual theme |
content_deploy_site | Deploy to Cloudflare edge |
content_deploy_status | Check deploy status |
Data Access (IDAP)
| Tool | What It Does |
|---|---|
idap_list_resources | List businesses/contacts/emails |
idap_fetch_resource | Get one resource with includes |
idap_search | Full-text search |
idap_write_flags | Flag leads (qualified, contacted, etc.) |
idap_batch_fetch | Fetch up to 100 resources at once |
Jobs
| Tool | What It Does |
|---|---|
scrape_website | Crawl a website for contacts |
search_google_maps | Find businesses on Google Maps |
verify_emails | Verify email deliverability |
submit_job | Submit any job type |
get_job_results | Get job results |
Rate Limits
| Limit | Value |
|---|---|
| API requests | 100/minute per client |
| Job submissions | 10/minute per client |
| Response format | Always use ?format=yaml to save tokens |
Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
Custom Components (Shadow DOM)
Build reusable UI components that are CSS-isolated via Shadow DOM:
POST /api/v1/dashboard/content/components
{
"slug": "hero-gradient",
"name": "Gradient Hero",
"category": "hero",
"html_template": "<section><h1>{{ props.headline }}</h1></section>",
"css": "section { background: linear-gradient(135deg, var(--primary), #000); padding: 4rem 2rem; } h1 { font-size: 3rem; color: white; }",
"props_schema": {
"type": "object",
"properties": {
"headline": { "type": "string", "title": "Headline" }
}
}
}
Use in a page block:
{
"type": "component",
"component_slug": "hero-gradient",
"props": { "headline": "Welcome to Acme" }
}
Uploading Images & Media
Agents building sites need images for hero backgrounds, blog covers, logos, and more. SpiderIQ stores media on Cloudflare R2 (CDN).
Import from URL (recommended for agents)
POST /api/v1/media/files/import-url
Authorization: Bearer $TOKEN
Content-Type: application/json
{
"url": "https://example.com/hero-image.jpg",
"folder": "/content"
}
Returns: { "url": "https://media.cdn.spideriq.ai/content/hero-image.jpg" }
Upload Base64
POST /api/v1/media/files/upload-base64
Authorization: Bearer $TOKEN
Content-Type: application/json
{
"file_base64": "data:image/png;base64,iVBOR...",
"filename": "logo.png",
"folder": "/branding"
}
Dashboard Content Upload
For CMS-specific media (auto-converts to WebP, 5MB limit):
POST /api/v1/dashboard/content/media/upload
Authorization: Bearer $TOKEN
Content-Type: multipart/form-data
file=@image.jpg
folder=/blog
alt_text=Blog hero image
MCP Tools
| Tool | What It Does |
|---|---|
import_from_url | Import images from external URLs to R2 |
list_files | Browse uploaded media files |
Using Images in Blocks
After uploading, use the returned CDN URL in your page blocks:
{
"type": "hero",
"data": {
"headline": "Welcome",
"background_image_url": "https://media.cdn.spideriq.ai/content/hero.webp"
}
}
Or in blog posts:
{
"cover_image_url": "https://media.cdn.spideriq.ai/blog/post-cover.webp"
}
Design Best Practices
When building sites with SpiderIQ, follow these guidelines for professional results.
Typography
- Use system fonts for performance:
font-family: system-ui, -apple-system, sans-serif - For custom fonts, reference Google Fonts CDN in your Liquid layout's
<head> - Limit to 2 font families max (one for headings, one for body)
- Use relative sizes:
remnotpx
Colors
- Set
primary_colorin site settings — it flows asvar(--primary)through all components - Maintain contrast ratio of 4.5:1 minimum for text on backgrounds
- Use
var(--primary)for CTAs, links, and accents - Dark backgrounds (
#111,#1a1a2e) with light text work well for hero sections
Components (Shadow DOM)
- All CSS must be self-contained inside the component — no Tailwind, no external stylesheets
- Use CSS variables for theme integration:
color: var(--primary) - Write mobile-first with
@media (min-width: 768px)for larger screens - Use
flexboxandgridfor layouts - Test at 320px, 768px, and 1280px widths
Spacing
- Use consistent spacing scale:
0.5rem,1rem,1.5rem,2rem,3rem,4rem - Page sections:
padding: 4rem 1.5rem(mobile),padding: 5rem 2rem(desktop) - Between elements within sections:
1remto2rem
Images
- Always set
alttext for accessibility - Use WebP format (SpiderIQ auto-converts on upload)
- Hero images: 1920x1080 recommended
- Blog covers: 1200x630 (matches OG image ratio)
- Logos: SVG preferred, PNG fallback at 2x resolution
Support
- API Docs: https://docs.spideriq.ai
- Health Check:
GET /api/v1/system/health - Content Reference:
GET /api/v1/content/help(best starting point for agents) - Tutorials: Build a Homepage | Build a Blog | Build a Dynamic Landing Page