# folio — agent-first document and presentation service folio is a private, agent-first document and presentation service for AWID teams. This is an aweb anapp: an agent-native app published by convention for the aweb.ai hub index. Agents authenticate with an AWID team certificate using aw id request --team-auth. AWID is the identity authority: https://awid.ai Aweb anapp hub: https://aweb.ai There are no app-local accounts, passwords, OAuth sessions, public document listings, or user-content feeds. Origin: - Production: https://folio.aweb.ai - Local development: http://127.0.0.1:8765 Core commands use the aw-native signed request path: ```bash export FOLIO_ORIGIN=https://folio.aweb.ai aw id request POST "$FOLIO_ORIGIN/v1/documents" --team-auth --raw --body '{"slug":"pitch","title":"Pitch","body":"# Pitch"}' aw id request POST "$FOLIO_ORIGIN/v1/documents" --team-auth --raw --body '{"slug":"deck","title":"Deck","template":{"name":"pitch","slots":{"cover":{"title":"Deck"},"sections":[]}}}' aw id request POST "$FOLIO_ORIGIN/v1/documents/pitch/versions" --team-auth --raw --body-file pitch-v2.md aw id request POST "$FOLIO_ORIGIN/v1/documents/deck/versions/template" --team-auth --raw --body '{"name":"memo","slots":{"cover":{"title":"Deck v2"},"sections":[]}}' aw id request POST "$FOLIO_ORIGIN/v1/assets" --team-auth --raw --body-file image-upload.json aw id request POST "$FOLIO_ORIGIN/v1/assets/video/direct-upload" --team-auth --raw --body '{"content_type":"video/mp4","max_duration_seconds":600}' aw id request PUT "$FOLIO_ORIGIN/v1/theme" --team-auth --raw --body-file theme.json aw id request POST "$FOLIO_ORIGIN/v1/present" --team-auth --raw --body '{"slug":"pitch","ttl_seconds":86400}' aw id request POST "$FOLIO_ORIGIN/v1/present//revoke" --team-auth --raw ``` Declarative templates: - Template slots are schema-validated and rendered to ordinary Markdown before storage; presentation falls back to the same themed Markdown renderer. - pitch slots: cover, metrics, sections, ask - memo slots: cover, sections - metrics slots: cover, metrics - cover fields: title (required), subtitle, eyebrow - metrics item fields: label (required), value (required), caption - sections item fields: heading (required), body - ask fields: headline, body, items (array of strings) - Create docs with JSON: {"slug":"deck","title":"Deck","template":{"name":"pitch","slots":{"cover":{"title":"Deck"},"metrics":[{"label":"Metric","value":"Value","caption":"Note"}],"sections":[{"heading":"Problem","body":"Markdown body"}],"ask":{"headline":"Ask","body":"Approve launch","items":["Ship"]}}}} - Append template versions with POST /v1/documents/{slug}/versions/template and body: {"name":"memo","slots":{"cover":{"title":"Update"},"sections":[{"heading":"Status","body":"Markdown body"}]}} Team-auth endpoints: - POST /v1/documents — JSON {slug,title,body} - GET /v1/documents — list team documents - GET /v1/documents/{slug} — current version - GET /v1/documents/{slug}/versions — version metadata - POST /v1/documents/{slug}/versions — raw UTF-8 Markdown body - POST /v1/documents/{slug}/versions/template — JSON built-in template version body - POST /v1/assets — upload safe raster image bytes - POST /v1/assets/video/direct-upload — create Cloudflare Stream direct upload - GET /v1/assets/{asset_id} — poll team-scoped image/video asset metadata - GET /v1/theme, PUT /v1/theme — team presentation theme - POST /v1/present — mint read-only capability link - POST /v1/present/{token}/revoke — revoke a team-owned link - GET /v1/billing — current v1 caps and usage Public endpoints: - GET / — human landing page - GET /llms.txt — this agent-readable entrypoint - GET /skills/ — skill index - GET /skills/create-from-template/SKILL.md — create documents from built-in templates - GET /skills/present-to-human/SKILL.md — mint/open/revoke present links - GET /skills/set-theme/SKILL.md — brand presentation pages - GET /skills/team-cert-verification/SKILL.md — verifier checklist - GET /present/{token} — server-rendered capability page for a pinned version - GET /assets/{asset_id} — public media bytes reachable only from capability pages - GET /robots.txt — crawler policy for user-content paths Privacy/noindex policy: - All user content is capability-link private and noindex: /present/* and /assets/* responses include X-Robots-Tag: noindex, nofollow, noarchive. - /present/* pages also include . - robots.txt disallows /present/ and /assets/. Important invariants: - AWID is authority for team keys, certificates, and revocation. - Every document, asset, theme, and present-link mutation is scoped to the verified certificate team_id. - Versions are append-only; edits create new versions. - Team-supplied Markdown is sanitized. Raw iframes are stripped; Cloudflare Stream iframes are generated only by the server for ready video assets. - folio stores server-readable text and media metadata. Do not call it end-to-end encrypted. Source of truth: - docs/sot.md - README.md - docs/spine-sot.md - aweb.ai hub: https://aweb.ai - AWID identity authority: https://awid.ai