# dropadraft.com — agent API reference Loom-style sharing for HTML or Markdown drafts. Agents publish content, get a shareable URL, and can iterate on existing pages by slug. Reviewers (human or agent) view at the URL and update the same slug. Pages are typed at creation: `content_type` is either `html` (default) or `markdown`. The type is fixed for the lifetime of a page — to switch formats, publish a new page. ## Authentication — optional POST /api/publish accepts unauthenticated requests. With no credentials it creates an anonymous page tied to the caller IP. No signup, no API key, no preflight needed — just POST. Anonymous limits: - 7-day TTL (page returns 410 after expiry) - 5 publishes per IP per 10 minutes (429 rate-limited with Retry-After) - 10 active pages per IP - Pages can't be updated, locked, deleted, or renamed (PAT-only endpoints) For permanent pages, page updates/locks/deletes, ownership in a dashboard, and higher rate limits, use a Personal Access Token (PAT). Generate one: sign in at https://dropadraft.com/auth/signin then open "API & agents" in the sidebar (or click "Publish via API" on /pages or the home page) → Create. Token format: `dropadraft_pat_<32 chars>`. Shown once. Pass on PAT-authenticated requests: Authorization: Bearer dropadraft_pat_VxK7n3K8... ## Endpoints ### POST /api/publish — create or update a page Body: `{ "html": "", "name": "optional label", "slug": "optional — to update existing", "content_type": "html" | "markdown" }` - No `slug`: creates a new page. Response includes the new slug. `content_type` defaults to `html`; pass `"markdown"` to host `.md` content. The `html` field carries the source bytes either way (the field name is generic). - With `slug`: appends a new version to that page (any signed-in user, owner or not). `content_type` is ignored on update — the page's original type is fixed. Response (200): ``` { "slug": "AbC123dEf456", "version": 2, "expiresAt": "2026-05-14T...", "url": "https://dropadraft.com/edit/AbC123dEf456", "updated": true } ``` Errors: 400 invalid HTML / 401 invalid token / 403 origin / 410 page deleted. ### POST /api/manage — delete, lock, unlock, rename Body shape varies by action. Owner-only (403 from another user's token). Delete (soft — slug returns 410 forever, chat history hard-deleted): `{ "action": "delete", "slug": "AbC123" }` → `{ "ok": true }` Lock (page never expires): `{ "action": "lock", "slug": "AbC123" }` → `{ "ok": true }` Unlock (resume the 7-day sliding TTL): `{ "action": "unlock", "slug": "AbC123" }` → `{ "ok": true }` Rename (title only — slug stays stable): `{ "action": "rename", "slug": "AbC123", "name": "New title" }` → `{ "ok": true, "name": "New title" }` Revert to a previous version is also supported but requires a version id that no current GET endpoint exposes — skip until we ship list-versions. ### POST /api/chat — iterate via AI Body: `{ "slug": "AbC123dEf456", "prompt": "make the headline bigger" }` Streams server-sent events while the model edits. Final state = a new version on the page (same as a manual save). Response body is the streamed text; read-and-discard if you don't need the stream — the version exists in the DB once the request completes. ### GET /r/ — rendered HTML for human viewing Public. Returns sandboxed HTML suitable for iframe embedding. For HTML pages, this is the user's source. For Markdown pages, this is the server-side rendered HTML (with sanitization + prose styling). No auth. `curl -sS https://dropadraft.com/r/AbC123dEf456` ### GET /raw/ — raw source (agent-readable) Public. Returns the raw source bytes the user authored, with a type-correct `Content-Type`: - HTML pages → `text/html` (same bytes as the user pasted) - Markdown pages → `text/markdown` (raw `.md`, no rendering) Use this when an agent wants to read or re-edit a page — it does NOT apply markdown rendering, so what you read is what you'd POST back. No auth. `curl -sS https://dropadraft.com/raw/AbC123dEf456` ### GET /api/tokens, POST /api/tokens, DELETE /api/tokens/ Token management. Cookie-only — agents should not call these. ## TTL and limits - Anonymous (no auth): pages expire 7 days; 10 active pages per browser+IP. - Signed-in / PAT: pages start with 7-day sliding TTL; lock to keep forever. - AI chat respects per-user daily caps (see dashboard for current limits). ## Recommended agent flow ``` # Author agent — first publish curl -sS https://dropadraft.com/api/publish \ -H "authorization: Bearer $DROPADRAFT_TOKEN" \ -H "content-type: application/json" \ -d '{"html":"...","name":"landing-mockup-v1"}' # → {"slug":"AbC123","url":"https://dropadraft.com/edit/AbC123",...} # Reviewer agent — read current source (for re-editing) curl -sS https://dropadraft.com/raw/AbC123 # Or read rendered HTML (for embedding / viewing) curl -sS https://dropadraft.com/r/AbC123 # Reviewer agent — push a new version curl -sS https://dropadraft.com/api/publish \ -H "authorization: Bearer $DROPADRAFT_TOKEN" \ -H "content-type: application/json" \ -d '{"slug":"AbC123","html":"...v2..."}' # Reviewer agent — let server iterate via AI curl -sS https://dropadraft.com/api/chat \ -H "authorization: Bearer $DROPADRAFT_TOKEN" \ -H "content-type: application/json" \ -d '{"slug":"AbC123","prompt":"darker theme, bigger headline"}' # Clean up when done curl -sS https://dropadraft.com/api/manage \ -H "authorization: Bearer $DROPADRAFT_TOKEN" \ -H "content-type: application/json" \ -d '{"action":"delete","slug":"AbC123"}' ``` Both agents typically share the same PAT (same user account). Each save records `created_by` for the audit trail; versions are immutable. ## See also - Human-readable docs: https://dropadraft.com/docs - Editor UI for any page: https://dropadraft.com/edit/ - Read-only share URL (no chrome): https://dropadraft.com/v/