# Site Commander Control Plane API

The Site Commander installation is the central Zernio gateway for connected sites and AI agents.

Base URL:

```text
https://pocketpapi.com
```

Authenticate every API request with the token created by an authenticated Site Commander administrator:

```http
Authorization: Bearer SC_TOKEN
```

Keep this token on the connected site's server. Never put it in browser JavaScript, HTML, a public repository, or a prompt.

Tokens are scoped to the projects and sites the administrator who created them can access. Site, task, activity, conversation, chat-message, ticket, ticket-message, review, and Zernio operations cannot reach another user's project or the protected Site Commander workspace.

For a connected site's own server or MCP client, create a site-scoped connection from that site's authenticated details page. The site token is shown once, stored only as a hash, can be rotated or revoked by the site owner, and cannot reach another site. Both token types are recorded in the central troubleshooting logs without storing bearer values or request bodies.

## Discovery

```text
GET /llms.txt
GET /.well-known/ai-plugin.json
GET /openapi.json
GET /api/control-plane/guide
POST /mcp
```

MCP clients should connect to `POST /mcp` with the same bearer header. The `sitecommander_api_guide` MCP tool returns this complete document. The MCP tools `sitecommander_projects` and `sitecommander_sites` locate the token creator's accessible workspaces without returning server paths. `sitecommander_sync_health` reports connected-site synchronization status without returning credentials. Support reads are available as `sitecommander_conversations`, `sitecommander_messages`, `sitecommander_tickets`, and `sitecommander_ticket_messages`.

## EasyApp mobile client

EasyApp is the shared iOS and Android client for connected customer sites. Site owners configure it from the authenticated Apps page. Public connections appear in the chooser; private connections are omitted until the owner supplies a configuration code. Public/private discovery controls enrollment only: users still sign in with an existing Site Commander workspace account before seeing leads or conversations.

```text
GET  /api/easyapp/sites
POST /api/easyapp/configure                 {"configuration_code":"EA-..."}
POST /api/easyapp/auth/login                {"site_key":"...","email":"...","password":"..."}
GET  /api/easyapp/me                        Authorization: Bearer EA_TOKEN
POST /api/easyapp/auth/logout               Authorization: Bearer EA_TOKEN
GET  /api/easyapp/leads                     Authorization: Bearer EA_TOKEN
POST /api/easyapp/leads/status              Authorization: Bearer EA_TOKEN
GET  /api/easyapp/conversations             Authorization: Bearer EA_TOKEN
GET  /api/easyapp/messages?conversation_id=456  Authorization: Bearer EA_TOKEN
POST /api/easyapp/messages/reply            Authorization: Bearer EA_TOKEN
```

EasyApp access tokens are site-scoped, expire after 30 days, and are stored only as hashes. Never use an MCP token in the mobile client. A mobile reply writes the shared `chat_messages` record, so it appears in the website widget and Site Commander Support Inbox/action center. EasyApp calls are visible to administrators in Audit Logs with the `easyapp` interface label; request bodies and bearer tokens are not logged.

An authorized MCP/API client can prepare the same site-linked app workspace from the builder automation contract. The operation is idempotent, requires a site the bearer token is allowed to access, and returns no configuration code or signing credential:

```text
POST /api/control-plane/easyapp
Authorization: Bearer SC_TOKEN
{"site_id":123,"app_name":"EasyApp","enabled":true,"visibility":"private"}
```

The matching MCP tool is `sitecommander_easyapp_ensure`. Use the authenticated Site Studio **Apps** tab for owner-facing discovery settings, one-time private configuration codes, and native source export. Native Apple/Google signing remains an external EAS, Xcode, Android Studio, or CI release step.

## Optional Site Commander mobile app

The Apps page also offers a standalone **Site Commander** native app. It signs in to the command center with an existing user account and shows only that user's accessible projects, sites, tasks, and inbound activity. It does not expose the protected internal Current Site workspace.

```text
POST /api/command-center/auth/login
{"email":"owner@example.com","password":"..."}

Authorization: Bearer SCM_TOKEN
GET /api/command-center/me
POST /api/command-center/auth/logout
GET /api/command-center/summary
GET /api/command-center/projects
GET /api/command-center/sites
GET /api/command-center/tasks?project_id=123&site_id=456
GET /api/command-center/activity
GET /api/command-center/integration-logs  (administrator troubleshooting permission)
```

