Contents

Agents and editors

Any tool that speaks the OpenAI or Anthropic API works. Give it three things.

base urlhttps://us-region.api.safeailabs.ai/v1
keysail_… in SAFE_AI_KEY
modeldeepseek/deepseek-v4.1-flash

Keep /v1 on the base URL unless a tool adds it. Where a tool asks for a context window, use 1048576.

Sail, our coding agent, needs no setup. Install it and run sail login.

Coding agents: Claude Code · Codex CLI · OpenCode · Pi · OpenClaw · Hermes Agent · Paperclip · Aider · Goose · Crush · OpenHands · Qwen Code · Warp

Editors: Zed · Cursor · Cline, Roo Code, Kilo Code · Continue · JetBrains AI Assistant · GitHub Copilot in VS Code

Chat apps: Open WebUI · LibreChat · SillyTavern · Jan · Msty Studio

Frameworks and SDKs: Vercel AI SDK · OpenAI Agents SDK · LangChain · LiteLLM · LlamaIndex · CrewAI · Mastra · Pydantic AI · AutoGen · Semantic Kernel · Haystack

Workflow tools: n8n · Dify · Flowise · Langflow

Not yet

Claude Code

Claude Code sends the Anthropic Messages API and adds /v1/messages itself, so the base URL has no /v1. Set the variables in ~/.claude/settings.json or your shell.

RegionUnited Statesus-region

~/.claude/settings.json
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://us-region.api.safeailabs.ai",
    "ANTHROPIC_AUTH_TOKEN": "sail_…",
    "ANTHROPIC_MODEL": "deepseek/deepseek-v4.1-flash",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "deepseek/deepseek-v4.1-flash",
    "CLAUDE_CODE_MAX_CONTEXT_TOKENS": "1048576"
  }
}

Codex CLI

Codex sends the Responses API. Add a provider to ~/.codex/config.toml. Project-level files cannot set providers. Codex stops at the first rate limit rather than waiting for the retry time, so a long session on a busy key ends early; ask us to raise the key's limits if that happens. On an API plan, pacing slows a session rather than ending it, but a request that waits more than 60 s for one of the workspace's places returns 429 and the Codex session ends.

RegionUnited Statesus-region

~/.codex/config.toml
model = "deepseek/deepseek-v4.1-flash"
model_provider = "safeailabs"
model_context_window = 1048576

[model_providers.safeailabs]
name = "Safe AI Labs"
base_url = "https://us-region.api.safeailabs.ai/v1"
env_key = "SAFE_AI_KEY"
wire_api = "responses"

OpenCode

Add a provider to opencode.json in the project, or ~/.config/opencode/opencode.json for every project.

RegionUnited Statesus-region

opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "provider": {
    "safeailabs": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "Safe AI Labs",
      "options": {
        "baseURL": "https://us-region.api.safeailabs.ai/v1",
        "apiKey": "{env:SAFE_AI_KEY}"
      },
      "models": {
        "deepseek/deepseek-v4.1-flash": { "name": "DeepSeek V4.1 Flash", "limit": { "context": 1048576, "output": 65536 } }
      }
    }
  },
  "model": "safeailabs/deepseek/deepseek-v4.1-flash"
}

Pi

Add a provider to ~/.pi/agent/models.json. Pi reloads it when you open /model.

RegionUnited Statesus-region

~/.pi/agent/models.json
{
  "providers": {
    "safeailabs": {
      "baseUrl": "https://us-region.api.safeailabs.ai/v1",
      "api": "openai-completions",
      "apiKey": "$SAFE_AI_KEY",
      "models": [{ "id": "deepseek/deepseek-v4.1-flash", "name": "DeepSeek V4.1 Flash" }]
    }
  }
}

Run pi --model safeailabs/deepseek/deepseek-v4.1-flash, or pick it in /model and save it as the default.

OpenClaw

Formerly Clawdbot. Add a provider to ~/.openclaw/openclaw.json and set it as the primary model. Keep contextWindow and maxTokens: without them OpenClaw assumes a context window and output limit of its own, not the model's. Keep timeoutSeconds too: OpenClaw drops a request that has sent no tokens for 120 s. On an API plan a long prompt waits for the plan's cap before its first token: a 200,000-token prompt waits about 44 minutes on API Small. The setup allows 60 minutes.

