← back to Ventura Claw

API.md

1110 lines

# VenturaClaw API Reference

Production endpoint: `https://venturaclaw.com`

---

## Authentication & Sessions

VenturaClaw uses HMAC-signed cookies for session management. All protected endpoints require a valid `cc_session` cookie.

### POST /api/auth/login
**Public** — Create a user session

**Request:**
```json
{
  "email": "admin@venturaclaw.com",
  "password": "admin"
}
```

**Response (200 OK):**
```json
{
  "ok": true,
  "role": "admin",
  "name": "Admin"
}
```

**Response (401 Unauthorized):**
```json
{
  "error": "invalid"
}
```

**Side effects:**
- Sets `cc_session` cookie (7 days, httpOnly, sameSite=lax)
- Logs failed login attempts to audit trail

**curl:**
```bash
curl -X POST https://venturaclaw.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"admin@venturaclaw.com","password":"admin"}' \
  -c cookies.txt
```

---

### POST /api/auth/logout
**Session required** — Destroy the current session

**Request:** (empty body)

**Response (200 OK):**
```json
{
  "ok": true
}
```

**Side effects:**
- Clears `cc_session` cookie

**curl:**
```bash
curl -X POST https://venturaclaw.com/api/auth/logout \
  -b cookies.txt
```

---

### GET /api/me
**Session required** — Get current user identity

**Response (200 OK):**
```json
{
  "user": {
    "sub": 1,
    "email": "admin@venturaclaw.com",
    "role": "admin",
    "name": "Admin",
    "iat": 1714982400000
  }
}
```

---

## Connectors

VenturaClaw connectors are pre-built integrations (Stripe, Cloudflare, Shopify, 56+ total). Users authenticate connectors individually by storing credentials.

### GET /api/connectors
**Session required** — List all available connectors with configuration status

**Query params:** (none)

**Response (200 OK):**
```json
{
  "connectors": [
    {
      "id": "stripe",
      "name": "Stripe",
      "category": "payments",
      "description": "Process payments, issue refunds, manage customers",
      "icon": "stripe",
      "real_impl": true,
      "configured": true,
      "sensitive": true,
      "website": "https://stripe.com"
    },
    {
      "id": "slack",
      "name": "Slack",
      "category": "communication",
      "description": "Send messages to Slack channels",
      "icon": "slack",
      "real_impl": true,
      "configured": false,
      "sensitive": false
    }
  ],
  "support_email": "info@agentabrams.com"
}
```

**Fields:**
- `real_impl`: true if a handler exists in `/connectors/` directory
- `configured`: true if current user has stored credentials for this connector
- `sensitive`: actions queued for approval unless connector is trusted

**curl:**
```bash
curl https://venturaclaw.com/api/connectors \
  -b cookies.txt \
  -H "Accept: application/json"
```

---

### GET /api/connectors/:id/health
**Session required** — Probe a connector's live status

**Path params:**
- `id` (string): connector ID (e.g. `stripe`, `slack`)

**Response (200 OK):**
```json
{
  "status": "ok",
  "connector": "stripe",
  "checked_at": "2026-05-05T18:42:30Z",
  "message": "API responding"
}
```

**Response (500 error):**
```json
{
  "status": "error",
  "connector": "stripe",
  "message": "Stripe API key invalid or missing"
}
```

**Side effects:**
- Makes test call to vendor API using stored credentials
- Does NOT write or modify any data

**curl:**
```bash
curl https://venturaclaw.com/api/connectors/stripe/health \
  -b cookies.txt
```

---

## User Connections (Credentials)

Users save API keys, OAuth tokens, and other credentials for connectors. All stored credentials are masked on retrieval (first 4 + last 4 chars only).

### GET /api/me/connections
**Session required** — List all connectors + field schemas + which are filled by current user

**Response (200 OK):**
```json
{
  "connections": [
    {
      "id": "stripe",
      "name": "Stripe",
      "category": "payments",
      "docsUrl": "https://docs.stripe.com",
      "fields": [
        {
          "key": "api_key",
          "label": "Secret Key",
          "type": "password",
          "required": true
        },
        {
          "key": "publishable_key",
          "label": "Publishable Key",
          "type": "text",
          "required": false
        }
      ],
      "filled": true,
      "filled_fields": {
        "api_key": "sk_l…nqx2",
        "publishable_key": "pk_l…txy8"
      }
    },
    {
      "id": "cloudflare",
      "name": "Cloudflare",
      "category": "infrastructure",
      "filled": false,
      "filled_fields": null
    }
  ]
}
```

