Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat(api): Phase 0 — REST Admin API foundation (/api/v1/health)
Introduces the /api/v1/* REST Admin API surface for trusted clients
(e.g. NullClaw iOS app) as an opt-in gateway feature.

Changes:
- src/api/context.zig: ApiContext struct (per-request context, mirrors
  WebhookHandlerContext pattern; sendSuccess/sendError envelope helpers)
- src/api/api.zig: comptime Endpoint registry, dispatch() entry point,
  handleHealth handler (GET /api/v1/health — structured component health,
  pid, uptime); 10 new tests
- src/config_types.zig: GatewayConfig.admin_api bool field (default false)
- src/config_parse.zig: parse gateway.admin_api from config.json
- src/gateway.zig: wire api.dispatch() into the main request loop;
  import api/api.zig; /api/v1/* branch with same cron-style auth guard
- config.example.json: add admin_api: false under gateway
- docs/en/gateway-api.md: document /api/v1/ section, response envelope,
  enabling instructions, and Phase 0 endpoint reference
  • Loading branch information
vernonstinebaker committed Apr 19, 2026
commit 5a2ba2ae0a55722aeca6fd7414f295c7cc676361
3 changes: 2 additions & 1 deletion config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@
"gateway": {
"port": 3000,
"host": "127.0.0.1",
"require_pairing": true
"require_pairing": true,
"admin_api": false
},

"tunnel": {
Expand Down
63 changes: 62 additions & 1 deletion docs/en/gateway-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Default gateway endpoint: `http://127.0.0.1:3000`
- [Security](./security.md): come here when a security review needs the concrete HTTP auth and endpoint surface
- [Configuration](./configuration.md): return here after editing `gateway` settings to validate the API-facing behavior

## Endpoints
## Endpoints

| Endpoint | Method | Auth | Description |
|---|---|---|---|
Expand All @@ -40,6 +40,7 @@ Default gateway endpoint: `http://127.0.0.1:3000`
| `/max` | POST | `X-Max-Bot-Api-Secret` when configured | Max inbound webhook delivery |
| `/.well-known/agent-card.json` | GET | None | A2A Agent Card discovery (public) |
| `/a2a` | POST | `Authorization: Bearer <token>` | A2A JSON-RPC 2.0 endpoint |
| `/api/v1/health` | GET | `Authorization: Bearer <token>` | REST Admin API — structured health with component detail (requires `gateway.admin_api: true`) |

## Quick Examples

Expand Down Expand Up @@ -294,12 +295,72 @@ Include `contextId` in the message to group tasks into a conversation. All messa
| -32005 | ContentTypeNotSupportedError | Incompatible content types |
| -32007 | AuthenticatedExtendedCardNotConfiguredError | Extended card not available |

## REST Admin API (`/api/v1/`)

The REST Admin API provides programmatic access to runtime state for trusted clients such as the NullClaw iOS app. It is **opt-in** and disabled by default.

### Enabling

Add `"admin_api": true` under the `gateway` key in `config.json`:

```json
{
"gateway": {
"require_pairing": true,
"admin_api": true
}
}
```

When `admin_api` is `false` (the default), every request to `/api/v1/*` returns:

```json
{"success":false,"data":null,"error":{"code":"ADMIN_API_DISABLED","message":"Set gateway.admin_api=true in config.json to enable the REST admin API"}}
```

### Auth

The same Bearer token used for `/webhook` and `/cron` is required. Requests without a valid token receive `401 Unauthorized`.

### Response envelope

All Admin API responses use a consistent JSON envelope:

```json
{"success":true,"data":{...},"error":null}
{"success":false,"data":null,"error":{"code":"ERROR_CODE","message":"human-readable message"}}
```

### Phase 0 endpoints

#### `GET /api/v1/health`

Returns structured component health, PID, and uptime.

```json
{
"success": true,
"data": {
"status": "ok",
"pid": 12345,
"uptime_seconds": 3600,
"components": {
"gateway": {"status": "ok", "restart_count": 0}
}
},
"error": null
}
```

`status` is `"ok"` when all components report `"ok"`, otherwise `"degraded"`.

## Security Guidance

1. Keep `gateway.require_pairing = true`.
2. Keep gateway on loopback (`127.0.0.1`) and expose externally through tunnel/proxy.
3. Treat bearer tokens as secrets; do not commit or log them.
4. Treat Max webhook secrets the same way: randomize them per account and do not reuse one secret across multiple bots.
5. Only enable `gateway.admin_api = true` when a trusted client (e.g. NullClaw iOS app) requires it.

## Next Steps

Expand Down
Loading