Compatible APIs

Call Runware with the OpenAI, Anthropic and TypeSafe request formats. Point an existing SDK at Runware by changing the base URL and the API key.

Introduction

Besides its native API, Runware accepts requests in three other providers' formats. If your code already uses one of their SDKs, point it at Runware by changing two values: the base URL and the API key. Requests and responses keep the provider's format, so the provider's documentation stays the reference for every parameter.

EndpointFormatReference
/v1/chat/completionsOpenAI Chat CompletionsOpenAI API reference
/v1/messagesAnthropic MessagesClaude API reference
/v1/decisionsTypeSafe decisionsTypeSafe docs

All three read your Runware API key from the Authorization: Bearer header, and take a Runware AIR ID in model. Each section below lists the models its endpoint serves.

OpenAI Chat Completions

https://api.runware.ai/v1/chat/completions takes the OpenAI Chat Completions format. If you already use the OpenAI SDK or any tool that speaks the OpenAI protocol, it works without Runware-specific parsing.

If you need access to Runware-specific features like taskUUID tracking, includeCost, or the async delivery method, use the native API instead. The OpenAI-compatible endpoint focuses on broad compatibility with the standard OpenAI request and response format.

Quick start

Send a standard chat completion request to https://api.runware.ai/v1/chat/completions using your Runware API key and a Runware model ID:

{
  "model": "minimax:m2.7@0",
  "messages": [
    { "role": "user", "content": "What is the capital of France?" }
  ],
  "max_completion_tokens": 256
}

The request format is identical to the OpenAI Chat Completions API. The only difference is that model uses a Runware AIR ID (e.g., minimax:m2.7@0, google:gemini@3.1-pro) instead of an OpenAI model name.

curl -X POST https://api.runware.ai/v1/chat/completions \
  -H "Authorization: Bearer $RUNWARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "minimax:m2.7@0",
    "messages": [{"role": "user", "content": "What is the capital of France?"}],
    "max_completion_tokens": 256
  }'
from openai import OpenAI

client = OpenAI(
    api_key="your_runware_api_key",
    base_url="https://api.runware.ai/v1",
)

response = client.chat.completions.create(
    model="minimax:m2.7@0",
    messages=[{"role": "user", "content": "What is the capital of France?"}],
    max_completion_tokens=256,
)

print(response.choices[0].message.content)
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'your_runware_api_key',
  baseURL: 'https://api.runware.ai/v1',
});

const response = await client.chat.completions.create({
  model: 'minimax:m2.7@0',
  messages: [{ role: 'user', content: 'What is the capital of France?' }],
  max_completion_tokens: 256,
});

console.log(response.choices[0].message.content);

Streaming

Set "stream": true to receive tokens as they are generated, exactly as you would against the OpenAI API. To include token counts at the end of the stream, add stream_options:

{
  "model": "minimax:m2.7@0",
  "stream": true,
  "stream_options": { "include_usage": true },
  "messages": [
    { "role": "user", "content": "Tell me a joke" }
  ],
  "max_completion_tokens": 512
}

The SSE response format is identical to OpenAI's. Content arrives in choices[0].delta.content, and the stream ends with data: [DONE].

Streaming with OpenAI SDKs

The OpenAI Python and TypeScript SDKs handle all SSE parsing for you:

from openai import OpenAI

client = OpenAI(
    api_key="your_runware_api_key",
    base_url="https://api.runware.ai/v1",
)

with client.chat.completions.stream(
    model="minimax:m2.7@0",
    messages=[{"role": "user", "content": "Tell me a joke"}],
    max_tokens=512,
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)
import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'your_runware_api_key',
  baseURL: 'https://api.runware.ai/v1',
});

const stream = await client.chat.completions.create({
  model: 'minimax:m2.7@0',
  messages: [{ role: 'user', content: 'Tell me a joke' }],
  max_tokens: 512,
  stream: true,
});

for await (const chunk of stream) {
  const content = chunk.choices[0]?.delta?.content;
  if (content) process.stdout.write(content);
}
curl -N -X POST https://api.runware.ai/v1/chat/completions \
  -H "Authorization: Bearer $RUNWARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "minimax:m2.7@0",
    "stream": true,
    "stream_options": {"include_usage": true},
    "messages": [{"role": "user", "content": "Tell me a joke"}],
    "max_completion_tokens": 512
  }'

Reasoning models

Models with internal reasoning stream those tokens in choices[0].delta.reasoning_content before the final response appears in choices[0].delta.content, which is the same pattern OpenAI's reasoning models follow.