**curl:**
```bash
curl https://venturaclaw.com/api/me/connections \
  -b cookies.txt
```

---

### POST /api/me/connections/:id
**Session required** — Save or update credentials for a connector

**Path params:**
- `id` (string): connector ID

**Request body:**
```json
{
  "api_key": "sk_live_...",
  "publishable_key": "pk_live_..."
}
```

Fields accepted are defined by the connector's schema in GET /api/me/connections. Extra fields are silently ignored.

**Response (200 OK):**
```json
{
  "ok": true
}
```

**Response (400 Bad Request):**
```json
{
  "error": "no recognized fields"
}
```

**Response (404 Not Found):**
```json
{
  "error": "no real impl for this connector yet"
}
```

**Side effects:**
- Persists credentials to `data/credentials.json`
- Logs event to audit trail with field names (not values)

**curl:**
```bash
curl -X POST https://venturaclaw.com/api/me/connections/stripe \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{"api_key":"sk_live_...","publishable_key":"pk_live_..."}'
```

---

### DELETE /api/me/connections/:id
**Session required** — Remove credentials for a connector

**Response (200 OK):**
```json
{
  "ok": true
}
```

**Side effects:**
- Deletes credentials from `data/credentials.json`
- Logs removal to audit trail

**curl:**
```bash
curl -X DELETE https://venturaclaw.com/api/me/connections/stripe \
  -b cookies.txt
```

---

### POST /api/me/connections/import
**Session required** — Bulk import credentials from pasted text or JSON

Supports three formats:
1. **env** — KEY=VALUE lines (e.g., from `~/.env` or secrets-manager `.env`)
2. **claude-json** — Pasted `~/.claude.json` (extracts mcpServers env blocks)
3. **json** — Raw JSON object with env vars

Recognizes 45+ standard environment variables (STRIPE_SECRET_KEY, CLOUDFLARE_API_TOKEN, etc.) and maps them to connector IDs and field names.

**Request:**
```json
{
  "content": "STRIPE_SECRET_KEY=sk_live_...\nCLOUDFLARE_API_TOKEN=v1.abc...",
  "format": "auto"
}
```

**Response (200 OK):**
```json
{
  "ok": true,
  "format": "env",
  "envKeysSeen": 5,
  "serverCount": 0,
  "populated": [
    {
      "connector": "stripe",
      "fields": ["api_key"]
    },
    {
      "connector": "cloudflare",
      "fields": ["api_key"]
    }
  ],
  "unmatched": ["UNKNOWN_VAR"]
}
```

**Recognized env vars:**
- Stripe: `STRIPE_SECRET_KEY`, `STRIPE_PUBLISHABLE_KEY`, `STRIPE_API_KEY`
- Cloudflare: `CLOUDFLARE_API_TOKEN`, `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_TOKEN`
- Shopify: `SHOPIFY_ACCESS_TOKEN`, `SHOPIFY_TOKEN`, `SHOPIFY_STORE`
- Slack: `SLACK_BOT_TOKEN`, `SLACK_TOKEN`
- [+40 more — see ENV_KEY_TO_CONNECTOR in server.js]

**Side effects:**
- Merges recognized credentials into user's namespace
- Adds `_imported_at` and `_import_source` metadata
- Logs import event with connector count and format

**curl:**
```bash
curl -X POST https://venturaclaw.com/api/me/connections/import \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d @- << 'EOF'
{
  "content": "STRIPE_SECRET_KEY=sk_live_...\nCLOUDFLARE_API_TOKEN=...",
  "format": "auto"
}
EOF
```

---

## OAuth Configuration (Admin)

VenturaClaw supports 10 OAuth providers (Google, Slack, Stripe Connect, Notion, HubSpot, Mailchimp, Discord, and 3 more). An admin registers each vendor's OAuth app once. Users then click "Connect Vendor" to grant permissions.

### GET /api/admin/oauth/providers
**Admin required** — List OAuth providers + setup status + redirect URIs

