---
name: vibiz-use-one
description: Use just one Vibiz Stack service (sign-in, database, payments, email, AI, analytics, replay, files, web data, connectors, social, company) from an app NOT hosted on Vibiz - another host, a plain HTML site, a mobile app's backend, a cron job or a script - creating a project with only that resource, adding the app's domain as running elsewhere, and giving the app its one key. Use when someone wants one Vibiz feature without deploying on Vibiz, or the app already runs somewhere else.
---

# Use one Vibiz service, from an app hosted anywhere

**Connect first.** Not logged in (`unauthorized` with `reason: not_logged_in`, or the CLI says "Not logged in")? Run `npx @vibiz/cli login`, show the person the link it prints and ask them to click Authorize. Never ask them to paste a key into the chat. **Keep the CLI current:** a command named here that your `vibiz` doesn't have (an unknown-command or usage error) means the CLI is out of date, not that Vibiz can't do it: run `npm install -g @vibiz/cli@latest` (or `npx -y @vibiz/cli@latest <command>`) and retry, and refresh these skills with `vibiz skills add --global`. Never tell the person something isn't possible because an old CLI lacks the command.

Every service works on its own. Never tell the person they must deploy on Vibiz to use one: a project is just the services they pick, and none needs `hosting`.

## Pick what to create

| They want | Create with | Domain (step 2) | In the app |
| --- | --- | --- | --- |
| A Postgres database | `--resources database` | no | `DATABASE_URL` |
| Sign-in | `--resources auth` (brings the database) | **yes** | `VIBIZ_AUTH_*` from the env |
| To take payments | `--resources none` | for webhooks | `vibiz.payments.checkout({ lookup_key, user, success_url, cancel_url })` |
| To send email | `--resources email` | no | `vibiz.email.send({ to, subject, text })`, from `@<slug>.vibiz.app` |
| hello@their-domain to their inbox | `--resources none` | its DNS | `vibiz email forward hello@example.com <inbox>` (owner) |
| AI models | `--resources ai` | no | `new OpenAI(vibiz.ai)` |
| Visitor analytics | `--resources analytics,replay` (replay too, unless they said no) | **yes** | the tag from `vibiz analytics snippet` |
| Session replay | `--resources replay` (brings analytics) | **yes** | the same tag, then `vibiz('replay', 'start')` after the visitor consents |
| Files with permanent links | `--resources none` | no | `vibiz.files.upload(bytes, { name })` |
| Scraping, search, ads library | `--resources none` | no | `vibiz.actions.run('web.scrape', { url })` (or the CLI and MCP tools, no app at all) |
| An outside API with its key kept safe | `--resources none` | no | a connector (see the vibiz-connectors skill) |
| Social posting, company formation | `--resources none` | no | no app code: the CLI, console or MCP tools |

`--resources payments` (or files, social, company…) makes the same empty project as `none` and says so. Several at once: `--resources auth,ai,email`. Whenever analytics is set up, add `replay` with it unless the person said no to recordings: it records only after the visitor consents (the site calls `vibiz('replay', 'start')` from its own consent prompt), and tell them where to watch (the vibiz-analytics skill).

## Steps

