9d9

Concepts

How 9d9 works: static deploys, claiming, forms and analytics.

9d9 hosts static sites. Sites are built and changed by AI — every change, from a typo to a redesign, is a new build pushed as a deploy. There is no CMS: the deployed folder is the site.

Static hosting

Every deploy is an atomic snapshot of a dist/ directory. Files live in R2 under a deploy_id prefix. A small KV entry per hostname points at the current deploy_id. When you activate a deploy we flip that pointer; old files stay around for a week so rollback is one tool call.

Request path

  1. Browser hits your-slug.9d9.dev/about.
  2. Render Worker reads host:your-slug.9d9.dev from KV — gets {org_id, current_deploy_id}.
  3. Tries R2 keys in order: about/index.html, about.html, then about.
  4. First hit is served. If none, returns the deploy's 404.html (or a generic).

Cache headers

File classcache-control
HTML (*.html, /)public, max-age=0, must-revalidate + ETag
Hashed (/_astro/, /_next/static/, *.HASH.*)public, max-age=31536000, immutable
Everything elsepublic, max-age=300, stale-while-revalidate=86400

Claiming

An AI can create a site and deploy to it before anyone has an account (POST /v1/sites, or the CLI with no key). Nothing is public yet: slug.9d9.dev shows "Not published yet". The response includes a claim link; the owner opens it, confirms with their email, and the site goes live as theirs. Unclaimed sites are deleted after 7 days.

The key the AI received keeps working after the claim — until then it can only deploy; afterwards it can also read contacts, attach domains and upload media.

Each network can create one site a day without an account and own up to ten. Signed in, you skip the claim step entirely: create a site in the dashboard and give your AI a key from its Settings page. Schools, agencies and shared offices can ask for more at app.9d9.dev/limits.

Forms

Point any form at the contacts endpoint. Submissions appear under Contacts in the dashboard.

<form action="https://api.9d9.dev/contacts/{org_id}/submit" method="POST">
  <input name="name"> <input name="email" type="email"> <textarea name="message"></textarea>
  <input type="hidden" name="_source" value="contact-form">
  <input type="hidden" name="_redirect" value="https://your-site/thanks/">
  <input name="_honeypot" tabindex="-1" autocomplete="off" style="position:absolute;left:-9999px">
</form>

It accepts form posts and JSON fetch() from any origin. _honeypot must stay empty (bot trap); _redirect sends plain-HTML submits somewhere after success.

Analytics

First-party, cookie-light pageviews. Add to every page's <head>:

<script src="https://api.9d9.dev/beacon" data-org="{org_id}" async></script>