**Response (200 OK):**
```json
{
  "providers": [
    {
      "id": "google",
      "name": "Google (Sheets / Drive / Gmail)",
      "icon": "google",
      "tint": "#4285F4",
      "auth_url": "https://accounts.google.com/o/oauth2/v2/auth",
      "token_url": "https://oauth2.googleapis.com/token",
      "scope": "https://www.googleapis.com/auth/spreadsheets https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/gmail.send",
      "register_url": "https://console.cloud.google.com/apis/credentials/oauthclient",
      "docs_url": "https://developers.google.com/identity/protocols/oauth2/web-server",
      "note": "Create OAuth 2.0 Client ID · Application type: Web · Authorized redirect URI: paste below.",
      "redirect_uri": "https://venturaclaw.com/oauth/google/callback",
      "has_credentials": true,
      "registered_at": "2026-05-04T10:30:00Z"
    },
    {
      "id": "slack",
      "name": "Slack",
      "has_credentials": false,
      "registered_at": null
    }
  ],
  "redirect_uri_pattern": "https://venturaclaw.com/oauth/<vendor>/callback"
}
```

---

### POST /api/admin/oauth/:vendor/credentials
**Admin required** — Register OAuth app credentials for a vendor

After admin registers an OAuth app with a vendor (Google, Slack, etc.), paste the client_id and client_secret here.

**Path params:**
- `vendor` (string): `google`, `slack`, `stripe`, `notion`, `hubspot`, `mailchimp`, `discord`

**Request:**
```json
{
  "client_id": "123456789.apps.googleusercontent.com",
  "client_secret": "GOCSPX-abc..."
}
```

**Response (200 OK):**
```json
{
  "ok": true,
  "vendor": "google"
}
```

**Response (404 Not Found):**
```json
{
  "error": "unknown vendor"
}
```

**Side effects:**
- Persists credentials to `data/oauth-apps.json`
- Records timestamp and admin email
- Logs to audit trail

---

### DELETE /api/admin/oauth/:vendor/credentials
**Admin required** — Remove OAuth app credentials for a vendor

**Response (200 OK):**
```json
{
  "ok": true
}
```

**Side effects:**
- Deletes vendor entry from `data/oauth-apps.json`
- Logs removal to audit trail
- Does NOT invalidate existing user tokens (they remain in user credentials)

---

### POST /api/admin/oauth/:vendor/sandbox
**Admin required** — Launch isolated Browserbase session for OAuth app registration

Creates a temporary cloud browser (expires in 10 min) pre-aimed at the vendor's OAuth registration page. Admin logs in once, registers the app, copies Client ID/Secret.

**Path params:**
- `vendor` (string): OAuth provider ID

**Response (200 OK):**
```json
{
  "ok": true,
  "session_id": "abc-123-def",
  "live_view": "https://api.browserbase.com/debug/abc-123-def",
  "register_url": "https://console.cloud.google.com/apis/credentials/oauthclient",
  "redirect_uri": "https://venturaclaw.com/oauth/google/callback",
  "hint": "Step 1: paste https://console.cloud.google.com/apis/credentials/oauthclient into the cloud browser's address bar. Step 2: register the app, set redirect URI, copy Client ID/Secret. Step 3: paste them back here."
}
```

**Response (500 error):**
```json
{
  "error": "BROWSERBASE_API_KEY not in env (add to ~/Projects/secrets-manager and restart)"
}
```

**Side effects:**
- Calls Browserbase API to create session
- Logs session creation to audit trail

---

### POST /api/admin/browserbase/release/:sessionId
**Admin required** — Release a Browserbase session early

**Path params:**
- `sessionId` (string): session ID returned by /sandbox endpoint

**Response (200 OK):**
```json
{
  "ok": true
}
```

**Side effects:**
- Sends REQUEST_RELEASE to Browserbase API
- Logs release to audit trail

---

## OAuth User Flow

### GET /oauth/:vendor/connect
**Session required** — Redirect user to vendor's OAuth consent screen

User clicks "Connect Google" (or other vendor) on the connections page → this endpoint signs a CSRF state token and redirects.

**Path params:**
- `vendor` (string): OAuth provider ID

