APIClaw is now a live production API gateway.
Generate persistent sk-claw- keys in your workspace. One key, every API. Keys are hashed after creation -- shown once, never stored in plain text.
All 15+ proxy endpoints upgraded in one change. Accepts Authorization: Bearer sk-claw-... alongside legacy identifier auth. Zero breaking changes.
OpenAI-compatible LLM endpoint. Routes to OpenRouter (800+ models). Streaming support. Usage tracking. Standard protocol -- works with any AI tool.
APIClaw configured as a first-class provider in OpenClaw. Telegram bots now powered entirely by APIClaw gateway. No direct Anthropic key needed.
| Test | Result | Latency |
|---|---|---|
GET /v1/models on prod |
13 models listed | -- |
| Fake key rejection | 401 with error message | -- |
sk-claw- → Gateway → OpenRouter → Claude |
Response received | 2.2s |
| OpenClaw CLI → APIClaw → Telegram delivery | "APIClaw e2e works through OpenClaw" | 17.8s |
| Telegram DM → bot responds | Confirmed live by operator | -- |
workspaceApiKeys: defineTable({
workspaceId: v.id("workspaces"),
key: v.string(),
keyHash: v.string(), // SHA lookup (raw key not stored)
keyPrefix: v.string(), // "sk-claw-...last4" for display
name: v.string(), // user label
lastUsedAt: v.optional(v.number()),
createdAt: v.number(),
revokedAt: v.optional(v.number()),
})
.index("by_keyHash", ["keyHash"])
.index("by_workspaceId", ["workspaceId"])
| Function | Type | Purpose |
|---|---|---|
generateKey | mutation | Create key, return raw ONCE, store hash only |
listKeys | query | Return prefix + metadata (never raw key) |
revokeKey | mutation | Soft delete with revokedAt timestamp |
resolveKey | internalQuery | Hash lookup for gateway auth |
touchKey | mutation | Update lastUsedAt on each use |
resolveWorkspaceFromRequest(ctx, request) 1. Authorization: Bearer sk-claw-... → resolveKey → workspaceId 2. X-APIClaw-Identifier (legacy) → workspaceId 3. Anonymous → allowed, untracked
| Endpoint | Method | Auth | Purpose |
|---|---|---|---|
/v1/chat/completions | POST | sk-claw- required | OpenAI-compatible LLM gateway |
/v1/models | GET | optional | List available models |
/proxy/* (15+ routes) | POST | sk-claw- or legacy | All existing API proxies |
{
"models": {
"providers": {
"apiclaw": {
"baseUrl": "https://adventurous-avocet-799.convex.site/v1",
"apiKey": "sk-claw-...q6Yd",
"api": "openai-completions",
"auth": "api-key",
"models": [
{ "id": "anthropic/claude-sonnet-4-6", "name": "Claude Sonnet 4.6" },
{ "id": "anthropic/claude-haiku-3.5", "name": "Claude Haiku 3.5" },
{ "id": "openai/gpt-4o", "name": "GPT-4o" },
{ "id": "google/gemini-2.5-pro-preview", "name": "Gemini 2.5 Pro" },
{ "id": "meta-llama/llama-3.3-70b-instruct", "name": "Llama 3.3 70B" },
{ "id": "deepseek/deepseek-chat", "name": "DeepSeek Chat" }
]
}
}
}
}
Key discovery: OpenClaw appends /chat/completions to baseUrl. The baseUrl must include /v1.
convex/schema.ts Added workspaceApiKeys table + indexesconvex/apiKeys.ts NEW Generate, list, revoke, resolve, touchconvex/http.ts Unified auth + /v1/chat/completions + /v1/modelslanding/.../workspace/page.tsx API Keys tab + nav + config snippet~/.openclaw/openclaw.json APIClaw as primary provider, Telegram restored| Component | Status | Detail |
|---|---|---|
| Convex prod | DEPLOYED | adventurous-avocet-799 |
| Gateway endpoint | LIVE | /v1/chat/completions responding |
| Prod API key | ACTIVE | sk-claw-...q6Yd ("OpenClaw Production") |
| OpenClaw default model | ACTIVE | apiclaw/anthropic/claude-sonnet-4-6 |
| Telegram bots | LIVE | 4 accounts responding |
| Anthropic OAuth | ELIMINATED | No longer needed |
| Frontend build | CLEAN | Next.js + Convex both pass |