# Use one service

> Use just one Vibiz service - sign-in, a database, payments, email, AI, analytics, files, web data - from an app hosted anywhere, a plain site, a mobile app's backend or a script.

Every Vibiz service works on its own. The app doesn't have to be deployed on Vibiz: it can run on another host, be a plain HTML site, a mobile app's backend, a cron job or a script. A project is just the services you pick, and none of them needs `hosting`.

## Three steps

1. **Create a project with only what you need.** `vibiz init <name> --resources <one>` (MCP: `vibiz_create_project { name, resources: ["auth"] }`). Payments, files, web data, social, company and connectors need no resource: `--resources none` (or naming them, `--resources payments`, makes the same empty project).
2. **Add the app's domain as running elsewhere**: `vibiz domains add app.example.com --elsewhere`. From an agent key, analytics counts it at once and sign-in trusts it once its TXT record (`trust_record`, `_vibiz.app.example.com`) is in and `vibiz domains verify app.example.com` finds it, or the owner confirms it in the console. Sign-in trusts it, analytics counts visits from it, and payment events may be sent to it. Not needed for a script or a server with no web address.
3. **Give the app its key.** One secret, `VIBIZ_APP_KEY`, reaches everything the project has: an owner copies it from the console and puts it in the host. An agent hands them the link that opens it ready to copy (`app_key_console_url` from `vibiz_project_env`), never directions. The app loads the rest at boot:

```ts
import { vibiz } from '@vibiz/app';
await vibiz.loadEnv(); // DATABASE_URL, VIBIZ_AUTH_*, VIBIZ_WEBHOOK_SECRET… into process.env
```

Any language: `npx @vibiz/cli run -- <start command>`. A build step or CI: `npx @vibiz/cli env pull --format dotenv -o .env.production`. A connected host (`vibiz hosts add <host> <app>`) gets the values written for it instead. For local work, `vibiz dev` writes the development copy (its own key, no production data) to `.env.development.local`.

## Per service

| Service | Create with | Domain needed | The app uses it with |
| --- | --- | --- | --- |
| Database | `--resources database` | no | `DATABASE_URL`, plain Postgres over the internet |
| Sign-in | `--resources auth` (brings the database) | yes, the app's web address | `VIBIZ_AUTH_*` from the env ([Sign-in](https://app.vibiz.app/docs/sign-in)) |
| Payments | `--resources none` | for webhooks | `vibiz.payments.checkout(…)` with any `https` `success_url` and `cancel_url`; events at the webhook URL the owner sets (`vibiz payments webhook <url>`) |
| Email | `--resources email` | no | `vibiz.email.send(…)` from `<mailbox>@<slug>.vibiz.app` |
| Email at your own domain | `--resources none` | its own DNS | `vibiz email forward hello@example.com <inbox>` (owner), no app code |
| AI | `--resources ai` | no | `new OpenAI(vibiz.ai)`: OpenAI-compatible, metered per call |
| Analytics | `--resources analytics` (add `replay` too, unless the person doesn't want recordings) | yes | the tag from `vibiz analytics snippet` before `</head>`; server events with `vibiz.track(…)` |
| Session replay | `--resources replay` (brings analytics) | yes | the same tag; `vibiz('replay', 'start')` once the visitor consents |
| Files | `--resources none` | no | `vibiz.files.upload(bytes, { name })` returns a permanent link |
| Web data | `--resources none` | no | `vibiz.actions.run('web.scrape', { url })` and every other action |
| Design | `--resources none`, or no project at all | no | `vibiz design <url> --tailwind`, or `vibiz.actions.run('web.design', { url })`: the theme and brief work in any stack |
| Connectors | `--resources none` | no | `vibiz connectors add …`; the app calls them through Vibiz with its key |
| Social | `--resources none` | no | the owner connects accounts once (`vibiz social connect <platform>`); posts from the CLI, the console or an agent |
| Company formation | `--resources none` | no | `vibiz company draft`, the owner files |

Without the package, every call above is an HTTP route under `/v1/app` with `Authorization: Bearer $VIBIZ_APP_KEY` ([@vibiz/app](https://app.vibiz.app/docs/app-sdk)).

## Examples

A Next.js app on another host that only takes payments:

```bash
vibiz init shop --resources none
vibiz domains add shop.example.com --elsewhere      # agent key: then its TXT record + verify
vibiz payments products add Pro --amount 900 --interval month --lookup-key pro-monthly
vibiz payments webhook https://shop.example.com/api/vibiz/webhook   # owner key (production); agent keys set development
```

Once the domain is trusted, the live webhook defaults to `https://shop.example.com/api/vibiz/webhook` anyway; an agent key can set a live URL on one of the project's domains with `PATCH /v1/projects/<id>/payments?env=production`.

```ts
import { vibiz } from '@vibiz/app';

const { url } = await vibiz.payments.checkout({
  lookup_key: 'pro-monthly',
  user: session.userId,
  success_url: 'https://shop.example.com/thanks',
  cancel_url: 'https://shop.example.com/pricing',
});
// redirect the buyer to url; await vibiz.webhooks.receive(req) in the webhook route (only the app key needed)
```

A script that sends a daily report by email:

```bash
vibiz init reports --resources email
VIBIZ_APP_KEY=vz_app_… node report.mjs
```

```js
import { vibiz } from '@vibiz/app';
await vibiz.email.send({ to: 'team@example.com', subject: 'Daily report', text: body });
```

A plain HTML site with analytics: `vibiz init mysite --resources analytics`, `vibiz domains add mysite.com --elsewhere`, then paste `vibiz analytics snippet` before `</head>` ([Analytics](https://app.vibiz.app/docs/analytics)).

## Good to know

- **The app key is a server secret.** `@vibiz/app` refuses to run in a browser. A plain site or a mobile app calls its own backend (or a small function) that holds the key; only the analytics tag's site key is public.
- **Add every domain the app answers on.** Sign-in and analytics refuse other origins (`www.` comes with the domain). An agent may add one; sign-in trusts it once its TXT record proves it (or the owner confirms it).
- **Payment webhooks have no default without hosting.** On Vibiz hosting events go to `https://<slug>.vibiz.app/api/vibiz/webhook` by themselves; elsewhere the owner sets the URL, or an agent sets one on a domain the owner already added. Setting it puts `VIBIZ_WEBHOOK_SECRET` in the env.
- **Rotations follow on the next boot.** Values loaded with the key are read fresh each start; pasted values don't follow a rotation.
- **What needs Vibiz hosting:** deploys, previews and rollback; buying a domain (it is served there at once: connect one bought elsewhere with `--elsewhere` instead); and the code in an [export](https://app.vibiz.app/docs/export) (the database and the env guide export without it).
- **Add hosting later** with `vibiz add hosting`: every key is then pushed to the host by itself.
