[ API documentation ]

Build on MWS

Everything you need to drop the MWS gateway into your stack. If something here is unclear, email hello@vellora.ai.

Base URL

All endpoints live under:

https://api.mws.run/v1

Authentication

Every request needs a Bearer token in the Authorization header. Generate one in the dashboard after you've added at least $10 in credits or subscribed to a plan.

Authorization: Bearer <your-api-key>

Endpoints

  • POST /v1/messages: Anthropic Messages format (recommended for new code).
  • POST /v1/messages/count_tokens: Approximate token count where enabled (rough estimate; Anthropic-equivalent tokenizer not used).
  • POST /v1/chat/completions: OpenAI Chat Completions format. Streaming and tool-use supported.
  • GET /v1/models: List available Dragon profiles.
  • POST /v1/embeddings: Embedding generation.
  • POST /v1/rerank: Document reranking.

Streaming

Set stream: true. Anthropic-shape responses use Anthropic's SSE event types (message_start, content_block_delta, etc.). OpenAI-shape responses use standard data: {...}\\n\\n chunks terminated by [DONE].

const stream = client.messages.stream({
  model: "claude-sonnet-4-6",
  max_tokens: 1024,
  messages: [{ role: "user", content: "Stream me a poem." }],
});

for await (const event of stream) {
  if (event.type === "content_block_delta" && event.delta.type === "text_delta") {
    process.stdout.write(event.delta.text);
  }
}

Tool use

Both API shapes support function/tool calling. IDs are preserved verbatim across turns, so the standard request → tool_use → tool_result → end_turn flow works unchanged from the underlying SDK.

const tools = [
  {
    name: "get_weather",
    description: "Look up the weather for a city.",
    input_schema: {
      type: "object",
      properties: { city: { type: "string" } },
      required: ["city"],
    },
  },
];

const first = await client.messages.create({
  model: "claude-sonnet-4-6",
  max_tokens: 512,
  tools,
  messages: [{ role: "user", content: "What's the weather in Paris?" }],
});

// first.stop_reason === "tool_use"
// Reply with a tool_result and call again to get the final answer.

Models & pricing

Pass a Claude model name (claude-sonnet-4-6, claude-haiku-4, claude-opus-4) or pass a Dragon profile slug directly. Unknown model strings default to Dragon.

Dragon

dragon · Everyday coding

$0.1294 in / $0.9412 out per 1M

SWE-bench: 76.2% Verified / 50.9% Pro

DeepSeek V4 Flash

deepseek-flash · Cheapest lane, 1M context (/deepseek-flash)

$0.1647 in / $0.3294 out per 1M

Kimi K2.7-Code

k2.7 · Harder everyday tasks (/k2.7)

$1.1176 in / $4.7059 out per 1M

SWE-bench: 78.2% Verified / 58.6% Pro

GLM-5.2

glm-5.2 · Hardest tasks (/glm-5.2, or append /max)

$1.6471 in / $5.1765 out per 1M

SWE-bench: — Verified / 62.1% Pro

Kimi K3

k3 · Frontier lane, 1M context (/k3)

$3.5294 in / $17.6471 out per 1M

DeepSeek V4 Pro

deepseek-pro · Frontier agentic lane, 1M context (/deepseek-pro)

$1.5529 in / $4.6588 out per 1M

Qwen3.8 Max

qwen3.8 · Long-horizon agentic tasks (/qwen3.8)

$2.3529 in / $7.0588 out per 1M

MiniMax M3

minimax-m3 · Cheapest long-context lane, 512k (/minimax-m3)

$0.3529 in / $1.4118 out per 1M

Errors

  • 400: Invalid request body (e.g. missing max_tokens, malformed tool schema).
  • 401: Missing, invalid, or revoked API key.
  • 402: Out of credits or quota. Top up at /dashboard/credits.
  • 429: Rate limit exceeded (per-key limit, or per-IP for unauthenticated traffic). Check Retry-After.
  • 5xx: Upstream provider unavailable. Retry with backoff.

Rate limits

Rate limits apply per key. A fresh key starts at roughly 8 requests per second with a short burst ceiling above that. When you hit the limit, the response is 429 with a Retry-After header: back off and retry.

  • Per-key, not per-account. Each key gets its own limit, so parallel workloads can run on separate keys. Account usage still has to stay inside the acceptable use policy.
  • Need more throughput? Email hello@vellora.aiwith what you're building and we'll raise your limits.

SDK compatibility notes

  • Prompt caching: cache_control markers are accepted but not honored as-is; the gateway manages its own caching. You never need to set them.
  • Vision:image blocks are accepted where the selected lane supports them; otherwise they're dropped.
  • Token counting via messages.count_tokens uses a 4-char-per-token estimate. Treat as approximate.
  • anthropic-version header is accepted but currently a no-op.
  • Stop sequences work but may behave differently than Anthropic; they pass through to the upstream tokenizer.

Migration guide

From Anthropic

  1. Set baseURL: "https://api.mws.run/v1" on your Anthropic client.
  2. Replace your Anthropic key with an MWS key.
  3. That's it. Model names, message format, tool calls all unchanged.

From OpenAI

  1. Set baseURL: "https://api.mws.run/v1" on your OpenAI client.
  2. Replace your OpenAI key with an MWS key.
  3. Change model: "gpt-4o" to model: "dragon" (or another profile). Models like gpt-4o route to Dragon by default.