RegionUnited Statesus-region

~/.openclaw/openclaw.json
{
  agents: { defaults: { model: { primary: "safeailabs/deepseek/deepseek-v4.1-flash" } } },
  models: {
    providers: {
      safeailabs: {
        baseUrl: "https://us-region.api.safeailabs.ai/v1",
        apiKey: "${SAFE_AI_KEY}",
        api: "openai-completions",
        timeoutSeconds: 3600,
        models: [{ id: "deepseek/deepseek-v4.1-flash", name: "DeepSeek V4.1 Flash", contextWindow: 1048576, maxTokens: 65536 }],
      },
    },
  },
}

Put your key in SAFE_AI_KEY, in the environment OpenClaw runs in or ~/.openclaw/.env. To switch to it later from the shell: openclaw models set safeailabs/deepseek/deepseek-v4.1-flash.

Hermes Agent

Point the model block in ~/.hermes/config.yaml at your region. The key goes in ~/.hermes/.env as SAFE_AI_KEY=sail_…. Hermes reads the model's context window from /v1/models with your key, so the block needs no context_length. Keep stale_timeout_seconds: Hermes drops a request that has sent no tokens for 180 s. On an API plan a long prompt waits for the plan's cap before its first token: a 200,000-token prompt waits about 44 minutes on API Small. The setup allows 60 minutes.

RegionUnited Statesus-region

~/.hermes/config.yaml
model:
  default: deepseek/deepseek-v4.1-flash
  provider: custom
  base_url: https://us-region.api.safeailabs.ai/v1
  api_key: ${SAFE_AI_KEY}
providers:
  custom:
    stale_timeout_seconds: 3600

Or run hermes model, choose the custom endpoint, and enter the base URL, your key and the model id. Leave the context length blank, then add the providers block above.

Paperclip

Paperclip runs other agents and reaches a model through the adapter of the agent it runs. Its OpenCode adapter takes an OpenAI-compatible provider: set PAPERCLIP_OPENCODE_PROVIDERS to this JSON, in the Paperclip server's environment or the agent's environment variables, with your key beside it as SAFE_AI_KEY.

RegionUnited Statesus-region

PAPERCLIP_OPENCODE_PROVIDERS
{
  "safeailabs": {
    "npm": "@ai-sdk/openai-compatible",
    "name": "Safe AI Labs",
    "options": {
      "baseURL": "https://us-region.api.safeailabs.ai/v1",
      "apiKey": "{env:SAFE_AI_KEY}"
    },
    "models": {
      "deepseek/deepseek-v4.1-flash": { "name": "DeepSeek V4.1 Flash", "limit": { "context": 1048576, "output": 65536 } }
    }
  }
}

Set the agent's model to safeailabs/deepseek/deepseek-v4.1-flash, and PAPERCLIP_OPENCODE_SMALL_MODEL to the same value, so the model OpenCode uses for helper tasks such as session titles is one your region serves. Paperclip applies both variables to an agent that runs on the Paperclip host with dangerouslySkipPermissions on, which is the adapter's default.

Paperclip's Hermes adapter has no model field: Hermes keeps its own model in ~/.hermes/config.yaml, set up as in Hermes Agent.

Aider

2 environment variables and a model prefixed openai/.

RegionUnited Statesus-region

Shell
export OPENAI_API_BASE=https://us-region.api.safeailabs.ai/v1
export OPENAI_API_KEY=$SAFE_AI_KEY
aider --model openai/deepseek/deepseek-v4.1-flash

Goose

Add a provider file to ~/.config/goose/custom_providers/ and select it in ~/.config/goose/config.yaml. Goose reads the key from the variable api_key_env names.

RegionUnited Statesus-region

