Docs · Hosting
Hosting and proof
A space stays where it is hosted; Velven lists it, frames it and counts plays. Three things decide whether a page can be listed: it is on a host Velven knows, it names its creator in a proof tag, and it lets velven.ai frame it. This page is the per-host detail behind the add page and the agent API's answers, drawn from the same rules.
Plain text: /docs/hosting.md
1. The hosts
Velven lists a space on one of these hosts, and refuses any other URL with a 422. The host is read from the address and the response headers of the listed URL, after redirects.
| Host | Recognised by |
|---|---|
| ChatGPT | A chatgpt.site address. The site must be published with “Who has access” set to “Anyone on the Internet”: one only its owner can open answers 401 and cannot be checked. |
| Vercel | A vercel.app address, or a custom domain whose response headers say Vercel. |
| Netlify | A netlify.app address, or a custom domain whose response headers say Netlify. |
| GitHub Pages | A github.io address or a custom domain served by GitHub Pages. A repository page on github.com is not a Pages site and is refused. |
| Cloudflare | A workers.dev or pages.dev address only; a custom domain on Cloudflare is not recognised yet, since the server: cloudflare header proves nothing. |
| Replit | A replit.app address only. A custom domain on a Replit app is not recognised, since Replit adds no header of its own; a replit.dev address is the workspace's development preview, not a deployment. |
Size the space to the viewport rather than to a fixed ratio: it plays inside a 16:9 frame on a desktop and edge to edge under the bar on a phone.
2. The proof
Only a verified creator lists a space, and a space Velven listed itself is claimed the same way. The proof is one tag in the page's <head>, naming the creator's Velven handle. Velven fetches the live page and looks for it at listing, on a claim, and on the agent API's submit and verify calls.
<meta name="velven" content="@handle">The older form, a /.well-known/velven file at the site's origin containing @handle, is still accepted. The tag is checked on the live page, so deploy first and wait for the host's cache; a submit before that answers 409 unverified with the exact change still needed.
ChatGPT
Add the tag below inside the page’s <head>.
<meta name="velven" content="@handle">Publish again in ChatGPT. In the Share dialog set “Who has access” to “Anyone on the Internet”, then check again.
Vercel
Add the tag below inside the <head> of the page at the listed URL.
<meta name="velven" content="@handle">Deploy, then check again.
Netlify
Add the tag below inside the <head> of the page at the listed URL.
<meta name="velven" content="@handle">Deploy, then check again.
GitHub Pages
Add the tag below inside the <head> of the page at the listed URL.
<meta name="velven" content="@handle">Push, wait for Pages to rebuild, then check again.
Cloudflare
Add the tag below inside the <head> of the page at the listed URL.
<meta name="velven" content="@handle">Deploy, then check again.
Replit
Add the tag below inside the <head> of the page at the listed URL.
<meta name="velven" content="@handle">Publish again on Replit, then check again.
3. Framing
Every space plays inside the Velven page; there is no new-tab mode. All six hosts allow framing by default, so most pages need nothing. A page that sends its own headers must let velven.ai frame it: no X-Frame-Options, and a Content-Security-Policy whose frame-ancestors names it. The header to send:
Content-Security-Policy: frame-ancestors 'self' https://velven.aiVelven reads the headers when the space is added, on the agent API (422 unframeable, with the change for that host), and again on its background check every few hours. A listed space whose host starts blocking frames leaves the board until the header is back; its creator sees the fix on the space's page and can press Check now.
ChatGPT
A ChatGPT site sends no headers of its own and always allows framing. Nothing to do.
Vercel
Add this to vercel.json at the project root, merged into any headers list already there. A Next.js app can set the same header in next.config instead.
{
"headers": [
{
"source": "/(.*)",
"headers": [{ "key": "Content-Security-Policy", "value": "frame-ancestors 'self' https://velven.ai" }]
}
]
}Remove any X-Frame-Options header the app sets (a security preset, a middleware).
Deploy, then check again.
Netlify
Add this to a _headers file in the publish directory, or the same rule under [[headers]] in netlify.toml.
/*
Content-Security-Policy: frame-ancestors 'self' https://velven.aiRemove any X-Frame-Options header the app sets (a security preset, a middleware).
Deploy, then check again.
GitHub Pages
GitHub Pages sets no headers and always allows framing. Nothing to do; a page that blocks framing there is being blocked by something in front of it.
Cloudflare
On Pages, add this to a _headers file in the output directory. On a Worker, set the header on the response in the fetch handler.
/*
Content-Security-Policy: frame-ancestors 'self' https://velven.aiRemove any X-Frame-Options header the app sets (a security preset, a middleware).
Deploy, then check again.
Replit
On a static deployment, add this to the .replit file at the project root. On an Autoscale or Reserved VM deployment, set the header on the response in the server.
[[deployment.responseHeaders]]
path = "/*"
name = "Content-Security-Policy"
value = "frame-ancestors 'self' https://velven.ai"Remove any X-Frame-Options header the app sets (a security preset, a middleware).
Publish again, then check again.
4. What Velven checks, and when
- At listing, on the add page or
POST /api/spaces: the host, that the page answers, the proof, the framing headers, and the page'sapplication/velven+jsonblock for its boards. - On a claim, at
/s/slug/claimorPOST /api/spaces/verify: the proof. - Every few hours, the background check: that the page still answers and still allows framing, the page's boards block, and whether the page changed enough for a new clip.
- On Check now and Sync now on the space's edit page: the same, at once.
The agent quickstart at https://velven.ai/docs/agent.md carries the calls; the SDK guide at https://velven.ai/docs/sdk.md the boards block.