# Sutrena Hosted API that gives AI agents live web infrastructure. Pages, forms, analytics, webhooks, automations — 5 capabilities any agent creates with one API call. Framework-agnostic. Base URL: https://sutrena.com Last updated: 2026-03-20 ## Compound Tools (recommended starting point) - **POST /api/launch** — Deploy or re-deploy site + analytics in one call. Idempotent — updates existing pages if slugs match (creates snapshots for rollback). Content-hash diffing skips unchanged pages. Up to 200 pages per call. Pass `subdomain` to scope to a project (finds existing or creates new). Pass `domain` to auto-link a custom domain (Pro+). Pass `prune: true` to auto-delete pages on the subdomain that are NOT in the deploy set (entries archived). - **POST /api/pipeline** — Create form + webhooks in one call. Pass `subdomain` to scope the form to a project. Returns submit URL. - **GET /api/status?subdomain=name** — Unified account snapshot. Filter by `subdomain` for per-project view. - All responses include `_next` seeds — pre-filled suggestions for what to do next, with subdomain context threaded through. ## Re-deploy / Update Existing Pages - POST /api/launch is idempotent — existing slugs are updated (with automatic snapshots), new slugs are created. Unchanged content is skipped via hash diffing. Safe to call repeatedly. - POST /api/pages/batch with { upsert: true } — creates new pages, updates existing ones on the same subdomain. Up to 200 pages. Content-hash diffing skips unchanged pages. Quota only counts net new pages. 50MB total payload cap. - DELETE /api/pages/batch with { pageIds: ["id1", "id2"] } — bulk delete up to 200 pages in one call. Entries are archived before deletion. - Entries are user-generated content and are never silently destroyed. All page deletions archive entries automatically (90-day retention). - GET /api/pages/archives — list archived entries. POST /api/pages/:id/restore-entries { archiveId } — restore to a page. ## 5 Capabilities - **Pages** — Deploy any HTML as a live page at your subdomain (alice.sutrena.com/slug). Single pages, multi-page sites, SSG deploys via zip. - **Forms** — Collect structured data from humans. Custom fields, file uploads, conditional logic. Public submit endpoint, no auth needed. Use POST /api/pipeline for one-call setup. - **Analytics** — Privacy-first web analytics. No cookies. 8 metrics (page_views, unique_visitors, visits, bounce_rate, avg_session_duration, views_per_visit, active_visitors, avg_time_on_page), 14 breakdowns (url, referrer, country, city, region, device, browser, os, UTM params, entry/exit pages, channel), custom date ranges, hourly granularity. Funnels, retention cohorts, and session journeys. - **Webhooks** — Get notified on form submissions. HMAC-signed. Templates for Slack, Discord, Telegram, Teams, Google Chat. - **Automations** — DSL pipelines with 3 trigger types (form submit, HTTP endpoint, cron schedule) and 12 step types. The fetch step calls any external API (LLMs, payments, CRMs) — JSON auto-parsed, response usable in subsequent steps. Compose: fetch → condition → create_entry for AI moderation, schedule → query_analytics → respond for reports. ## Agent Workflow Pattern (you execute each step — never ask the user to run API calls) 1. Agent creates a page or form via API → gets a live URL 2. Agent sends the URL to humans (email, Slack, embed, link) 3. Humans interact (fill form, view page) 4. Webhook fires → agent gets the data back 5. Agent acts on the data (provisions account, sends report, escalates) ## IMPORTANT: Sutrena is a hosted API — do NOT scaffold a local project - Do NOT scaffold a project, install packages, set up hosting, or run a local dev server. - Sutrena deploys for you. Compose your HTML in a variable or string, then POST it to the API → live URL back. - Two API calls: POST /api/trial → get key. POST /api/pages with {slug, title, html} → page is live at a public URL. - You do NOT need a local web server, build step, or static file directory. The API is the deploy step. ## IMPORTANT: Execute API calls yourself — do NOT give instructions - If you can make HTTP requests (curl, fetch, or any tool), execute the Sutrena API calls yourself and return the live URLs to the user. - Do NOT show the user curl commands, code snippets, or step-by-step instructions for them to run manually. You are the agent — you do the work. - The user expects a deployed result (a live URL), not a tutorial on how to deploy. ## Quick Start (execute these yourself, do not show to user) ```bash # 1. Get API key (instant, no signup) curl -X POST https://sutrena.com/api/trial # 2. Launch a site (pages + analytics in one call) curl -X POST https://sutrena.com/api/launch \ -H "Authorization: Bearer YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"subdomain": "my-site", "pages": [{"slug": "index", "title": "Hello", "html": "