**Query params:**
- `redirect_after` (optional): where to redirect after OAuth callback completes (default: `/connections`)

**Response (302 Found):**
```
Location: https://accounts.google.com/o/oauth2/v2/auth?
  client_id=...&
  redirect_uri=https://venturaclaw.com/oauth/google/callback&
  state=<signed-24-byte-token>&
  response_type=code&
  scope=...
```

**Side effects:**
- Creates entry in `data/oauth-state.json` (expires after 30 min)
- Logs to audit trail

---

### GET /oauth/:vendor/callback
**Public** — Vendor redirects here with authorization code

Handles the OAuth code-for-token exchange. On success, stores access_token (and refresh_token if provided) in user credentials.

**Query params (vendor-provided):**
- `code` (string): authorization code from vendor
- `state` (string): CSRF token (validated against oauth-state.json)
- `error` (optional): error from vendor if user denied

**Response (302 Found):**
```
Location: /connections
```

**Response (400 Bad Request):**
```html
<h1>OAuth error</h1>
<pre>invalid_scope</pre>
<p><a href="/connections">← back</a></p>
```

**Stored token structure:**
```json
{
  "access_token": "ya29.a0AfH6SMBx...",
  "refresh_token": "1//0gF...",
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/spreadsheets ...",
  "expires_at": "2026-05-06T12:42:30Z",
  "_connected_at": "2026-05-05T12:42:30Z",
  "_via": "oauth"
}
```

**Side effects:**
- Exchanges code for token at vendor's token_url
- Stores token in `data/credentials.json` under user ID
- Logs successful connection to audit trail
- Deletes state token from oauth-state.json

---

## Chat & Intent Routing

### POST /api/chat
**Session required** — Send a natural-language message to the intent router

Routes the user's message through a regex-based planner first, then escalates to local LLM (Ollama qwen3:14b on Mac Studio 1) if no match. Triggers corresponding connector actions—either immediately (safe, non-sensitive) or queued for admin approval.

**Request:**
```json
{
  "message": "post our newest product to all socials"
}
```

**Response (200 OK):**
```json
{
  "reply": "Drafting posts for all 10 social platforms. 10 actions queued for approval.",
  "toolCalls": [
    {
      "connector": "instagram",
      "name": "Instagram",
      "action": "post.create",
      "queued": true,
      "input": {}
    },
    {
      "connector": "facebook",
      "name": "Facebook",
      "action": "post.create",
      "queued": true,
      "input": {}
    }
  ]
}
```

**Example: Slack message**
```json
{
  "message": "tell the team 'deploy is ready' in #announcements"
}
```

Response:
```json
{
  "reply": "Slack message queued for approval → #announcements: \"deploy is ready\"",
  "toolCalls": [
    {
      "connector": "slack",
      "name": "Slack",
      "action": "chat.postMessage",
      "queued": true,
      "input": {
        "channel": "announcements",
        "text": "deploy is ready"
      }
    }
  ]
}
```

**Example: Stripe refund**
```json
{
  "message": "refund $50 from charge ch_1234abcd"
}
```

Response:
```json
{
  "reply": "Stripe refund queued for approval (ch_1234abcd) — $50.",
  "toolCalls": [
    {
      "connector": "stripe",
      "name": "Stripe",
      "action": "refund.create",
      "queued": true,
      "input": {
        "charge": "ch_1234abcd",
        "amount": 5000
      }
    }
  ]
}
```

**Queued vs. Executed:**
- `queued: true` — sensitive actions (payments, comms) → create approval record
- `queued: false` — read-only or low-risk actions → execute immediately if real impl exists

**Side effects:**
- Logs message and tool calls to audit trail
- For queued calls: creates approval records (persisted to `data/approvals.json`)
- For executed calls: may modify external systems (calls real connector implementations)

**curl:**
```bash
curl -X POST https://venturaclaw.com/api/chat \
  -b cookies.txt \
  -H "Content-Type: application/json" \
  -d '{"message":"what is my stripe balance"}'
```

---

## Approvals

### GET /api/approvals
**Session required** — List pending/completed approval records

Admins see all approvals. Regular users see only their own.