~/.config/goose/custom_providers/safeailabs.json
{
  "name": "safeailabs",
  "engine": "openai",
  "display_name": "Safe AI Labs",
  "api_key_env": "SAFE_AI_KEY",
  "base_url": "https://us-region.api.safeailabs.ai/v1",
  "models": [{ "name": "deepseek/deepseek-v4.1-flash", "context_limit": 1048576 }],
  "supports_streaming": true
}
~/.config/goose/config.yaml
GOOSE_PROVIDER: safeailabs
GOOSE_MODEL: deepseek/deepseek-v4.1-flash

Crush

Add a provider to crush.json in the project, or ~/.config/crush/crush.json for every project. crush.json is the older format and is deprecated; newer releases take the same settings as provider add and model add lines in crushrc.

RegionUnited Statesus-region

crush.json
{
  "$schema": "https://charm.land/crush.json",
  "providers": {
    "safeailabs": {
      "name": "Safe AI Labs",
      "type": "openai-compat",
      "base_url": "https://us-region.api.safeailabs.ai/v1",
      "api_key": "$SAFE_AI_KEY",
      "models": [
        { "id": "deepseek/deepseek-v4.1-flash", "name": "DeepSeek V4.1 Flash", "context_window": 1048576, "default_max_tokens": 65536 }
      ]
    }
  },
  "models": { "large": { "provider": "safeailabs", "model": "deepseek/deepseek-v4.1-flash" } }
}

OpenHands

Settings, LLM, Advanced. Fill in the fields below and save.

modelopenai/deepseek/deepseek-v4.1-flash
base urlhttps://us-region.api.safeailabs.ai/v1
api keysail_…

Prefix the model with openai/. OpenHands sends requests through LiteLLM, which reads the prefix as the API shape.

Qwen Code

Add a model provider to ~/.qwen/settings.json. Qwen Code reads the key from the variable envKey names. Add "wireApi": "responses" to the model to send the Responses API instead.

RegionUnited Statesus-region

~/.qwen/settings.json
{
  "modelProviders": {
    "openai": [
      {
        "id": "deepseek/deepseek-v4.1-flash",
        "name": "DeepSeek V4.1 Flash",
        "envKey": "SAFE_AI_KEY",
        "baseUrl": "https://us-region.api.safeailabs.ai/v1"
      }
    ]
  },
  "security": { "auth": { "selectedType": "openai" } },
  "model": { "name": "deepseek/deepseek-v4.1-flash" }
}

Warp

Settings, search for inference endpoint. Add the base URL, your key and the model id, and save.

endpoint urlhttps://us-region.api.safeailabs.ai/v1
api keysail_…
modeldeepseek/deepseek-v4.1-flash

Warp sends the request from its own servers, so the request does not leave from your machine. Custom endpoints are on the Free plan and on paid plans for teams of 10 or fewer.

Zed

Add the provider in settings.json. Enter the key in the provider's settings panel, or set SAFEAILABS_API_KEY. Zed does not read keys from settings.

RegionUnited Statesus-region

settings.json
{
  "language_models": {
    "openai_compatible": {
      "safeailabs": {
        "api_url": "https://us-region.api.safeailabs.ai/v1",
        "available_models": [
          { "name": "deepseek/deepseek-v4.1-flash", "display_name": "DeepSeek V4.1 Flash", "max_tokens": 1048576 }
        ]
      }
    }
  }
}

Cursor

Settings, Models, API Keys. Turn on OpenAI API Key and paste your key. Turn on Override OpenAI Base URL and enter the base URL. Add a custom model named deepseek/deepseek-v4.1-flash.

Cursor sends the request from its own servers, so the request does not leave from your machine. The override applies to every model while it is on, and Tab keeps using Cursor's models.

Cline, Roo Code, Kilo Code

Choose the OpenAI Compatible provider in the extension settings and enter 3 fields.

base urlhttps://us-region.api.safeailabs.ai/v1
api keysail_…
model iddeepseek/deepseek-v4.1-flash

Set the context window to 1048576 in the model configuration. Kilo Code also reads ~/.config/kilo/kilo.jsonc, in the same shape as OpenCode.

Continue

Add a model to ~/.continue/config.yaml. Put the key in ~/.continue/.env; the extension does not read your shell.

RegionUnited Statesus-region

