# Site Commander Control Plane API

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

Base URL:

```text
https://commander.stouterenterprises.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.

## 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.

## Effects library (public, no token required)

The effects 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 /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.

## Control-plane reads

```text
GET /api/control-plane/status
GET /api/control-plane/sites
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/reviews?site_id=SITE_ID
```

## 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.