// First chunk - role assignment
data: {"id":"chatcmpl-e36b09e6-7a1c-4d8f-b5e2-9c4a3f6d8e1b","object":"chat.completion.chunk","model":"minimax:m2.7@0","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}

// Reasoning chunks - choices[0].delta.reasoning_content
data: {"id":"chatcmpl-e36b09e6-7a1c-4d8f-b5e2-9c4a3f6d8e1b","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"reasoning_content":"The user asks 2+2. Simple arithmetic."},"finish_reason":null}]}

// Actual response - switches to choices[0].delta.content
data: {"id":"chatcmpl-e36b09e6-7a1c-4d8f-b5e2-9c4a3f6d8e1b","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"4"},"finish_reason":null}]}

// Usage chunk (when stream_options.include_usage is set)
data: {"id":"chatcmpl-e36b09e6-7a1c-4d8f-b5e2-9c4a3f6d8e1b","object":"chat.completion.chunk","choices":[],"usage":{"prompt_tokens":51,"completion_tokens":38,"total_tokens":89,"cost":0.000134}}

// Final chunk - finish reason
data: {"id":"chatcmpl-e36b09e6-7a1c-4d8f-b5e2-9c4a3f6d8e1b","object":"chat.completion.chunk","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: [DONE]

Key differences from OpenAI

While the endpoint is fully compatible with the OpenAI protocol, there are a few things to be aware of:

AspectOpenAIRunware
Model IDsgpt-4o, gpt-4o-miniAIR format: minimax:m2.7@0, google:gemini@3.1-pro
AuthenticationOpenAI API keyRunware API key (same Authorization: Bearer header)
Base URLhttps://api.openai.com/v1https://api.runware.ai/v1
Available modelsOpenAI models onlyMultiple providers: MiniMax, Google Gemini, and more
Naming conventionsnake_case (finish_reason, reasoning_content)snake_case (same as OpenAI on this endpoint)

This endpoint uses snake_case field names (finish_reason, max_tokens) to match the OpenAI convention. The native API uses camelCase (finishReason, maxTokens).

Key differences from the native API

If you are choosing between the OpenAI-compatible endpoint and the native Runware API, here is how they compare:

Native APIOpenAI-compatible
Endpointhttps://api.runware.ai/v1https://api.runware.ai/v1/chat/completions
Request formatArray of task objects with taskType and taskUUIDSingle object (standard OpenAI format)
Streaming trigger"deliveryMethod": "stream""stream": true
Async supportYes ("deliveryMethod": "async" with webhooks/polling)No
Cost trackingincludeCost: true on the requestIncluded in the usage chunk when stream_options.include_usage is set
Usage trackingincludeUsage: true on the requeststream_options: { "include_usage": true }
Task trackingtaskUUID for request/response correlationStandard id field on response chunks
Naming conventioncamelCasesnake_case

Use the OpenAI-compatible endpoint when you want the fastest integration path or are already working with the OpenAI SDK.

Use the native API when you want a consistent request format across all Runware modalities (images, video, audio, text, 3d) and access to features like async delivery and task-level tracking.

Models

ModelModel ID
Claude Fable 5anthropic:claude@fable-5
Claude Fable 5.1anthropic:claude@fable-5.1
Claude Haiku 4.5anthropic:claude@haiku-4.5
Claude Opus 4.7anthropic:claude@opus-4.7
Claude Opus 4.8anthropic:claude@opus-4.8
Claude Opus 5anthropic:claude@opus-5
Claude Opus 5.5anthropic:claude@opus-5.5
Claude Sonnet 4.6anthropic:claude@sonnet-4.6
Claude Sonnet 5anthropic:claude@sonnet-5
Claude Sonnet 5.5anthropic:claude@sonnet-5.5
DeepSeek-V4-Flash-0731deepseek:v4@flash
DeepSeek-V4-Pro-0423deepseek:v4@pro
DeepSeek-V4.1-Flashdeepseek:v4.1@flash
Gemini 3 Flashgoogle:gemini@3-flash
Gemini 3.1 Flash Litegoogle:gemini@3.1-flash-lite
Gemini 3.1 Progoogle:gemini@3.1-pro
Gemini 3.5 Flashgoogle:gemini@3.5-flash
Gemini 3.5 Flash-Litegoogle:gemini@3.5-flash-lite
Gemini 3.6 Flashgoogle:gemini@3.6-flash
Gemini 3.7 Flashgoogle:gemini@3.7-flash
Gemini 3.8 Flashgoogle:gemini@3.8-flash
Gemma 4 31Bgoogle:gemma@4-31b
GLM-5.1zai:glm@5.1
GLM-5.2zai:glm@5.2
GLM-5.3zai:glm@5.3
GLM-5.3-Flashzai:glm@5.3-flash
GPT-5 Miniopenai:gpt@5-mini
GPT-5 Nanoopenai:gpt@5-nano
GPT-5.4openai:gpt@5.4
GPT-5.4 Miniopenai:gpt@5.4-mini
GPT-5.4 Nanoopenai:gpt@5.4-nano
GPT-5.4 Proopenai:gpt@5.4-pro
GPT-5.5openai:gpt@5.5
GPT-5.6 Lunaopenai:gpt@5.6-luna
GPT-5.6 Solopenai:gpt@5.6-sol
GPT-5.6 Terraopenai:gpt@5.6-terra
GPT-6 Astraopenai:gpt@6-astra
GPT-6 Lunaopenai:gpt@6-luna
GPT-6 Solopenai:gpt@6-sol
GPT-6.1 Solopenai:gpt@6.1-sol
gpt-oss-120bopenai:gpt-oss@120b
gpt-oss-safeguard-20bopenai:gpt-oss-safeguard@20b
Grok 4.3xai:grok@4.3
Grok 4.7xai:grok@4.7
Kimi K2.6moonshotai:kimi@k2.6
Kimi K3moonshotai:kimi@k3
MiniMax M2.7minimax:m2.7@0
MiniMax M2.7 Highspeedminimax:m2.7@highspeed
MiniMax M3minimax:m3@0
Shieldstral 1.0 3Bmistralai:shieldstral@1.0-3b

Anthropic Messages

https://api.runware.ai/v1/messages takes the Anthropic Messages format. The request body reaches Anthropic unchanged, so every Messages parameter works as documented, including thinking, prompt caching, tool use and vision. With "stream": true, the response streams Anthropic's own server-sent events.

The Anthropic SDKs send the API key in an x-api-key header by default. Runware reads it from Authorization: Bearer, so pass your Runware API key as auth_token in Python or authToken in TypeScript, and set the base URL to https://api.runware.ai.

curl -X POST https://api.runware.ai/v1/messages \
  -H "Authorization: Bearer $RUNWARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic:claude@opus-5.5",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "What is the capital of France?"}]
  }'
from anthropic import Anthropic

client = Anthropic(
    auth_token="your_runware_api_key",
    base_url="https://api.runware.ai",
)

message = client.messages.create(
    model="anthropic:claude@opus-5.5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "What is the capital of France?"}],
)

print(message.content[0].text)
import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic({
  authToken: 'your_runware_api_key',
  baseURL: 'https://api.runware.ai',
});

const message = await client.messages.create({
  model: 'anthropic:claude@opus-5.5',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'What is the capital of France?' }],
});