~/.continue/config.yaml
models:
  - name: DeepSeek V4.1 Flash
    provider: openai
    model: deepseek/deepseek-v4.1-flash
    apiBase: https://us-region.api.safeailabs.ai/v1
    apiKey: ${{ secrets.SAFE_AI_KEY }}
    roles: [chat, edit, apply]
    capabilities: [tool_use]

JetBrains AI Assistant

Settings, Tools, AI Assistant, Providers & API keys. Under Third-party AI providers choose OpenAI-compatible, fill in the fields below and select Test Connection.

urlhttps://us-region.api.safeailabs.ai/v1
api keysail_…
tool callingon

After Test Connection succeeds, pick the model from the list the provider returns.

GitHub Copilot in VS Code

Run Chat: Manage Language Models, select Add Models, then Custom Endpoint. Enter a group name, a display name and your key, and choose Chat Completions. VS Code opens chatLanguageModels.json for the rest.

RegionUnited Statesus-region

chatLanguageModels.json
[
  {
    "name": "Safe AI Labs",
    "vendor": "customendpoint",
    "apiKey": "${input:SAFE_AI_KEY}",
    "apiType": "chat-completions",
    "models": [
      {
        "id": "deepseek/deepseek-v4.1-flash",
        "name": "DeepSeek V4.1 Flash",
        "url": "https://us-region.api.safeailabs.ai/v1/chat/completions",
        "toolCalling": true,
        "vision": false,
        "maxInputTokens": 1048576,
        "maxOutputTokens": 65536
      }
    ]
  }
]

The url is the full path; VS Code adds nothing to it. VS Code asks for the key once and keeps it in its secret storage. A Copilot Business or Enterprise administrator can turn this off with the Bring Your Own Language Model Key policy.

Open WebUI

Set the connection when the container starts, or add it later in Admin Settings, Connections. Open WebUI reads the model list from /models.

RegionUnited Statesus-region

Shell
docker run -d -p 3000:8080 \
  -e OPENAI_API_BASE_URL=https://us-region.api.safeailabs.ai/v1 \
  -e OPENAI_API_KEY=$SAFE_AI_KEY \
  -v open-webui:/app/backend/data \
  --name open-webui ghcr.io/open-webui/open-webui:main

Chat titles, tags and follow-up suggestions are extra requests on the same key, sent to the chat model unless a task model is set in Admin Settings, Interface.

LibreChat

Add a custom endpoint to librechat.yaml and put SAFE_AI_KEY in LibreChat's .env.

RegionUnited Statesus-region

librechat.yaml
endpoints:
  custom:
    - name: "Safe AI Labs"
      apiKey: "${SAFE_AI_KEY}"
      baseURL: "https://us-region.api.safeailabs.ai/v1"
      models:
        default: ["deepseek/deepseek-v4.1-flash"]
        fetch: true
      titleConvo: true
      titleModel: "deepseek/deepseek-v4.1-flash"

SillyTavern

API Connections. Set API to Chat Completion and Chat Completion Source to Custom (OpenAI-compatible), then enter the fields below and select Connect.

custom endpointhttps://us-region.api.safeailabs.ai/v1
custom api keysail_…
model iddeepseek/deepseek-v4.1-flash

Enter the base URL with /v1 and without /chat/completions.

Jan

Settings, Model Providers, Add Provider. Choose the OpenAI API format and enter the base URL and your key. Jan reads the model list from /models; add the model with + if it is not listed.

base urlhttps://us-region.api.safeailabs.ai/v1
api keysail_…
model iddeepseek/deepseek-v4.1-flash

With the Anthropic API format, enter the base URL without /v1: https://us-region.api.safeailabs.ai.

Msty Studio

Model Hub, Model Providers, Add Provider, OpenAI compatible endpoint. Enter the base URL and your key, then select Fetch Models.

api endpointhttps://us-region.api.safeailabs.ai/v1
api keysail_…
modeldeepseek/deepseek-v4.1-flash

Vercel AI SDK

The OpenAI-compatible provider sends chat completions. The plain OpenAI provider works too and sends the Responses API.