Site Commander mobile sessions expire after 30 days and are separate from both MCP and EasyApp tokens. The optional Expo source is included in Site Commander source exports under `mobile/site-commander`.

## Effects library (public, no token required)

The Help Center effects page currently presents 63 recipes, including advanced scroll-driven motion, text systems, 3D/perspective interactions, form feedback, dialogs, and free MIT library starters. The catalog is intentionally separate from authenticated control-plane data. Any website, build script, or AI client can discover copyable motion recipes without opening the Site Commander command center:

```text
GET /help/effects
GET /api/effects
GET /api/effects/{effect_id}
POST /api/effects/compose
```

Search with `q`, `category`, `library`, and `limit` query parameters. `GET /api/effects/{effect_id}` returns the description, best-fit guidance, license, dependency/install note, and complete code snippet. The compose endpoint accepts JSON such as:

```json
{
  "effect_id": "fade-up-reveal",
  "target_selector": ".feature-card",
  "reduced_motion": true
}
```

The public endpoints are read-only and CORS-enabled. They prepare code; they do not write to another website. Pin third-party versions, review licenses, keep effects scoped, and test touch, keyboard focus, and `prefers-reduced-motion` before publishing.

## Effects through MCP

Authenticated MCP clients can use these read-only, idempotent tools:

```text
sitecommander_effects_search
sitecommander_effects_fetch
sitecommander_effects_compose
```

Advise a GPT/LLM to search first, fetch the selected `effect_id`, compose it for the real selector, and return exact insertion points. Prefer native recipes when they meet the need; choose a free MIT library only when it materially reduces complexity. The compose tool prepares a recipe and never edits a customer site by itself.

Mail identity MCP tools are site-scoped. `sitecommander_mail_profiles` reads profiles, `sitecommander_mail_profile_upsert` saves a sender name/address and optional public photo, and the four `sitecommander_bimi_*` tools prepare, inspect, verify, and return the DNS record. BIMI preparation and verification change configuration or verification timestamps, so callers should treat them as write/configuration actions and keep them behind an approval policy. None of these tools changes DNS, sends mail, or returns mail credentials.

## Control-plane reads

```text
GET /api/control-plane/status
GET /api/control-plane/projects
GET /api/control-plane/sites
GET /api/control-plane/easyapp
POST /api/control-plane/easyapp             {"site_id":123,"visibility":"private"}
GET /api/control-plane/sync-health
GET /api/control-plane/tasks
GET /api/control-plane/activity?site_id=SITE_ID
GET /api/control-plane/conversations?site_id=SITE_ID
GET /api/control-plane/messages?conversation_id=CONVERSATION_ID
GET /api/control-plane/tickets?site_id=SITE_ID
GET /api/control-plane/ticket-messages?ticket_id=TICKET_ID
GET /api/control-plane/reviews?site_id=SITE_ID
POST /api/control-plane/messages/reply
GET /api/control-plane/mail/profiles?site_id=SITE_ID
GET /api/control-plane/bimi/status?site_id=SITE_ID
GET /api/control-plane/bimi/record?site_id=SITE_ID
```

The conversation endpoints read live website chats, including the complete message list. The ticket endpoints read support tickets created from the site and their replies. A message reply is shown in the visitor's embedded site widget and in the Site Commander Support Inbox/action center.

## Sender photos and BIMI

Email identity management is site-scoped and available from the authenticated site page at **Email identity** or through the same bearer token:

```text
GET  /api/control-plane/mail/profiles?site_id=SITE_ID
POST /api/control-plane/mail/profiles
GET  /api/control-plane/bimi/status?site_id=SITE_ID
POST /api/control-plane/bimi/prepare
POST /api/control-plane/bimi/verify
GET  /api/control-plane/bimi/record?site_id=SITE_ID
```

Create or update a sender profile with a hosted HTTPS photo URL or base64 PNG/JPEG/WebP photo no larger than 4 MB:

```json
{
  "site_id": 123,
  "sender_email": "hello@example.com",
  "sender_name": "Example Company",
  "photo_base64": "data:image/png;base64,..."
}
```

Prepare a BIMI logo with a BIMI SVG Tiny PS file and optional VMC/CMC certificate chain. Both files may be sent as base64 in JSON:

```json
{
  "site_id": 123,
  "selector": "default",
  "dkim_selector": "resend",
  "avatar_preference": "brand",
  "svg_base64": "data:image/svg+xml;base64,...",
  "certificate_pem_base64": "data:application/x-pem-file;base64,..."
}
```