0. **Is the app already live somewhere?** Find out before creating anything, because its real address decides where sign-in, analytics and payment events point. Look in the folder (`.vercel/project.json`, `vercel.json`, `netlify.toml`, `fly.toml`, `render.yaml`, `wrangler.toml`, `CNAME`, `package.json` `homepage`, the README, the git remote), and **ask the person** "Where is it live? (e.g. https://yourapp.com)" when unsure. Never assume `<slug>.vibiz.app`: nothing answers there unless the app was deployed on Vibiz. Then pass that domain at creation (`vibiz init "<name>" --resources <…> --domain yourapp.com`), or add it right after (step 2), and save it in your notes for the project.
1. **Create.** `vibiz init "<name>" --resources <one>` in the app's folder (it writes `./vibiz.json`), or `vibiz_create_project { name, resources: ["auth"] }` (`resources: "none"` for none). Already have a project? `vibiz add <resource>` or `vibiz_add_resources`.
2. **The app's domain, when the table says so.** Run `vibiz domains add app.example.com --elsewhere` (an agent key may: analytics and replay count it at once; sign-in trusts it once proven: if you can edit the domain's DNS, add the TXT record in `trust_record` (`_vibiz.<domain>` = `vibiz-verify=…`) and run `vibiz domains verify <domain>`; otherwise the owner confirms it in the console ▸ Domains, so give them the domain's console link when sign-in is needed). Sign-in trusts it, analytics counts visits from it, payment events may go there. Every domain the app answers on (`www.` comes along).
3. **The key.** The host gets ONE secret, `VIBIZ_APP_KEY`: the owner copies it from the console. Give them the link itself, never directions: `vibiz_project_env { project_id }` returns `app_key_console_url` (it opens the production key ready to copy), and any `owner_only` error carries a `console_url` to hand over (`vibiz env` from an agent key answers `owner_only` with the env page's link). You never see or print it. The app loads the rest at start:
   - Node, Bun, Deno: `import { vibiz } from '@vibiz/app'; await vibiz.loadEnv();` (`npm install @vibiz/app`)
   - Any language: `npx @vibiz/cli run -- <start command>`
   - A build step or CI: `npx @vibiz/cli env pull --format dotenv -o .env.production`
   - A host Vibiz can write the env into (vercel, netlify, render, railway, fly, heroku, cloudflare-workers, cloudflare-pages, github-actions; `vibiz hosts add` alone lists them): the owner runs `vibiz hosts add <host> <app>` once (owner key; the host's token from its usual variable, like `VERCEL_TOKEN`, or a hidden prompt), and the values stay in sync by themselves. `vibiz_hosts { project_id }` shows them; `sync: true` pushes again now.
   `vibiz connect` in the folder detects the host and prints the right one.
4. **Local work.** `vibiz dev` (or `vibiz_dev_env`) writes the development copy to `.env.development.local`: its own app key, database branch with no production rows, sign-in trusting `http://localhost:3000`.

## Payments on another host

Events go to the app's real site: once its domain is on the project (`--elsewhere`, trusted), the live webhook defaults to `https://<that domain>/api/vibiz/webhook`, and a webhook left on the unused `<slug>.vibiz.app` address moves there by itself. Check it with `vibiz_payments { action: "get", env: "production" }`: if `webhook.url` isn't on the site where the app is live, fix it. To set another path, an agent key may set a live URL on a domain the project already has, over HTTP: `PATCH /v1/projects/<id>/payments?env=production { "webhook_url": "https://app.example.com/api/vibiz/webhook" }` (the MCP tool and `vibiz payments webhook` from an agent key change development only); any other URL needs the owner. The route checks each event with `const event = await vibiz.webhooks.receive(req)`, which needs only `VIBIZ_APP_KEY` (never ask for `VIBIZ_WEBHOOK_SECRET` on the host). `success_url` and `cancel_url` are any `https` address on their site. Details: the vibiz-payments skill.

## Gotchas

- **The app key is a server secret.** `@vibiz/app` refuses to run in a browser. A static site or a mobile app calls its own backend (a server route, a serverless function) that holds the key. Only the analytics site key is public.
- **Sign-in or analytics refused a request?** The origin isn't one of the project's domains: the owner adds it with `--elsewhere`.
- **Rotating the key**: `vibiz app-key rotate` (production needs an owner key; `--dev` for development). The new key goes to Vibiz hosting and connected hosts by itself and is never printed; the old one keeps working for a day (`--grace <seconds>`, `0` ends it now). A host holding a pasted key needs the new one before then. The app reads its env fresh on each start, so it follows after a restart.
- **Needs Vibiz hosting:** `vibiz deploy`, previews, rollback, buying a domain (`hosting_required`: connect one bought elsewhere with `--elsewhere` instead), and the code part of an export. Adding hosting later (`vibiz add hosting`) pushes every key there by itself.

## References

- `references/use-one.md`: the full page, per service, with examples.
- `references/keys.md`: keys, environments, getting the env to a host.
- `references/app-sdk.md`: every `@vibiz/app` call and its HTTP route.
