webfaCeMEdiawebface.cloud docs
← Dashboard

Deploy on webface.cloud

Every app on webface.cloud is a full backend — database, auth, file storage, and a REST + realtime API — that also hosts your frontend on the same domain. One origin: no CORS setup, no separate hosting bill.

React Vite npm webface.cloud API

Point your frontend at the app

npm install pocketbase

import PocketBase from 'pocketbase'
const pb = new PocketBase('https://your-app.webface.cloud')  // or '/' in production

await pb.collection('users').authWithPassword(email, password)
const items = await pb.collection('items').getList(1, 20)

// realtime — changes stream to every open browser:
pb.collection('items').subscribe('*', e => render(e.record))

The webface.cloud API is powered by the open-source PocketBase engine — its JS SDK and documentation apply directly.

Option A — Deploy from GitHub (recommended)

  1. On your app card, open Frontend → Connect & deploy and paste your repo URL (e.g. https://github.com/you/site).
  2. Default build is npm ci && npm run build with output dist/ (Vite). CRA users: set output to build. Plain static sites: leave the build command empty.
  3. Auto-deploy on push: install the webfaCe Cloud GitHub App on the repo once (private repos too — no tokens anywhere). The webhook is registered for you when you connect; every push to your branch redeploys. Not on GitHub, or prefer not to install it? Copy the webhook URL from the card into the repo's Settings → Webhooks (content type JSON).

Starting from nothing? Agents can create a repo from our template first (POST /api/platform/repos / MCP create_repo) — it ships AGENTS.md/CLAUDE.md so any coding agent builds correctly — then connect it.

Option B — Upload a zip

npm run build
zip -r mysite.zip dist

Then Upload zip on the app card. Live in seconds; replace any time. Client-side routing (React Router) works — unknown paths fall back to index.html.

Google sign-in (OAuth2)

  1. In Google Cloud Console → Credentials, create an OAuth client ID (type: Web application).
  2. Add the authorized redirect URI: https://your-app.webface.cloud/api/oauth2-redirect (add your custom domain's too, if attached).
  3. In your app's Data admin (/_/) → users collection → Options → OAuth2, enable Google and paste the client ID + secret.
  4. Frontend, one line: await pb.collection('users').authWithOAuth2({ provider: 'google' })

The same panel supports GitHub, Apple, Microsoft, Discord and 25+ other providers — identical steps.

Going live on your own domain

  1. On the app card → Custom domain, attach your domain (e.g. oloro.ca).
  2. At your registrar, point the domain's DNS A record at 137.184.160.83 (for a subdomain, an A record on that host works the same).
  3. Done. The HTTPS certificate issues itself within about a minute of DNS going live — your app answers on both addresses.

Don't own a domain yet? webfaCeMEdia can register and connect one for you — reply to your invite email. Want traffic analytics for your org site? Ask us to enable it — privacy-respecting and cookieless.

Connect your coding agent (MCP + API)

Agents can run this whole platform — create apps, connect repos, deploy, attach domains — through MCP or plain REST. The steps below are written so an agent can execute them directly.

  1. Generate a token: dashboardAPI access → Generate API token (sent as Authorization: Bearer <token>).
  2. Install the MCP server (macOS/Linux): curl -fsSL https://webface.cloud/install-mcp.sh | sh — it prints exact config for Claude Code, OpenCode, and any stdio client, and a one-line verification.
  3. Running the MCP binary yourself: set WFC_URL=https://webface.cloud and WFC_TOKEN=<token>. A token only works on the platform that issued it.
  4. No MCP client? Use the REST reference below. Apps are addressable by id or subdomain.

Rules for agents: no Express/Flask/serverless — the backend exists; server logic goes in pb_hooks/*.pb.js and schema in pb_migrations/ (see below), both deployed with the repo or zip. Collections can also be made by a human in /_/.

Platform API reference

Base https://webface.cloud/api/platform · header Authorization: Bearer wfc_… · JSON in, JSON out. Every error is {"error": "…"} with the status shown. <app> is an app id or subdomain you own.

EndpointBody → Response
GET /apps200 {"apps":[App…]}
POST /apps{"subdomain":"myapp","name":"My App"}201 App. Subdomain: 2–30 chars, lowercase letters/digits/hyphens, not reserved. Live at App.url in ~10 s. template is accepted from operators only (stock · community · oloro · wholesale · dispatch · custom); everyone else gets stock. 403 if your account cannot create apps, 422 on an invalid or taken subdomain.
GET /apps/<app>200 App
POST /repos{"name":"my-app","private":true}201 {full_name, html_url, clone_url, private, default_branch, next}. Generates a repo from webfacemedia-inc/app-template in the platform's org with the GitHub App already installed. Same gate as app creation. 501 if the platform has no GitHub App.
POST /apps/<app>/git{"repoUrl":"https://github.com/you/site","branch":"main","buildCmd":"","outputDir":""} (only repoUrl required, must be https) → 202 App + "webhook":"auto"|"manual". auto: the GitHub App registered the push webhook, you're done. manual: add webhook_url to the repo's webhooks (JSON) yourself. Private repos clone through the App when it's installed on them. pb_hooks/ + pb_migrations/ at the repo root deploy too (app restarts); a hooks-only repo is a valid backend deploy. A first build starts immediately. Empty buildCmd = auto-detect (package.jsonnpm ci && npm run build, output dist/ or build/; no package.json = static).
POST /apps/<app>/deployno body → 202 {"deploying":true}. Rebuilds from the connected repo; 422 if none is connected. Poll GET /apps/<app>: deploying goes false, deploy_error holds the log tail on failure, last_deploy updates on success.
POST /apps/<app>/frontendmultipart, field bundle = a zip (≤200 MB) with index.html at its root or inside one top-level dir such as dist/200 {"live":…, "installed":{frontend,hooks,migrations}, "restarted":bool}. The zip may also carry pb_hooks/ and pb_migrations/ (at its root or inside the one wrapping folder); a hooks-only zip leaves the frontend alone. Atomic swaps; previous builds are archived, not deleted.
POST /apps/<app>/domain{"domain":"example.ca"}200 {"domain":…,"dns":"point an A record at <ip>; HTTPS is automatic"}. "" detaches. 422 for platform subdomains or a domain already on another app.
POST /apps/<app>/events{"type":"git_deploy_ok","message":"…"} (typegit_deploy_start · git_deploy_ok · git_deploy_error) → 201 {"status":"logged"}. For your own CI: a git_deploy_ok stamps last_deploy and appears in the app's event feed.

App object: id, name, subdomain, url, admin_url, api_url, status (provisioning · running · stopped · error), template, frontend (bool), hooks (bool — pb_hooks live), deploying (bool), and when set: custom_domain, repo_url, webhook_url, deploy_error, last_error, last_deploy (UTC, RFC 3339). 401 = missing/invalid token · 403 = not your app · 404 = no such app. There is no delete endpoint — deletion is a dashboard action (data is archived, never destroyed). MCP tools map 1:1: list_apps, create_repo, create_app, app_status, connect_repo, deploy, attach_domain, upload_frontend, log_event.

Server logic — pb_hooks and pb_migrations

Need more than CRUD — custom routes, scheduled jobs, validation, multi-tenant rules? Put PocketBase JavaScript hooks in pb_hooks/*.pb.js and schema migrations in pb_migrations/*.js at the root of your repo or zip, next to your frontend. They deploy with the app and it restarts so migrations apply and hooks load. The platform runs upstream PocketBase with the JSVM, so a local ./pocketbase serve over the same folders is an exact rehearsal of production.

my-app/
  index.html            (or dist/ · build/ from your bundler)
  pb_hooks/main.pb.js   routerAdd("GET", "/api/classes/public", (e) => e.json(200, {...}))
  pb_migrations/1700000000_init.js

Built this way: webfaCe Classes — multi-tenant class booking for gyms and studios, hooks + migrations in the repo, the site under pb_public/.

Reference: PocketBase JS hooks · JS migrations. A backend-only repo (hooks, no index.html) deploys too — your existing frontend stays. GET /api/platform/apps/<app> reports "hooks": true once server logic is live. Hook routes under /api/… win over the frontend's catch-all.

What every app gets

/your frontend
/api/…database, auth, files, realtime
/_/your data admin panel