`bimi/prepare` stores the validated public assets and returns the exact DNS name and TXT value to publish. Site Commander never changes DNS. `bimi/verify` checks HTTPS hosting, SVG Tiny PS constraints, SPF, the configured DKIM selector, enforced DMARC, and the BIMI TXT record. It reports `ready` only when the Gmail-oriented checklist also has a VMC/CMC; it reports `yahoo_eligible` when the Yahoo-oriented checklist passes. Mailbox-provider reputation, volume, and caching can still affect display.

The hosted sender photo is an integration asset, not a universal override. Gmail and Microsoft 365 account/directory photos remain provider-owned, and Outlook may show a recipient's local contact photo. BIMI is a brand logo signal where supported; it is not a personal-avatar guarantee.

## Site connection setup

Open `Projects → site → Connect site to command center` in the authenticated command center. Copy the `scc_...` token from the one-time reveal into the connected site's server environment:

```text
COMMAND_CENTER_URL=https://pocketpapi.com
SITE_COMMANDER_SITE_ID=123
SITE_COMMANDER_TOKEN=scc_...
```

Use the site token for the event endpoint, site-scoped reads, approved chat replies, and the remote MCP endpoint. The token is limited to its site and the owner's current project membership. A failed call is visible in Audit Logs with the site, interface, action, status, duration, and bounded safe error text.

Check synchronization health with:

```text
GET /api/control-plane/sync-health
```

The response reports each authorized site's active connection state, last event, last API call, successful calls, and failed calls. It never returns credentials or absolute server paths.

## Inbound site events

Connected sites send contact forms, leads, subscriptions, and messages to:

```http
POST /api/control-plane/events
Content-Type: application/json
```

```json
{
  "site_id": 123,
  "type": "contact",
  "name": "Jordan Smith",
  "email": "jordan@example.com",
  "subject": "Pricing question",
  "message": "Please send details."
}
```

Allowed types are `message`, `subscription`, `contact`, and `lead`. The envelope also accepts `external_id`, `category`, `subcategory`, `folder`, `source`, `status`, `priority`, `tags`, `custom_fields`, and any additional site-specific keys. Normalized fields are indexed; the complete original payload is returned as `metadata` in activity responses.

Example with site-specific routing fields:

```json
{"site_id":123,"type":"message","external_id":"crm-8842","category":"support","subcategory":"billing","folder":"vip","source":"contact-widget","status":"open","priority":"high","tags":["enterprise","renewal"],"custom_fields":{"plan":"pro","order_id":"A-19"},"message":"I need help with renewal."}
```

## Replies and approved actions

Reply to a Google Business Profile review:

```http
POST /api/control-plane/reviews/reply
Content-Type: application/json
```

```json
{"site_id":123,"review_id":"REVIEW_ID","message":"Thank you for visiting us."}
```

Reply to a website conversation:

```http
POST /api/control-plane/messages/reply
Content-Type: application/json
```

```json
{"conversation_id":456,"message":"Thanks — our team will follow up shortly.","metadata":{"category":"support","subcategory":"billing","folder":"vip","tags":["enterprise"]}}
```

## Central Zernio gateway

The central installation uses its encrypted Zernio API key internally. Connected sites never receive that key.

```text
GET  /api/control-plane/zernio/accounts?site_id=SITE_ID
GET  /api/control-plane/zernio/capabilities?site_id=SITE_ID
GET  /api/control-plane/zernio/reviews?site_id=SITE_ID
POST /api/control-plane/zernio/posts?site_id=SITE_ID
```

Create a post through the gateway:

```json
{
  "text": "This week's update is now live.",
  "targets": [
    {"platform":"facebook","accountId":"ACCOUNT_ID"},
    {"platform":"linkedin","accountId":"ACCOUNT_ID"}
  ]
}
```

All gateway actions are site-scoped, use the central Zernio credentials, and are audit logged. The gateway intentionally exposes approved operations instead of arbitrary Zernio URL forwarding.

## Server-side PHP example

```php
$url = $commandCenter . '/api/control-plane/reviews?site_id=' . (int) $siteId;
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [
    'Authorization: Bearer ' . $siteCommanderToken,
    'Accept: application/json',
]]);
$reviews = json_decode((string) curl_exec($ch), true);
curl_close($ch);
```

Google Business Profile review access requires a verified Google Business Profile account connected to the site through Zernio. The central Zernio API key remains encrypted in Site Commander.