**Response (200 OK):**
```json
{
  "approvals": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "userId": 2,
      "userEmail": "demo@venturaclaw.com",
      "connector": "stripe",
      "connectorName": "Stripe",
      "action": "refund.create",
      "input": {
        "charge": "ch_1234abcd",
        "amount": 5000
      },
      "message": "refund $50 from charge ch_1234abcd",
      "status": "pending",
      "createdAt": "2026-05-05T18:30:00Z",
      "decidedBy": null,
      "decidedAt": null,
      "executionResult": null,
      "executionError": null,
      "executedAt": null
    }
  ]
}
```

---

### POST /api/approvals/:id/decide
**Admin required** — Approve or reject a pending action

Executes the action on approve (if real impl exists), logs comms-compliance checks, and stores decision + result/error.

**Path params:**
- `id` (string): approval UUID

**Request:**
```json
{
  "decision": "approve",
  "input": {
    "channel": "announcements",
    "text": "deploy is live"
  },
  "comms_compliance_override": false
}
```

**Response (200 OK):**
```json
{
  "ok": true,
  "approval": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "status": "approved",
    "decidedBy": "admin@venturaclaw.com",
    "decidedAt": "2026-05-05T18:35:00Z",
    "executionResult": {
      "ok": true,
      "ts": "2026-05-05T18:35:01Z"
    },
    "executedAt": "2026-05-05T18:35:01Z",
    "commsCompliancePassed": true
  }
}
```

**Response (422 Unprocessable Entity) — Comms compliance violation:**
```json
{
  "error": "comms_compliance_violations",
  "kind": "dnc_match",
  "violations": [
    {
      "type": "dnc_federal",
      "match": "recipient@example.com"
    }
  ],
  "message": "1 recipient(s) on Federal DNC list",
  "hint": "fix the violations OR resubmit with comms_compliance_override:true (audit-logged)"
}
```

**Decision values:**
- `"approve"` — execute the action (if real impl exists)
- `"reject"` — log rejection and stop

**Comms compliance:**
- Email/SMS/voice actions checked against CAN-SPAM, TCPA, Federal/State DNC, CCPA suppressions
- If violations found: returns 422 unless `comms_compliance_override: true` (logged)

**Side effects:**
- Calls real connector implementation if decision is "approve"
- Stores result or error message
- Logs decision to audit trail with violation summary

---

## Audit Log

### GET /api/audit
**Admin required** — Paginated audit trail of all events

**Query params:**
- `limit` (optional, default 200, max 1000): number of events

**Response (200 OK):**
```json
{
  "events": [
    {
      "ts": "2026-05-05T18:35:01Z",
      "kind": "approval_executed",
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "connector": "slack",
      "action": "chat.postMessage",
      "by": "admin@venturaclaw.com",
      "ok": true
    },
    {
      "ts": "2026-05-05T18:30:00Z",
      "kind": "chat",
      "userId": 2,
      "message": "post to announcements",
      "toolCalls": 1
    },
    {
      "ts": "2026-05-05T18:00:00Z",
      "kind": "login",
      "userId": 2,
      "email": "demo@venturaclaw.com",
      "role": "user"
    }
  ],
  "total": 427
}
```

**Event kinds:**
- `login`, `login_failed`, `logout`
- `connection_saved`, `connection_removed`, `connections_imported`
- `oauth_connected`, `oauth_app_registered`, `oauth_app_removed`
- `chat`, `chat_exec`, `connector_exec`
- `approval_decision`, `approval_executed`
- `comms_compliance_passed`, `comms_compliance_blocked`, `comms_compliance_override`
- `browserbase_sandbox_opened`, `browserbase_released`

---

## Admin: User Management

### GET /api/admin/users
**Admin required** — List all users (passwords redacted)

**Response (200 OK):**
```json
{
  "users": [
    {
      "id": 1,
      "email": "admin@venturaclaw.com",
      "name": "Admin",
      "role": "admin"
    },
    {
      "id": 2,
      "email": "demo@venturaclaw.com",
      "name": "Demo User",
      "role": "user"
    }
  ]
}
```

---

### POST /api/admin/users
**Admin required** — Create a new user

**Request:**
```json
{
  "email": "newuser@venturaclaw.com",
  "password": "temporary-password",
  "name": "New User",
  "role": "user"
}
```

