APIClaw Session Report

The API Layer for AI Agents
Session: April 5, 2026 — NordSym AB

APIClaw is now a live production API gateway.

Telegram bot responding via APIClaw. Anthropic OAuth dependency eliminated. E2E proven.

What We Built

Feature 1

Workspace API Keys

Generate persistent sk-claw- keys in your workspace. One key, every API. Keys are hashed after creation -- shown once, never stored in plain text.

Feature 2

Unified Auth Layer

All 15+ proxy endpoints upgraded in one change. Accepts Authorization: Bearer sk-claw-... alongside legacy identifier auth. Zero breaking changes.

Feature 3

Gateway /v1/chat/completions

OpenAI-compatible LLM endpoint. Routes to OpenRouter (800+ models). Streaming support. Usage tracking. Standard protocol -- works with any AI tool.

Feature 4

OpenClaw Integration

APIClaw configured as a first-class provider in OpenClaw. Telegram bots now powered entirely by APIClaw gateway. No direct Anthropic key needed.

E2E Architecture

Telegram
OpenClaw Gateway
APIClaw Gateway
sk-claw-...q6Yd
OpenRouter
Claude Sonnet 4.6

E2E Test Results

TestResultLatency
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 --

Backend: API Keys

Schema (convex/schema.ts)

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"])

Functions (convex/apiKeys.ts)

FunctionTypePurpose
generateKeymutationCreate key, return raw ONCE, store hash only
listKeysqueryReturn prefix + metadata (never raw key)
revokeKeymutationSoft delete with revokedAt timestamp
resolveKeyinternalQueryHash lookup for gateway auth
touchKeymutationUpdate lastUsedAt on each use

Backend: Gateway

Auth Resolution (convex/http.ts)

resolveWorkspaceFromRequest(ctx, request)
  1. Authorization: Bearer sk-claw-...  → resolveKey → workspaceId
  2. X-APIClaw-Identifier (legacy)      → workspaceId
  3. Anonymous                          → allowed, untracked

Endpoints

EndpointMethodAuthPurpose
/v1/chat/completionsPOSTsk-claw- requiredOpenAI-compatible LLM gateway
/v1/modelsGEToptionalList available models
/proxy/* (15+ routes)POSTsk-claw- or legacyAll existing API proxies

OpenClaw Configuration

{
  "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.

Files Changed

Production State

ComponentStatusDetail
Convex prodDEPLOYEDadventurous-avocet-799
Gateway endpointLIVE/v1/chat/completions responding
Prod API keyACTIVEsk-claw-...q6Yd ("OpenClaw Production")
OpenClaw default modelACTIVEapiclaw/anthropic/claude-sonnet-4-6
Telegram botsLIVE4 accounts responding
Anthropic OAuthELIMINATEDNo longer needed
Frontend buildCLEANNext.js + Convex both pass