RegionUnited Statesus-region

pnpm add ai @ai-sdk/openai-compatible
import { createOpenAICompatible } from "@ai-sdk/openai-compatible";
import { generateText } from "ai";

const safeailabs = createOpenAICompatible({
  name: "safeailabs",
  baseURL: "https://us-region.api.safeailabs.ai/v1",
  apiKey: process.env.SAFE_AI_KEY,
});

const { text } = await generateText({
  model: safeailabs("deepseek/deepseek-v4.1-flash"),
  prompt: "Hello",
});

OpenAI Agents SDK

Set a default client. Turn tracing off unless you also have an OpenAI key.

RegionUnited Statesus-region

import os
from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client, set_tracing_disabled

client = AsyncOpenAI(
    base_url="https://us-region.api.safeailabs.ai/v1",
    api_key=os.environ["SAFE_AI_KEY"],
)
set_default_openai_client(client, use_for_tracing=False)
set_tracing_disabled(True)

agent = Agent(name="Assistant", instructions="Be brief.", model="deepseek/deepseek-v4.1-flash")
result = Runner.run_sync(agent, "Hello")
print(result.final_output)

LangChain

RegionUnited Statesus-region

Python
import os
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model="deepseek/deepseek-v4.1-flash",
    base_url="https://us-region.api.safeailabs.ai/v1",
    api_key=os.environ["SAFE_AI_KEY"],
)

LiteLLM

Prefix the model with openai/. Works in the SDK and in the proxy config.

RegionUnited Statesus-region

import os
import litellm

r = litellm.completion(
    model="openai/deepseek/deepseek-v4.1-flash",
    api_base="https://us-region.api.safeailabs.ai/v1",
    api_key=os.environ["SAFE_AI_KEY"],
    messages=[{"role": "user", "content": "Hello"}],
)

LlamaIndex

Use OpenAILike with is_chat_model=True. Without it LlamaIndex sends legacy completions, and without context_window it assumes 3,900 tokens.

RegionUnited Statesus-region

pip install llama-index-llms-openai-like
import os
from llama_index.llms.openai_like import OpenAILike

llm = OpenAILike(
    model="deepseek/deepseek-v4.1-flash",
    api_base="https://us-region.api.safeailabs.ai/v1",
    api_key=os.environ["SAFE_AI_KEY"],
    context_window=1048576,
    is_chat_model=True,
    is_function_calling_model=True,
)
print(llm.complete("Hello"))

CrewAI

Prefix the model with openai/. Without it CrewAI takes the first part of the id for a provider of its own and ignores the base URL.

RegionUnited Statesus-region

pip install crewai
import os
from crewai import Agent, Crew, LLM, Task

llm = LLM(
    model="openai/deepseek/deepseek-v4.1-flash",
    base_url="https://us-region.api.safeailabs.ai/v1",
    api_key=os.environ["SAFE_AI_KEY"],
)
agent = Agent(role="Assistant", goal="Answer briefly", backstory="", llm=llm)
task = Task(description="Say hello", expected_output="A greeting", agent=agent)
print(Crew(agents=[agent], tasks=[task]).kickoff())

Mastra

Give the agent a model object with the base URL, the model id and the key.

RegionUnited Statesus-region

pnpm add @mastra/core
import { Agent } from "@mastra/core/agent";

const agent = new Agent({
  id: "assistant",
  name: "Assistant",
  instructions: "Be brief.",
  model: {
    id: "deepseek/deepseek-v4.1-flash",
    url: "https://us-region.api.safeailabs.ai/v1",
    apiKey: process.env.SAFE_AI_KEY,
  },
});

const result = await agent.generate("Hello");
console.log(result.text);

Pydantic AI

OpenAIChatModel sends chat completions. OpenAIResponsesModel takes the same provider and sends the Responses API.

RegionUnited Statesus-region

pip install pydantic-ai
import os
from pydantic_ai import Agent
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.providers.openai import OpenAIProvider

