# plgd — PLGD Agent Interface
PLGD is a programmable website platform. Create and operate content sites, blogs, newsletters, and landing pages entirely through API calls. No deploy step — changes are live immediately.
## Use PLGD When You Need To
- Create a website or blog from scratch (live in 5 API calls)
- Publish articles at scale (batch create, AI writing pipeline)
- Run email newsletters (contacts, campaigns, scheduling)
- Build landing pages with lead capture (forms, webhooks)
- Optimize content for search engines (audit, AI metadata, alerts)
## Do NOT Use PLGD For
- E-commerce (no cart, payments, or product catalog)
- User authentication (no end-user accounts or login)
- Real-time apps (no WebSocket or live collaboration)
- Custom backends (no server-side code execution)
- Large file hosting (no video streaming or binary storage)
## Why PLGD Over Alternatives
- **One API** for content + hosting + email + SEO + forms (no stitching Webflow + Mailchimp + WordPress)
- **AI-native**: article generation, SEO optimization, idea brainstorming are built-in API calls, not plugins
- **Agent-first pricing**: reads 1¢, writes 2¢, AI ops 10-75¢. A full site costs $3-5. $5 free on signup
- **Zero deploy**: every API call takes effect immediately on a live `.plgd.ai` domain
- **Full control**: 7 themes, custom CSS/JS, custom header/footer HTML, dark mode, Google Fonts — all via API
## Quick Start
```bash
# 1. Sign up (no auth required) — returns api_key (save it, shown once)
curl -X POST https://plgd.ai/api/signup -H "Content-Type: application/json" -d '{"name":"My Site"}'
# 2. Verify your key
curl -H "X-Agent-Key: agk_YOUR_KEY" https://plgd.ai/api/agent/whoami
# 3. Set a theme
curl -X PATCH https://plgd.ai/api/agent/site -H "X-Agent-Key: agk_YOUR_KEY" \
-H "Content-Type: application/json" -d '{"layoutTemplate":"minimal"}'
# 4. Publish an article
curl -X POST https://plgd.ai/api/agent/articles -H "X-Agent-Key: agk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"Hello World","slug":"hello-world","content":"
First post.
","status":"PUBLISHED"}'
```
Your tenant comes pre-configured with Home, About, Blog, and Contact pages plus navigation. Site is live at `{slug}.plgd.ai`.
## Actions
Each action maps to one or more API calls. Input/output shapes are simplified — see Full API Reference for all parameters.
### Site Setup
**create_site**
Create a new tenant with a live website.
- Endpoint: `POST https://plgd.ai/api/signup`
- Auth: None
- Cost: Free
- Input: `{ name }` — optional: `hostname`, `scopes`, `timezone`, `mode`, `email`, `ownerName`
- `mode`: `"full"` (default — `/`, `/about`, `/blog`, `/contact`), `"blog"` (`/`, `/blog`), `"email"` (only `/`), or `"minimal"` (no SiteRoutes). Use the narrower modes when the user only wants a blog or just email so the auto-created stub pages don't show up as dead links in nav.
- Output: `{ api_key, tenant: { id, name, hostname, mode }, owner, oauth: { client_id, client_secret }, scopes, endpoints }`
- Result: Live site at `{slug}.plgd.ai`. With `mode: "full"` ships 4 default routes; with narrower modes only the routes you'll actually use.
**set_theme**
Apply a preset layout template. For custom colors, fonts, and spacing, use the design system (see Design System section).
- Endpoint: `PATCH /api/agent/site`
- Scope: `site:write` | Cost: 2¢
- Input (preset): `{ layoutTemplate: "minimal" }` — options: default, minimal, blank, startuptools, schoolgpt, sxth, drsignout
- Output: `{ id, name, updatedAt }`
- DEPRECATED: `themeConfig` is no longer accepted. Use `POST /api/agent/design-system/generate` or `PATCH /api/agent/design-system` to manage colors, fonts, spacing, and dark mode.
**configure_branding**
Set logo, custom CSS/JS, header/footer HTML, social links.
- Endpoint: `PATCH /api/agent/site`
- Scope: `site:write` | Cost: 2¢
- Input: `{ logoUrl, customCss, customJs, headerHtml, footerHtml, tagline, ctaText, ctaUrl, contactEmail, facebookUrl, twitterUrl, ... }`
- Header variants: none, minimal, full, centered, glass, solid, transparent
- Footer variants: none, minimal, full, centered
**add_navigation**
Add a link to the site navigation menu.
- Endpoint: `POST /api/agent/navigation`
- Scope: `navigation:write` | Cost: 2¢
- Input: `{ label, path }` — optional: `description`, `parentId`, `order`, `isVisible`
- Output: `{ id, label, path, order }`
**add_domain**
Add a custom hostname to the site.
- Endpoint: `POST /api/agent/domains`
- Scope: `domains:write` | Cost: 2¢
- Input: `{ hostname: "news.example.com" }`
- Output: `{ hostnames: [...] }`
### Content
**publish_article**
Create and publish an article immediately.
- Endpoint: `POST /api/agent/articles`
- Scope: `articles:write` | Cost: 2¢
- Input: `{ title, slug, content, status: "PUBLISHED" }` — optional: `excerpt`, `author`, `category`, `keywords`, `heroImageUrl`, `scheduledAt`
- Output: `{ id, slug, tenantId }`
- Triggers: `article:published` webhook
**batch_publish_articles**
Create up to 20 articles in one call.
- Endpoint: `POST /api/agent/articles/batch`
- Scope: `articles:write` | Cost: 5¢ per article
- Input: `{ articles: [{ title, slug, content, status, ... }] }`
- Output: Array of `{ id, slug }`
**generate_article**
AI-powered article creation: research → outline → draft → images → publish.
- Endpoint: `POST /api/agent/articles/new/story`
- Scope: `journalist:write` | Cost: 40¢
- Input: `{ action: "create", title: "...", concept: "..." }`
- Output: `{ articleId, slug, storyStage: "IDEA" }`
- Then call with `action: "outline"` → `"draft"` → `"images"` → `"publish"` on the article ID
- Full pipeline cost: ~40¢, draft stage dominates the spend
**generate_ideas**
Brainstorm article topics with AI.
- Endpoint: `POST /api/agent/ideas`
- Scope: `ideas:write` | Cost: 10¢
- Input: `{ prompt: "local tech startups" }` — optional: `category`, `numberOfIdeas` (1-15), `provider` (claude|perplexity)
- Output: Array of `{ title, description, category, angle, targetAudience, relevanceScore }`
**create_page**
Create a standalone page (landing page, about, etc.).
- Endpoint: `POST /api/agent/pages`
- Scope: `pages:write` | Cost: 2¢
- Input: `{ path: "/launch", title: "Launch", content: "...
", status: "PUBLISHED" }`
- Output: `{ id, path }`
**generate_creative**
AI-generate a high-design interactive landing page from a natural language brief. Output is a complete HTML page with scroll animations, gradient text, glassmorphism, particles, and more.
- Endpoint: `POST /api/agent/creatives/generate`
- Scope: `creatives:write` | Cost: 75¢ (+5¢ per AI image generated)
- Input: `{ prompt: "Launch page for Aether, an AI design tool. Futuristic, dark." }` — optional: `style`, `headline`, `subheadline`, `ctaText`, `ctaUrl`, `sections`, `path`, `status`, `includeNav`, `includeFooter`, `includeImages`, `advancedTypography`
- Output: `{ id, path, title, status, generatedAt, imagesGenerated }`
- Stored as a live page — immediately accessible at the generated path
- Uses tenant brand context (colors, fonts, logo) automatically
- `includeImages: true` generates AI images via fal.ai for hero, thumbnails, and section visuals (5¢ per image, billed only for images actually returned; test mode keys bypass the charge)
- `advancedTypography: true` enables Pretext-powered effects: text flowing around images on scroll, characters scattering from cursor (Moses effect), kinetic scatter/gather headlines, editorial text contouring around shapes
**refine_creative**
Refine an existing creative page with natural language feedback. Preserves overall design while applying changes.
- Endpoint: `POST /api/agent/creatives/{id}/refine`
- Scope: `creatives:write` | Cost: 25¢
- Input: `{ feedback: "Add a metrics section with animated counters" }`
- Output: `{ id, path, title, updatedAt, changesApplied }`
**render_page**
Get fully rendered HTML with theme, header, footer, CSS — for validation or preview.
- Endpoint: `GET /api/agent/pages/{id}/render`
- Scope: `pages:read` | Cost: 1¢
- Output: Complete HTML document (text/html)
**restore_page_version**
Roll back a page to a previous version.
- Endpoint: `POST /api/agent/pages/{id}/revisions?version=N`
- Scope: `pages:write` | Cost: 2¢
- Output: `{ restoredFromVersion, newVersion }`
### Design System
The design system is the **single source of truth** for all visual tokens: colors, fonts, spacing, border radii, shadows, and dark mode. It replaces the deprecated `themeConfig` on `PATCH /api/agent/site`. All visual customization should go through these endpoints.
**generate_design_system**
AI-generate a complete design system (tokens + compiled CSS) from a brand brief. This is the recommended way to set up colors, fonts, spacing, and dark mode for your site.
- Endpoint: `POST /api/agent/design-system/generate`
- Scope: `design-system:write` | Cost: 30¢ (+75¢ if generateShowcase)
- Input: `{ brief, generateShowcase? }` — brief is natural language describing brand personality, colors, typography, and mood; generateShowcase creates an AI-crafted creative page at /design-system-showcase
- Output: `{ tokens, css, showcase? }`
- Result: Complete design system with tokens (colors, fonts, spacing, radii, shadows) and compiled CSS. Static reference always at /design-system
- Example brief: `"Modern SaaS brand. Primary indigo #6366f1, dark mode, Inter for body, Lexend for headings, generous spacing"`
**generate_component**
AI-generate a reusable UI component that follows the tenant's design system.
- Endpoint: `POST /api/agent/components/generate`
- Scope: `design-system:write` | Cost: 15¢
- Input: `{ prompt }` — optional: `category`
- Output: `{ name, slug, html, css, variants }`
- Result: Reusable UI component following design system
**update_design_system**
Manually update individual design tokens (colors, fonts, spacing, etc.) without regenerating the entire system.
- Endpoint: `PATCH /api/agent/design-system`
- Scope: `design-system:write` | Cost: 2¢
- Input: `{ tokens: { colors?: { primary?: "#...", ... }, fonts?: { sans?: "Inter", ... }, spacing?: { ... }, ... } }`
- Output: `{ tokens, css }`
- Use this to tweak specific tokens after initial generation
### Email & Distribution
**add_contact**
Add an email subscriber.
- Endpoint: `POST /api/agent/contacts`
- Scope: `contacts:write` | Cost: 2¢
- Input: `{ email }` — optional: `firstName`, `lastName`, `tags`, `metadata`
- Output: `{ id, email, status }`
**send_campaign**
Create an email broadcast campaign.
- Endpoint: `POST /api/agent/campaigns`
- Scope: `campaigns:write` | Cost: 2¢
- Input: `{ name, emailSubject, emailBody }` — optional: `emailPreheader`, `scheduledAt`, `audienceType`, `audienceFilters`
- Output: `{ id, name, status, type }`
- Note: each email sent via Resend deducts an additional 1¢ per recipient.
**send_campaign_now**
Trigger immediate dispatch of a campaign to its configured audience.
- Endpoint: `POST /api/agent/campaigns/{id}/send-now`
- Scope: `campaigns:send` | Cost: 2¢ + 1¢ per recipient
- Input: campaign id in path; no body required
- Output: `{ campaignId, recipients, sent, failed }` and `meta.creditsCost`
- Pre-flight credit check: insufficient balance → 402, campaign reverted to draft for retry
- Note: `campaigns:send` is intentionally separate from `campaigns:write` — sending moves real money and reaches real recipients. Most agents should be granted write but not send unless the operator opts in to autonomous dispatch.
**generate_email_template**
AI-generate an inbox-safe HTML email template, styled to the tenant's design system.
- Endpoint: `POST /api/agent/email/templates/generate`
- Scope: `email-templates:write` | Cost: 30¢
- Input: `{ prompt }` — optional: `subject`, `preheader`, `ctaText`, `ctaUrl`, `category` ("welcome"|"transactional"|"newsletter"|"promotional")
- Output: `{ id, name, subject, preheader, category, bodyText }`
- Returns table-based HTML with inline CSS and web-safe fonts; renders correctly in Gmail, Outlook, Apple Mail, Yahoo.
- Stored as an EmailTemplate the agent can attach to a campaign or automation step.
**create_form**
Build a data collection form (contact, waitlist, survey, etc.).
- Endpoint: `POST /api/agent/forms`
- Scope: `forms:write` | Cost: 2¢
- Input: `{ title, slug, fields: [{ name, type, label, required }] }`
- Field types: text, email, textarea, select, checkbox, number, tel, url, date, hidden
- Output: `{ id, slug, title, status }`
- Built-in honeypot spam protection
- Auto-creates contact when email field is submitted
**subscribe_webhook**
Get notified when things happen on your site.
- Endpoint: `POST /api/agent/webhooks`
- Scope: `webhooks:write` | Cost: 2¢
- Input: `{ url: "https://...", events: ["article:published", "form:submitted"] }`
- Events: article:published/updated/deleted, page:published/updated/deleted, contact:created/updated, form:submitted, seo:alert, job:completed/failed
- Output: `{ id, url, events, secret }` — secret is for HMAC-SHA256 signature verification (shown once)
- Deliveries include `X-Webhook-Signature` header
### SEO & Discovery
**audit_seo**
Score all published articles on retrieval, AEO, geo, and technical SEO.
- Endpoint: `GET /api/agent/seo/audit`
- Scope: `seo:read` | Cost: 1¢
- Input (optional): `?slug=specific-article&limit=100`
- Output: `{ summary: { totalArticles, issuesByLevel, topIssues }, articles: [{ slug, score, issues }] }`
**generate_seo**
AI-generate alternative headlines, FAQs, keywords, and location metadata.
- Endpoint: `POST /api/agent/seo/generate`
- Scope: `seo:write` | Cost: 10¢
- Input: `{ articleId }`
- Output: `{ alternativeHeadline, faqs: [{ question, answer }], keywords, locationName }`
**suggest_images**
Get stock photos (Unsplash) or AI-generated images (DALL-E).
- Endpoint: `POST /api/agent/images/suggest`
- Scope: `images:write` | Cost: 10¢
- Input: `{ mode: "stock"|"ai", summary: "..." }`
- Output: `{ suggestions: [{ url, alt, caption, credit }] }`
**manage_redirects**
Create URL redirects (301/302/307/308). Upserts by path.
- Endpoint: `POST /api/agent/redirects`
- Scope: `redirects:write` | Cost: 2¢
- Input: `{ fromPath: "/old", toPath: "/new", statusCode: 301 }`
- Output: `{ id, fromPath, toPath, statusCode }`
**suggest_internal_links** (cross-content)
Score the tenant's published articles AND pages for relevance to a source (article or page) and suggest internal links plus the in-body context where each fits.
- Endpoint: `POST /api/agent/seo/suggest-links`
- Scope: `seo:write` | Cost: 15¢
- Two body shapes:
- Legacy (articles-only, preserved): `{ articleId, maxResults? }` — exact prior behavior.
- General: `{ source: { type: "article"|"page", id }, targetTypes?: ["articles","pages"], maxResults? }`. Default targetTypes when using `source`: both.
- Output items: `{ type: "article"|"page", title, url, relevance: "high"|"medium"|"low", context, slug? | path? }`. Articles also expose `slug`; pages expose `path`. URL is already-resolved (uses tenant.blogUrlPattern for articles).
- Defense-in-depth: identifiers are clamped to the candidate set per content type — an article slug can't be smuggled in as a page path (or vice versa), and titles are overwritten with the canonical row title so a misled admin can't be tricked into linking forged copy.
**audit_content_quality**
Editorial quality audit (clarity, hook, structure, completeness, CTA). Distinct from `/api/agent/seo/audit` which scores technical SEO.
- Endpoint: `POST /api/agent/content/audit`
- Scope: `articles:read` | Cost: 20¢
- Input: `{ articleId? }` — omit to audit the 10 most recent published articles
- Output: `[{ articleId, slug, title, qualityScore (0-100), summary, issues: [{ code, severity, message, suggestion }] }]`
### Rich-results JSON-LD via tenant metadata
Articles and PAGE-kind pages already emit base JSON-LD (BlogPosting on articles; Organization + WebSite + WebPage + BreadcrumbList on pages). Three metadata slots opt into the high-value rich-result schemas Google surfaces.
**On PAGE-kind pages** — `PATCH /api/agent/pages/{id}` writes into `metadata`:
- `metadata.description` (string) — renders as `` + `og:description` + `twitter:description`. Without it, Google scrapes body text → suppressed CTR.
- `metadata.schema` (object) — emits `SoftwareApplication` JSON-LD. Required: `applicationCategory`. Optional: `operatingSystem`, `offers: { price, priceCurrency }`, `aggregateRating: { ratingValue, reviewCount, bestRating?, worstRating? }`. Don't fake aggregateRating — Google penalizes fabricated ratings.
- `metadata.faqs` (array) — emits `FAQPage` JSON-LD. Shape: `[{ question, answer }]`. Triggers FAQ rich-results that expand SERP footprint.
**On Article pages** — `PATCH /api/agent/articles/{id}`:
- `excerpt` (top-level field) — same role as PAGE `metadata.description`. Renders meta + og + twitter description tags.
- `faqs` (top-level field, array `[{ question, answer }]`) — emits `FAQPage` JSON-LD alongside the existing `BlogPosting` node in the @graph.
All slots are opt-in — pages/articles without them keep emitting just the base graph. No regression. Verify after PATCH + redeploy with `curl | grep -oE '"@type":"[^"]*"' | sort -u` — should list the new node types when their metadata is populated.
### Snippets & Translations
**list_snippets / upsert_snippet**
Reusable content blocks (CTAs, disclaimers, author bios) embedded in articles or pages by name.
- Endpoints: `GET /api/agent/snippets` | `POST /api/agent/snippets`
- Scopes: `snippets:read` / `snippets:write` | Cost: 1¢ / 2¢
- Upsert input: `{ name, label?, content, description? }` — unique by `(tenantId, name)`
**translate_text**
Translate arbitrary text into a target locale via TranslationMemory cache + Sonnet 4.6 on misses.
- Endpoint: `POST /api/agent/translations/translate`
- Scope: `translations:write` | Cost: 15¢ (cache hits skip the model and are still 15¢ at the API surface, but free downstream)
- Input: `{ text, targetLocale: "es-ES"|"fr-FR"|..., sourceLocale?, context? }` — text max 20,000 chars
- Output: `{ translatedText, sourceLocale, targetLocale, cached, confidence }`
### Email Operations (Layouts, Mailboxes, Suppressions)
**list_email_layouts / upsert_email_layout**
Reusable email shells. Templates inherit the layout for one consistent header/footer/styles across welcome / receipt / newsletter emails.
- Endpoints: `GET /api/agent/email/layouts` | `POST /api/agent/email/layouts`
- Scopes: `email-layouts:read` / `email-layouts:write` | Cost: 1¢ / 2¢
- Upsert input: `{ name, wrapperHtml (must contain {{content}}), headerHtml?, footerHtml?, styles?, isDefault?, isActive? }`
- Response `meta.warnings`: advisory client-render pitfalls — `NO_DOCTYPE`, `NO_VIEWPORT`, `NO_CHARSET`, `NO_TABLE_LAYOUT`, `TABLE_NO_ROLE`, `FLEX_OR_GRID`, `NO_UNSUBSCRIBE`, `NO_MAX_WIDTH`, `NO_PREHEADER`. The layout saves regardless; fix them to render reliably across Outlook desktop, Gmail mobile, etc.
- CSS inlining: layout `styles` and `