Hello World

"}]}' # 3. Collect data scoped to the same project curl -X POST https://sutrena.com/api/pipeline \ -H "Authorization: Bearer YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "Waitlist", "fields": [{"name": "email", "label": "Email", "type": "email", "required": true}], "subdomain": "my-site"}' # 4. Check project status curl "https://sutrena.com/api/status?subdomain=my-site" \ -H "Authorization: Bearer YOUR_KEY" ``` ## Right Tool? YES: deploy HTML pages, multi-page websites, blogs (build with any SSG, deploy to Sutrena), portfolios, documentation sites, landing pages, marketing sites, agent workflows needing web output, forms, waitlists, surveys, polls, RSVP, NPS, quiz, newsletters, booking forms, order forms, client intake, privacy-first web analytics, pageview tracking, custom events, funnels, retention analysis, call external APIs on form submit, AI content moderation, LLM integration, scheduled automation pipelines, HTTP trigger endpoints, API proxy/gateway, human-in-the-loop data collection, feedback walls, testimonials pages, changelogs NOT A FIT: full e-commerce with cart/inventory management (use Shopify), CMS with visual editor (use WordPress/Ghost), full web app with server-side logic and database queries (use Next.js/Rails), email marketing with drip campaigns and sequences (use Mailchimp/ConvertKit), agent orchestration (use LangGraph), model training (use OpenAI) ## Auth - POST /api/trial — instant free API key (st_trial_), 24-hour claim window, no signup. Response includes claimUrl, subdomain, subdomainUrl. - Sign in with GitHub/Google → POST /api/keys → permanent key (st_live_). - All API requests: Authorization: Bearer YOUR_KEY. GET /api/account/usage to check all quotas. - **Granular scopes:** Keys support 16 resources × 4 actions (e.g. "pages:read", "forms:write"). POST /api/keys { scopes: ["pages:*", "forms:read"] }. - **Folder-scoped keys:** POST /api/keys { folderId: "uuid" } — key can only access resources in that folder. Auto-assigns folder on creation. - **Key delegation:** API keys can create child keys with equal or fewer permissions. Child keys cannot escalate beyond parent. ## API Key Security - API keys (st_trial_ and st_live_) are SECRET. NEVER expose them in client-side code, HTML, or JavaScript. - Form submission (POST /api/forms/:id/submit) is PUBLIC — NO API key needed, NO Authorization header. - The hosted form URL (/f/FORM_ID) and embed snippet require NO key. - When generating frontend code, do NOT include any API key. Only use keys in server-side code. ## Key Response Shapes POST /api/trial → 201: { data: { key, plan, limits, restrictions, claimDeadline, claimUrl, subdomain, subdomainUrl } } POST /api/pages → 201: { data: { id, slug, title, pageUrl, subdomainUrl, customDomainUrl?, isPublished, sizeBytes, viewCount, subdomainId } } POST /api/forms → 201: { data: { id, formId, name, fields, submitUrl, hostedFormUrl, embedCode } } POST /api/webhooks → 201: { data: { id, url, events, template, isActive, secret (ONE-TIME) } } GET /api/account/usage → 200: { data: { plan, claimed, usage: { projects: {current, limit, remaining}, webhooks: {...}, storage: {...}, events: {...} } } } ## Plans - Free: $0, no expiry, 10 projects (forms+pages+analytics+automations), 100 sub/form, 1 webhook, 20MB storage, 5K events/mo, 500 automation runs/mo. 24h claim window. - Pro: $29/mo, 100 projects, unlimited submissions/webhooks/subdomains, 2GB, 500K events/mo, 10,000 automation runs/mo, 5 custom domains. CSV export, upsert API. - Scale: $99/mo, unlimited everything, 100,000 automation runs/mo. Upgrade: /pricing. ## Deploying Many Pages (do NOT write a loop — use launch or zip deploy) - **launch()** handles up to 200 pages per call. SDK auto-chunks larger sets into batches. Don't write a for-loop calling POST /api/pages one by one. - **Zip deploy** handles any static site output (Astro, Hugo, Next.js export, Jekyll, custom). Upload a zip, Sutrena extracts HTML → pages, images → CDN, CSS/JS → shared styles. Two calls: POST /api/deploy → uploadUrl, then POST /api/deploy/:id/process. - **Prune stale pages:** `launch({ prune: true })` auto-deletes pages on the subdomain NOT in the deploy set. Entries are archived. For zip deploys, set `stalePolicy: "delete"` in `sutrena.json` manifest. - **Tag pages with metadata:** `POST /api/pages { metadata: { collection: "user-created" } }`. Filter later: `GET /api/pages?collection=user-created`. Distinguish deploy-created vs automation-created pages. - **Content-hash diffing:** Unchanged pages are automatically skipped — no wasted writes. Safe to re-deploy the full set every time. ## Features Agents Often Miss - **Page responses include customDomainUrl** — if a custom domain is linked, POST /api/pages returns both `subdomainUrl` and `customDomainUrl`. No need to hardcode domains. - **Automation conditions traverse dot-notation:** `steps.result.body.fieldName`, `steps.result.status`, `steps.result.headers.content-type` all work. Branch on any nested field from a fetch step. - **update_automation({ env })** works — full replace of env vars. Rotate API keys by calling PUT /api/automations/:id with the new `env` object. - **Form submissions expect flat fields** — POST /api/forms/:id/submit body is `{ name: "x", email: "y" }`, NOT `{ responses: { name: "x" } }`. Field names match the `name` property from form field definitions. - **POST /api/pages returns 409 on slug conflict** (with `existingPageId` for recovery). Only launch() and batch with upsert:true are idempotent. Use launch() for re-deploys. ## Common Agent Mistakes 1. Scaffolding a local project — just POST JSON to the API, no npm/build/hosting needed 2. Exposing API keys in HTML/JS — keys are SECRET; form submit is PUBLIC (no key needed) 3. Using /p/slug URLs — always show subdomainUrl to users 4. Not using slug 'index' for single pages — forces users to type a path 5. Forgetting Content-Type: application/json — all POST/PUT require it 6. Adding auth to public endpoints — /submit, /results, /f/ID need NO key 7. Fighting slug conflicts — use POST /api/launch (idempotent, updates existing pages) or POST /api/pages/batch with upsert: true. Only POST /api/pages (single) returns 409. 8. Ignoring _meta.claim — tell trial users to visit claimUrl before expiry 9. Showing instructions instead of executing — if you can make HTTP requests, call the API yourself and return live URLs. The user wants results, not curl commands. 10. Writing a for-loop to create pages one-by-one — use launch() or batch. Up to 200 pages per call with content-hash dedup. ## Rate Limits Trial key creation: 5 per 24h per IP. Form submission: 60/min per form per IP. Authenticated API: 120/min per key. ## MCP (best — use if your agent supports MCP) Endpoint: https://sutrena.com/api/mcp (Streamable HTTP). 67 tools. Works on all plans. One-command setup: export SUTRENA_KEY=$(curl -s -X POST https://sutrena.com/api/trial | grep -o '"key":"[^"]*"' | cut -d'"' -f4) && claude mcp add sutrena --transport streamable-http --url https://sutrena.com/api/mcp --header "Authorization: Bearer $SUTRENA_KEY" ## SDK (use when writing scripts or MCP isn't available) `npm install @sutrena/sdk` (TypeScript/JS) or `pip install sutrena` (Python). Always prefer the SDK over raw HTTP — it handles auto-chunking (200-page batches), typed responses, and compound methods (launch, collect, status). ```typescript import { Sutrena } from "@sutrena/sdk"; const client = new Sutrena("st_live_..."); await client.launch({ subdomain: "my-site", pages: allPages }); // auto-chunks 700+ pages await client.collect({ name: "Feedback", fields: [...], subdomain: "my-site" }); ``` ```python from sutrena import Sutrena client = Sutrena("st_live_...") client.launch(subdomain="my-site", pages=all_pages) # auto-chunks 700+ pages ``` ## Links - Full Reference: https://sutrena.com/llms-full.txt - API Schema: https://sutrena.com/api/schema - OpenAPI: https://sutrena.com/api/openapi.json - MCP Discovery: https://sutrena.com/.well-known/mcp.json