model = OpenAIChatModel(
    "deepseek/deepseek-v4.1-flash",
    provider=OpenAIProvider(base_url="https://us-region.api.safeailabs.ai/v1", api_key=os.environ["SAFE_AI_KEY"]),
)
agent = Agent(model)
print(agent.run_sync("Hello").output)

AutoGen

AutoGen needs model_info for a model it does not know, with all 5 fields set. AutoGen is in maintenance; Microsoft Agent Framework replaces it.

RegionUnited Statesus-region

pip install "autogen-ext[openai]"
import asyncio, os
from autogen_core.models import UserMessage
from autogen_ext.models.openai import OpenAIChatCompletionClient

client = OpenAIChatCompletionClient(
    model="deepseek/deepseek-v4.1-flash",
    base_url="https://us-region.api.safeailabs.ai/v1",
    api_key=os.environ["SAFE_AI_KEY"],
    model_info={
        "vision": False,
        "function_calling": True,
        "json_output": True,
        "structured_output": True,
        "family": "unknown",
    },
)

async def main():
    r = await client.create([UserMessage(content="Hello", source="user")])
    print(r.content)
    await client.close()

asyncio.run(main())

Semantic Kernel

Pass an OpenAI client that points at your region.

RegionUnited Statesus-region

pip install semantic-kernel
import asyncio, os
from openai import AsyncOpenAI
from semantic_kernel.connectors.ai.open_ai import OpenAIChatCompletion, OpenAIChatPromptExecutionSettings
from semantic_kernel.contents import ChatHistory

chat = OpenAIChatCompletion(
    ai_model_id="deepseek/deepseek-v4.1-flash",
    async_client=AsyncOpenAI(base_url="https://us-region.api.safeailabs.ai/v1", api_key=os.environ["SAFE_AI_KEY"]),
)

async def main():
    history = ChatHistory()
    history.add_user_message("Hello")
    print(await chat.get_chat_message_content(history, OpenAIChatPromptExecutionSettings()))

asyncio.run(main())

Haystack

RegionUnited Statesus-region

pip install haystack-ai
from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack.utils import Secret

llm = OpenAIChatGenerator(
    model="deepseek/deepseek-v4.1-flash",
    api_base_url="https://us-region.api.safeailabs.ai/v1",
    api_key=Secret.from_env_var("SAFE_AI_KEY"),
)
print(llm.run([ChatMessage.from_user("Hello")])["replies"][0].text)

n8n

Create an OpenAI credential with your key and the base URL. In the OpenAI Chat Model node, choose the model by ID and enter deepseek/deepseek-v4.1-flash.

credentialOpenAI
api keysail_…
base urlhttps://us-region.api.safeailabs.ai/v1

Dify

Install the OpenAI-API-compatible plugin from the marketplace. In Settings, Model Provider, select Add Model on its card, choose the LLM type and fill in the fields below.

model namedeepseek/deepseek-v4.1-flash
api keysail_…
api endpoint urlhttps://us-region.api.safeailabs.ai/v1
model context size1048576

Set function calling support on if a workflow uses tools.

Flowise

Add a ChatOpenAI node. Create a credential with your key, set Model Name, then open Additional Parameters and set Base Path.

model namedeepseek/deepseek-v4.1-flash
api keysail_…
base pathhttps://us-region.api.safeailabs.ai/v1

The Flowise repository was archived on 13 Aug 2026, and 3.1.4 is its last release.

Langflow

Settings, Model Providers, OpenAI Compatible. Enter the base URL and your key and save. Langflow lists the models from /models; turn on the model, then choose OpenAI Compatible in a Language Model or Agent component.

base urlhttps://us-region.api.safeailabs.ai/v1
api keysail_…
modeldeepseek/deepseek-v4.1-flash

Not yet

  • Gemini CLI sends only the Gemini API, which is not served.
  • Windsurf is now Devin Desktop, which offers its own models and a few named cloud models, with no custom base URL.
  • Amp routes to a custom URL only in early access for its Megawatt, Gigawatt and Enterprise plans.
  • Make and Zapier have OpenAI apps with no base URL setting. Call the API from their HTTP modules instead.

See Compatibility for what is served.

Back toQuickstart

These docs as plain text for coding agents: llms.txt