**Response (200 OK):**
```json
{
  "ok": true,
  "user": {
    "id": 3,
    "email": "newuser@venturaclaw.com",
    "name": "New User",
    "role": "user"
  }
}
```

**Side effects:**
- Persists to `data/users.json`
- Logs creation to audit trail

---

### DELETE /api/admin/users/:id
**Admin required** — Remove a user

**Path params:**
- `id` (integer): user ID

**Response (200 OK):**
```json
{
  "ok": true,
  "removed": 1
}
```

---

## Comms Compliance (Email, SMS, Voice)

### POST /api/comms/scrub-preview
**Session required** — Preview what fields would be filtered by compliance rules

Does NOT require approval; anyone can test the scrubber.

**Request:**
```json
{
  "action": "slack.chat.postMessage",
  "input": {
    "channel": "announcements",
    "text": "new product launch"
  }
}
```

**Response (200 OK):**
```json
{
  "ok": true,
  "kind": "no_violations",
  "violations": [],
  "message": ""
}
```

**Response (with violations):**
```json
{
  "ok": false,
  "kind": "dnc_match",
  "violations": [
    {
      "type": "dnc_federal",
      "match": "recipient@example.com",
      "reason": "Federal Do-Not-Call"
    }
  ],
  "message": "1 recipient(s) on Federal DNC list"
}
```

---

### GET /api/comms/suppression
**Admin required** — List current suppression list (DNC, complaints, bounces)

**Response (200 OK):**
```json
{
  "entries": [
    {
      "kind": "dnc_federal",
      "value": "recipient@example.com",
      "reason": "CAN-SPAM opt-out 2026-04-30",
      "added_at": "2026-04-30T10:00:00Z"
    }
  ]
}
```

---

### POST /api/comms/suppression
**Admin required** — Add entry to suppression list

**Request:**
```json
{
  "kind": "dnc_federal",
  "value": "bounce@example.com",
  "reason": "bounced 3x, undeliverable"
}
```

**Response (200 OK):**
```json
{
  "ok": true,
  "kind": "dnc_federal",
  "value": "bounce@example.com",
  "added_at": "2026-05-05T18:40:00Z"
}
```

---

## Rate Limits & Quotas

**Currently none.** The following endpoints should implement rate limits:
- `POST /api/chat` — 10 req/min per user (prevents LLM spam)
- `POST /api/approvals/:id/decide` → `execute()` — 1 req/sec per connector (vendor API throttle)
- `POST /api/admin/oauth/:vendor/sandbox` — 3 per hour per admin (Browserbase session-minute quota)
- `POST /api/me/connections/import` — 5 per hour per user (prevents credential-stuffing)

**Recommendation:** Implement via express-rate-limit with Redis backend on production.

---

## Error Handling

All errors follow this shape:

**Validation error (400 Bad Request):**
```json
{
  "error": "missing email/password"
}
```

**Auth error (401 Unauthorized):**
```json
{
  "error": "unauthorized"
}
```

**Forbidden (403 Forbidden):**
```json
{
  "error": "forbidden"
}
```

**Not found (404 Not Found):**
```json
{
  "error": "not found"
}
```

**Conflict (409 Conflict):**
```json
{
  "error": "email exists"
}
```

**Server error (500 Internal Server Error):**
```json
{
  "error": "Stripe API error: invalid_request_error"
}
```

---

## Data Storage

All data persists to JSON files in `/server/data/`:
- `users.json` — user accounts (emails, hashed passwords, roles)
- `credentials.json` — { userId: { connectorId: { field: value } } }
- `oauth-apps.json` — { vendor: { client_id, client_secret, registered_at, registered_by } }
- `oauth-state.json` — { state: { userId, vendor, redirect_after, created_at } } (short-lived CSRF tokens)
- `approvals.json` — approval queue (newest first, max 500 entries)
- `audit.json` — full audit trail (newest first, max 500 entries)

**On production:** Replace JSON store with PostgreSQL (schema + migrations TBD).

---

## Public Domain

VenturaClaw is deployed to `https://venturaclaw.com`. All subdomains/paths require SSL. Robots.txt blocks `/admin` and `/api` from search indexing.

---

## Support

For API issues, contact `info@agentabrams.com` or file an issue in the VenturaClaw project.

Last updated: 2026-05-05