https://<org-slug>-<project-slug>.ravi.page/<route>, and you will know how to choose who can open it, protect it with a password, read comments on it and roll it back.
You need a Console login and a default project first: see Log in to the Console.
This page describes
ravi.bot@next. In @latest (3.260927.5), ravi pages ship is a dry-run unless you pass --execute, and it creates a separate host named after --title instead of using the project host. Install @next with bun add -g ravi.bot@next, or switch an existing install with ravi update --next.How Pages is organized
- A project has one default host:
<org-slug>-<project-slug>.ravi.page, for exampleacme-website.ravi.page. - A page is a route on that host.
/is the project home;/reportand/docsare other pages. --titleis the page title. It never creates a host.- Do not create one host per page. The host name
raviand names starting withravi-are reserved and cannot be created.
Publish your first page
1
List the routes already published
ravi pages list --project website --json shows the host itself; the default one has isDefault: true.2
Ship the page
--json, the output lists the host, then the route, its visibility and the URL, then a Comments line (see comments):ship creates <org-slug>-<project-slug> and gives it this ship’s --visibility as its default.3
Open the URL
The page is
private by default: open it while signed in to the Console with an account that can read the project. To open it to everyone, see Visibility.What ship takes
Pass --title and exactly one content source:
Defaults:
--route /, --visibility private, --entrypoint index.html. --project overrides the saved project scope. --json returns { url, site, slug, route, visibility, artifactId, uses?, warnings? }.
ship publishes immediately. --execute is accepted and ignored. If a ship fails, read the error before retrying; do not probe by shipping again.
Visibility
For
private pages, the visitor’s active organization in the Console must be the page’s organization. People in several organizations may need to switch organization in the Console first.
Host default and route policy
Two settings decide what a visitor gets:- The host default, set when the host was created: the Default visibility field,
--visibilityonravi projects create --default-page-site, or the--visibilityof the first ship when that ship created the host. - The route policy, set by every ship (
--visibility, defaultprivate).
public, the route policy applies. If the route is public, the host default applies. So a page is public only when both the route and the host default are public.
Change visibility without uploading anything:
- The first argument is the host slug (
<org-slug>-<project-slug>), as shown byravi pages list. - Without
--route, only the host default changes. Routes shipped with the defaultprivatestay private. - With
--route, only that route changes. The output shows the effectiveVisibilityand the hostDefault. - Switching to
publicis a dry-run without--execute: it prints the plan (host or route, current and target) and exits 3. Lowering visibility applies immediately.
private host, run both: ravi pages visibility <host> public --execute and either ship with --visibility public or set the route with --route.
There is no unpublish command. To take a page down, lower it: ravi pages visibility acme-website private --route /hello.
Password
--route defaults to /.
For automation, pipe the password from a protected file with --stdin:
remove requires a replacement --visibility, so removing a password never makes a page public by accident.
Share a page with one person
To show a private page to one person, share it with their email. Do not make the route public or add a password for that.- The person signs in to the Console with that email (verified) and sees only what was shared: the route, or with
--siteevery private route of the host. It is not membership: no operator bar, no voice Page Chat and no live Bases data. They can use the text chat of the routes shared with them, from the floating guest link. --expirestakes30d,12h,2wor an ISO date, up to 365 days. Sharing again updates the expiry and reason.unshare --grant <id>removes one grant by the idpages accesslists.- Anyone who can publish to the project can share: an organization
owner,adminordeveloper, or a project admin or developer.
viewer (default), developer, admin, billing and owner. Only an owner or admin invites, and only an owner invites an owner.
When a page answers that you have no access, ask its managers:
ravi link (to share or invite, both of you must have the role; a request is made in their name). A person without a link gets ACTOR_NOT_LINKED, and Ravi starts their link itself: on WhatsApp the agent asks them to message it in private, where Ravi sends the approval link. To let a narrower agent use them, grant mutate:pages.access:*, read:pages.access:*, mutate:invites:*, read:invites:* or mutate:access.requests:create as needed.
The operator bar and comments
When a project member opens a page from the Console (the project’s Pages list), a bar appears at the top of the page. Ordinary visitors never see it. Its labels are in Portuguese today. From the bar you can:- see and change the page visibility, and manage the route password;
- Comentar: leave a comment on an item of the page;
- Mais opções → Histórico de releases: list releases, see Mudanças (changed files and line diffs) and Restaurar an older release.
ravi pages ship prints a Comments line about a comment trigger, but the Console does not emit the event that trigger listens to, so it never fires. If people need to send feedback that wakes the agent, give them a form backed by a Base and a trigger, see Interactive pages with Bases.
Page Chat (voice agent)
Page Chat is a voice agent inside every page. A signed-in viewer taps Falar in the Pages bar and talks to an agent that operates the page for them. It acts as that viewer only: it cannot do anything the viewer could not do. Page Chat shows on a site only when the site setting is on and the organization featureconsole.pages.chat is on. Organizations that already existed when Page Chat launched have it on by default.
- The first argument is the host slug, the site id or the hostname.
setchanges only the flags you pass.--enabled trueturns on metered voice usage for every signed-in viewer of the site, so without--executeit prints the plan and exits 3.- Voices:
bossa(default, Brazilian Portuguese, feminine),tempo(Brazilian Portuguese, masculine),marin,quartz,ripple,vesper,willow,stone,gleam,meridian,beacon,delta,cinder.--languageis a BCP 47 tag (defaultpt-BR).--nametakes up to 60 characters and--instructionsup to 2,000. featureEnabledin the JSON is the organization feature;settings.enabledis the site.
aria-labels decide what it can find. A page can also register actions the agent may call:
push form: it works on every page, and the runtime reads the list where Page Chat is on. Action names use letters, digits, _ and -, up to 64 characters. A write action runs only after the viewer confirms by voice.
Text chat
Every page also has a text chat with Ravi. In the Pages bar, the Fale com o Ravi field opens a chat panel docked on the right (a bottom sheet on narrow screens), with a dot when there are unread messages. To put the chat inside a page, add the tag where it should go; the chat fills its container:min-height: 70vh, or make a page that holds only the chat.
Rooms. Each route has one shared room, where everyone who opens that page talks together, and each person has a private room on that route with the agent. Comments left with Comentar also show up in the shared room, pointing at the item they are about. The voice Page Chat is a mode of the same conversation: what is said becomes messages in the room.
Who can talk. Members of the organization who can read the project, and guests the route or site was shared with. Nobody signed out. The agent knows who wrote each message.
When the agent answers in a shared room:
- when someone calls it with
@ravior@followed by the assistant name (--name); - when someone clicks one of the buttons in its answers;
- while only one person has written in the room, since it is still a one-to-one conversation;
- to every message, when the site’s reply policy is
always.
--uses) and the knowledge marked for page viewers. Answers can include blocks besides text: a widget from your organization’s Library, a Bases view, a chart, buttons and a card. A view travels by reference: each person’s browser loads the rows with that person’s own access, so two people in the same room can see different rows.
Conversations as a Base. When your organization has Bases, the messages of shared rooms are also copied into a read-only Base of the project, conversas-pages (view Conversas, one row per message: text, who wrote it, member, guest or agent, text, voice or comment, page and time). Project members can read it like any other Base, so an agent can search or chart conversations with ravi bases. Private rooms are never copied, and a deleted message loses its text there too.
The text chat uses the same organization feature, console.pages.chat, and each agent turn is metered for the organization. Its settings live next to the voice ones:
--textturns the text chat on or off;--enabledstays the voice switch. By default the text chat is on, the reply policy ismention, the model is the platform default and no Ravi agent is set.--text true,--reply-policy alwaysand--ravi-agentwiden what the agent does, so without--executethey print the plan and exit 3. Turning things off, going back tomention, changing the model and the--clear-*flags apply at once.--text-modeltakes an AI Gateway model id,<provider>/<model>.ravi pages chat showlists the text chat, reply policy, text model and Ravi agent next to the voice settings (settings.text,settings.replyPolicy,settings.textModel,settings.raviAgentin the JSON).
Let the chat ask your Ravi
--ravi-agent <installation-id>/<agent> lets the page’s agent ask an agent on one of your organization’s Ravi machines, for example to look something up that only that machine knows. The question travels as a Library request, the same way agents on two machines ask each other:
- Find the installation id with
ravi agents directory --json(installation.idof the agent’s entry). - On that machine, open the agent to requests:
ravi agents requests finance on --execute. - Point the site at it:
ravi pages chat set acme-website --ravi-agent <installation-id>/finance --execute.
Releases and restore
Every publish creates a release of the whole host: the map of all its routes. Restoring a release brings every route on the host back to that state, not just one page. Restore from the operator bar (Restaurar). An unread comment on any route in that release blocks the restore. The project’s Pages screen in the Console lists the release history but has no restore button. To roll back a single page, ship its previous content to the same route again.ship also records each publish on a local artifact (art_*), so ravi artifacts release activate can re-activate a recorded release from the terminal. The artifactId that ship prints is the Console’s id, not the local one; see Artifacts for how to find it. The bar is the simpler path.
Let your agent publish
Your agent runs the sameravi pages ship through the daemon, using the daemon’s Console login. It publishes as you: your role, your name on the release, and your unread comments.
-
Run
ravi loginas the same OS user as the daemon (sameHOMEorRAVI_STATE_DIR). No daemon restart is needed. -
Give the agent Pages permissions. An agent with the
full-accessprofile (see Make yourself the owner) already has them. A narrower agent needs them in its capability list:--capabilitiesreplaces the list, so repeat the capabilities the agent already has.execute:group:pagesalso works for shipping and listing, but not forravi pages password. See Permissions. - Ask the agent, for example: “Publish ./report as /report on the website project.”
--dir upload can time out on the agent’s side even though the publish finished; check ravi pages published before shipping again.
Let your agent read a page
When you send your agent a Page link, it reads it withravi pages read instead of a browser. A browser would stop at the Console login on a private page; pages read goes through the Console with the daemon’s login and returns the page as Markdown, with its links and the host’s other routes.
- The agent picks the format. The default Markdown is the page’s text without its styles, layout or images, and the output says so.
--format htmlreturns the entry file’s source, and--format zip --out <file>(or--format files --out <dir>) downloads every published file, so the agent can see the design or build a page in the same style. - Public routes are always readable. Private,
protected_linkand password routes are read only on your own turns (the terminal, your direct chat with the agent, routines you own) and only when your login can read the project. When someone else sends the agent a private link, the command exits 3 and the agent tells them it cannot open it. - The read is static: the published file, not run in a browser. A data page built with JavaScript shows little text, and the result says so.
- Ravi blocks browser and fetch tools aimed at
*.ravi.pagelinks and points the agent toravi pages read. Every read of a private route is recorded in the Console audit log.
Custom domains
ravi pages domains <host> <hostname> binds a domain you own to a host. Without --execute it prints the DNS to create and writes nothing. With --execute it moves the setup forward and exits with DOMAIN_SETUP_REQUIRED while DNS work is pending. The message names the step (ownership, DNS, certificate) and the exact records; run the same command again once DNS has propagated.
ravi pages list shows each host’s custom domains. A pending one says why it does not serve yet, the DNS still missing and the command to check again; ravi pages published lists pending ones below the pages. Only ready domains appear in urls, so a hostname missing there does not serve the host, even when it answers 200 from another server.
The root domain (
example.com) serves the host directly when your DNS provider supports a CNAME at the root (CNAME flattening on Cloudflare, ALIAS or ANAME elsewhere). Plain A records are not supported. A subdomain that was never bound answers Cloudflare’s 522 error instead of a Pages 404.
Data pages
Pages that read and write a Base (--uses ravi.bases.*) work only for signed-in members of the organization, on private or protected_link routes. ship refuses them on a public route (exit 2) unless you pass --members-best-effort on purpose. --uses applies to the whole host. See Interactive pages with Bases.
Advanced and compatibility commands
Use
ravi pages ship for new pages. ravi skills show pages prints the agent-facing guide with more examples.