console.log(message.content[0].text);

Besides the AIR ID, model accepts the Runware model ID (anthropic-claude-opus-5-5) and Anthropic's own model name (claude-opus-5-5).

Models

ModelModel ID
Claude Fable 5anthropic:claude@fable-5
Claude Fable 5.1anthropic:claude@fable-5.1
Claude Haiku 4.5anthropic:claude@haiku-4.5
Claude Opus 4.7anthropic:claude@opus-4.7
Claude Opus 4.8anthropic:claude@opus-4.8
Claude Opus 5anthropic:claude@opus-5
Claude Opus 5.5anthropic:claude@opus-5.5
Claude Sonnet 4.6anthropic:claude@sonnet-4.6
Claude Sonnet 5anthropic:claude@sonnet-5
Claude Sonnet 5.5anthropic:claude@sonnet-5.5

Decisions

https://api.runware.ai/v1/decisions takes the TypeSafe decisions format. Instead of generating text, a decision model reads a state and answers a set of typed questions with probabilities and a confidence. The TypeSafe docs describe the question types.

The TypeSafe SDKs work by pointing the base URL at https://api.runware.ai with your Runware API key. Set model on every request, because the SDK's own default is not a Runware model ID.

curl -X POST https://api.runware.ai/v1/decisions \
  -H "Authorization: Bearer $RUNWARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe:jev@1",
    "state": "I was charged twice. Please fix this ASAP.",
    "questions": {
      "category": {
        "type": "choice",
        "instructions": "What is this ticket about?",
        "criteria": {"billing": null, "technical": null, "other": null}
      }
    }
  }'
from typesafe_sdk import Choice, TypeSafeClient

client = TypeSafeClient(
    api_key="your_runware_api_key",
    base_url="https://api.runware.ai",
)

response = client.system_one(
    model="typesafe:jev@1",
    state={"document": "I was charged twice. Please fix this ASAP."},
    questions={
        "category": Choice(
            instructions="What is this ticket about?",
            criteria={"billing": None, "technical": None, "other": None},
        ),
    },
)

print(response.answers["category"].choice)
import { choice, TypeSafeClient } from '@typesafe-ai/sdk';

const client = new TypeSafeClient({
  apiKey: 'your_runware_api_key',
  baseURL: 'https://api.runware.ai',
});

const response = await client.systemOne({
  model: 'typesafe:jev@1',
  state: { document: 'I was charged twice. Please fix this ASAP.' },
  questions: {
    category: choice('What is this ticket about?', {
      billing: null,
      technical: null,
      other: null,
    }),
  },
});

console.log(response.answers.category.choice);

Each answer arrives under answers, keyed by the question's name.

Models

ModelModel ID
Jevtypesafe:jev@1
Layarunware:laya@1