LLM APIの始め方
今の開発環境から、複数のAIモデルを1つのAPIキーで。
Quickstart
まず接続し、実際の作業を1件試します。OpenAI SDKを使う場合は、接続先とAPIキーを設定してください。
⚡ Sente(先手)— ターミナルで動くコーディングエージェント
Sente(先手)は、プロジェクトのコードを読み、調査・修正・確認を進めるCLIエージェントです。コマンドはte。インストール後にセットアップし、自分のプロジェクトで使います。
- 用意するもの:macOS / Linux(arm64・x64)のターミナル、curl・tar・Python 3、インターネット接続、作業するプロジェクト。Windowsではこの手順をWSL内で実行します。プロジェクト自体の実行環境はREADMEで確認してください。
- 認証:登録後、DashboardでAPIキーを発行して手元に用意します。
1. ターミナル:インストール
curl -fsSL https://teai.io/te | sh
入力欄に te_ で始まるAPIキーを貼ります(既存キーがあれば省略)。Enterでスキップした場合は、次の te login でキーを入力。te login 成功時の Saved to … が保存の目印です。独立した te setup コマンドはありません。
2. ターミナル:キーを確認・設定
te login
3. ターミナル:対象フォルダで起動
次の /path/to/project は引用符を残して実際のプロジェクトのパスに置き換えます。空白を含むパスにも対応し、移動に成功したときだけSenteを起動します。
cd "/path/to/project" && te
Senteの入力画面が開いたら、次の文章をSente内に貼ります。te で始まる端末コマンドと、Senteへの依頼文は入力先が違います。
このプロジェクトの起動手順を調べて、必要なコマンドを教えてください。設定が足りなければ、その項目を示してください。
案内された手順でプロジェクトが起動するか確認します。既存の開発ツールへの接続は接続ガイドへ。
最初の1件を、調査 → 実装・検証 → 引継ぎ
自分のプロジェクトでSenteを初めて使う方向け。起動を妨げる問題を1件調べ、必要なら修正し、検証結果と再開用メモを残します。未導入ならインストール・認証から。
導入済みならターミナルで te update を実行し、Senteを終了・再起動します。既存の個人コマンドは保持されるため、同名の定義がある場合は動作を確認してください。
用語:MCPは外部のサービスやツールにつなぐ仕組み。個人コマンドは自分で定義した /名前 の依頼テンプレートです。以下のコマンドは配布済みのテンプレートで、実際の操作はモデル・設定・権限に依存します。
料金・データ:モデルへの依頼は選択モデル・接続先の料金に従います(teai料金・残高)。会話、読み込んだコードの一部、ツール出力などは選択モデルの接続先へ送られ、MCP利用時はその接続先とも通信します。APIキーは認証欄で扱い、依頼文やGitには含めません。詳細は te privacy とデータの扱いへ。
準備:プロジェクトのディレクトリで設定確認
te doctor --workflow
LLMを呼ばずに有効な設定を確認します。Sente内では /workflow で設定の説明を頼めます。どちらも、MCPやAPIの接続・認証成功を証明するものではありません。
Sente内で、結果を確認しながら1つずつ依頼
/investigate 対象は今開いているプロジェクトです。起動手順と、起動を妨げる問題を1件調べてください。ファイルは変更せず、根拠のファイルと未確認の前提を示してください。コマンド実行が必要なら、その内容と目的を先に示してください。
結果で分岐:問題を再現できたら次の修正へ。問題なしなら修正を飛ばして引継ぎへ。未再現なら、試した手順・期待した結果・実際のエラーを補足して再調査します。
次の依頼は、この問題に必要なファイル変更と検証コマンドの実行までが対象です。公開・デプロイ、削除、課金が必要になったら追加確認するよう依頼します。
/implement 調査した問題を、このプロジェクト内の必要な変更で修正してください。プロジェクトの規約に従い、必要な検証を実行して、差分・実行したテストと結果・未確認事項を示してください。公開・デプロイ、削除、課金が必要なら先に確認してください。
/handoff 目的、制約、変更したファイル、実行した検証と未実行の検証、次の一手を1つまとめてください。編集権限があれば引継ぎを保存し、保存先を示してください。
/handoff は workflow_checkpoint の観測に目的や次の一手を添えます。checkpoint自体は読取専用で、自動保存や作業完了を保証しません。編集できなければ返答のテキストを保存し、再開時は作業ツリーと検証結果を確認し直してください。
再開:同じプロジェクトで新しいSenteを開く
次の docs/handoff.md は実際に保存されたパスへ置き換えます。保存していない場合は、引継ぎの返答をこの依頼と一緒に貼ってください。
docs/handoff.md の引継ぎを読んでください。現在の差分と検証結果を確認し直し、残っている次の一手から再開してください。完了済みと未確認を分けてください。
つまずいたら
- command not found:端末で
export PATH="$HOME/.local/bin:$PATH"を実行して再試行。まだ見つからなければインストールのエラーを確認します(独自のインストール先を指定した場合はそのパスを使用)。 - 認証エラー:接続とDashboardのキーを確認し、端末で
te loginをやり直します。環境変数TEAI_API_KEYは保存キーより優先されます。保存キーを使うなら同じ端末でunset TEAI_API_KEYを実行してから再起動。環境変数で管理するなら、その値を正しいキーへ更新して再起動します。残高不足なら同じ画面で確認します。 - /コマンドが見つからない:端末で
te update→ Senteを再起動 →/で候補を確認。個人定義がある場合は~/.config/sente/command/・commands/・sente.jsonの同名定義を確認します。通常文で依頼する場合も、調査だけか変更までかを明記してください。
マルチエージェントへの依頼例
複数エージェントの利用を明示して頼む例です。利用できるツール・権限によって実行可否が変わり、並列化や品質を保証するものではありません。
/implement この問題をマルチエージェントで調査・修正してください。独立した調査は並列に進め、根拠を統合してから実装してください。実装後は別のエージェントに差分をレビューしてもらい、指摘に対応してください。最後に実行したテストと結果、未確認事項、次の一手を示してください。
1. 登録してAPIキーを取得
無料登録 → DashboardでAPIキーを発行。キーはte_で始まります。登録で100クレジット。生成時に残高を消費します。
2. 接続先と環境変数を設定
macOS / Linuxのターミナル例です。発行したキーを環境変数 TEAI_API_KEY に設定します。
export TEAI_API_KEY="te_your_api_key"
3. コードを実行
python3 -m pip install openai
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.teai.io/v1",
api_key=os.environ["TEAI_API_KEY"],
)
response = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
コードを quickstart.py に保存し、python3 quickstart.py で実行します。
npm install openai
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.teai.io/v1",
apiKey: process.env.TEAI_API_KEY,
});
const response = await client.chat.completions.create({
model: "auto",
messages: [{ role: "user", content: "Hello!" }],
});
console.log(response.choices[0].message.content);
コードを quickstart.mjs に保存し、node quickstart.mjs で実行します。
curl https://api.teai.io/v1/chat/completions \
-H "Authorization: Bearer $TEAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"messages": [{"role": "user", "content": "Hello!"}]
}'
API接続で困ったとき
まずAPIキーの読み込みとモデル一覧を確認します。次のコマンドはモデル一覧を取得するだけで、文章を生成しません。
curl --fail-with-body --max-time 30 https://api.teai.io/v1/models \
-H "Authorization: Bearer $TEAI_API_KEY"
モデル一覧の取得だけでは、認証や残高、生成の成功までは確認できません。生成リクエストのステータスと本文も確認してください。
401:APIキーを確認
実行するターミナルでTEAI_API_KEYを設定し、SDKのキー指定を確認します。必要ならDashboardで再発行します。同じ無効なキーで再試行しても解消しません。
402:残高とエラー本文を確認
エラー本文が残高不足を示している場合は、Dashboardで残高とチャージ反映を確認してください。残高を確認できるまで生成の自動再試行を止めます。
429:指定された時間を待つ
Retry-Afterがあればその指示に従います。短時間に連打せず、同時実行数を減らしてください。
空の回答・タイムアウト
空の回答を成功として扱わず、モデル・出力上限・エラー本文を確認します。タイムアウトはサーバー側の処理完了が不明なため、再送で重複処理や追加消費が起き得ます。稼働状況と利用履歴を確認してから判断してください。
SenteエージェントAPI v1
Mac・Cloudで動くSenteへ、外部プログラムから指示を送り、会話履歴・進捗・承認待ちを扱うAPIです。teaiのモデルAPIとは別の接続先・認証・リクエスト形式です。OpenAI SDKのchat/completionsへ送るAPIではありません。
| 実行環境 | Base URL | 認証情報 |
|---|---|---|
| Mac loopback | http://127.0.0.1:4097/api/v1 | SENTE_REMOTE_TOKEN |
| Mac / Tailscale | http://<mac-tailnet-host>:4097/api/v1 | SENTE_REMOTE_TOKEN |
| Cloud | https://sente.teai.io/api/v1 | Cloudユーザーセッショントークン |
MacとCloudのファイル・セッション・認証は独立しています。接続先を切り替えても履歴は同期されません。Mac APIは導入済みの常駐エンジンが必要で、CLIのインストールだけで自動公開されるものではありません。
エージェント認証
Authorization: Bearer <agent-token>
Content-Type: application/json
Macは導入時に作成する ~/.config/teai/remote-api.env の SENTE_REMOTE_TOKEN を使用します。Cloudは通常のメールOTP・Googleログインで得るユーザーセッショントークンを使用します。DashboardのteaiモデルAPIキーやjobs用worker tokenでは代用できません。
CloudのOTPはルート直下の POST /auth/request に {"email":"<your-email>"}、続けて POST /auth/verify に {"email":"<your-email>","code":"<received-code>"} を送信します。招待・プランの条件は通常ログインと同じです。トークンはURL・チャット・Git・ログに載せず、401なら再認証してください。
Macへ外部接続する場合は、Macを電源につないでログインした状態にし、クライアントも同じTailscaleに参加します。公開インターネットへ直接開放しないでください。Bearerを付けられるサーバー側クライアントを使います。別オリジンのブラウザからの直接呼出しは対象外です。
最初の推論
Node.js 22以降の例です。まず接続済みモデル一覧を取得し、ツールを禁止した専用セッションで短い推論を1回実行します。生成は課金対象になり得ます。コードをagent-check.mjsへ保存してください。
const base = process.env.SENTE_API_BASE;
const token = process.env.SENTE_AGENT_TOKEN;
if (!base || !token) throw Error("Set SENTE_API_BASE and SENTE_AGENT_TOKEN");
const headers = {
authorization: `Bearer ${token}`,
"content-type": "application/json",
};
async function call(path, method = "GET", body) {
const response = await fetch(base + path, {
method, headers,
body: body === undefined ? undefined : JSON.stringify(body),
signal: AbortSignal.timeout(180000),
});
if (!response.ok) throw Error(`HTTP ${response.status} at ${path}`);
return response.status === 204 ? undefined : response.json();
}
const catalog = await call("/provider");
const providerID = "teai";
const modelID = "qwen/qwen3.7-flash";
if (!catalog.connected.includes(providerID) ||
!catalog.all.some(p => p.id === providerID && Object.hasOwn(p.models, modelID))) {
throw Error("Select a connected model from /provider");
}
const session = await call("/session", "POST", {
title: "API inference check",
permission: [{ permission: "*", pattern: "*", action: "deny" }],
});
console.log("session", session.id);
const result = await call(`/session/${session.id}/message`, "POST", {
model: { providerID, modelID },
parts: [{ type: "text", text: "Without tools, compute 17 + 25." }],
});
if (result.info?.error) throw Error(`Model error: ${result.info.error.name}`);
const text = result.parts.filter(p => p.type === "text").map(p => p.text).join("\n");
if (!text.trim()) throw Error("Empty answer; inspect session history");
console.log(text);
SENTE_API_BASEへ上の接続先、SENTE_AGENT_TOKENへその接続先のトークンを、安全な環境変数・Secretsから設定して実行します。既存Mac設定を読む場合は次のコマンドを使えます。秘密は出力しません。
node --env-file="$HOME/.config/teai/remote-api.env" --input-type=module -e '
process.env.SENTE_API_BASE = "http://127.0.0.1:4097/api/v1";
process.env.SENTE_AGENT_TOKEN = process.env.SENTE_REMOTE_TOKEN;
await import("./agent-check.mjs");
'
返答テキストとinfo.errorを確認し、必要なら同じIDの会話履歴を取得してください。HTTP 200やhealth成功だけでは推論成功を証明しません。noReply:trueは保存のみです。ツールを使う本来の仕事では、用途に必要な権限だけを付与してください。
エンドポイント
以下はエージェントのBase URLからの相対パスです。
| Method | Path | 用途 |
|---|---|---|
| GET | /global/health | エンジンの稼働確認 |
| GET | /provider | 接続済みモデル一覧 |
| GET / POST | /session | セッション一覧・作成 |
| GET | /session/:id | セッション情報 |
| POST | /session/:id/message | 同期推論 |
| POST | /session/:id/prompt_async | 非同期推論・通常204で受付 |
| GET | /session/:id/message | 会話履歴 |
| GET | /session/status | セッション別の実行状態 |
| GET | /event | SSEイベント |
| POST | /session/:id/abort | 実行停止 |
| GET | /permission, /question | 権限・質問の承認待ち |
| POST | /permission/:id/reply | 権限への返答 |
| POST | /question/:id/reply, /question/:id/reject | 質問への回答・拒否 |
メッセージ単体、todo・diff・children、Mac導入・運用の詳細は完全なAPI仕様を参照してください。
進捗・続行・停止
Bearer付きで/eventへ接続し、同じ推論本文を/prompt_asyncへPOSTします。204は受付であり完了ではありません。SSEのdata:行のJSONを読み、sessionIDやproperties.info.sessionIDで対象を絞ります。server.connectedは接続確認のみです。
続行は同じセッションIDへ次の指示を送ります。SSEが切れたら履歴と/session/statusで照合します。完全なイベント再送は保証しません。タイムアウトした推論を自動再送しないでください。処理が続いている可能性がある場合は/abortへPOSTします。
権限要求への本文は {"reply":"once"}(once / always / reject)、質問への本文は {"answers":[["<selected-answer>"]]} です。要求IDと内容を確認してから返答してください。Mac APIは本人のエンジンへのアクセスであり、独立した低権限サンドボックスではありません。
エラー・検証範囲
401はトークン、403は権限・Origin、404は未対応パスやセッション、413は本文サイズ、429は利用制限、503はエンジンやモデル設定を確認します。Cloudのmodel_configuration_unavailableとsubmitted:falseは推論を渡す前の失敗です。それ以外のタイムアウトは履歴と状態で確認してください。
2026-10-04にQwenでMac・Cloudの短い推論と履歴保存を確認(約2.1秒 / 4.0秒)、認証・health・SSEも確認しました。Geminiは同日の確認で上流課金エラーを返しました。これは現在の可用性・速度の保証ではありません。別端末からのMac接続、OS再起動後・閉蓋中の常駐、任意のツール作業・非同期続行は未確認です。
Authentication
全てのAPIリクエストにはAuthorizationヘッダーが必要です。
Authorization: Bearer te_your_api_key
APIキーはDashboardで発行・管理できます。キーは発行時に1回だけ表示されるので、安全に保管してください。
Base URL
全てのエンドポイントはこのBase URLからの相対パスです。OpenAI SDKのbase_urlにそのまま設定できます。
POST /v1/chat/completions
チャット補完を生成します。OpenAI Chat Completions API完全互換。
Request Body
| Parameter | Type | Required | Description |
|---|---|---|---|
| model | string | Yes | 使用するモデル (例: gpt-4o, claude-sonnet-4-6) |
| messages | array | Yes | メッセージ配列 (role: system/user/assistant) |
| temperature | number | No | 0.0~2.0 (default: 1.0) |
| max_tokens | integer | No | 生成する最大トークン数 |
| stream | boolean | No | SSEストリーミングを有効にする |
| tools | array | No | Function calling用のツール定義 |
| tool_choice | string | No | "auto", "none", "required" |
Response
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1710000000,
"model": "gpt-4o",
"choices": [{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you?"
},
"finish_reason": "stop"
}],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 8,
"total_tokens": 20
}
}
Streaming
"stream": trueを指定すると、SSE (Server-Sent Events) でトークンが逐次返されます。
stream = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Rustの特徴を3つ教えて"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
const stream = await client.chat.completions.create({
model: "claude-sonnet-4-6",
messages: [{ role: "user", content: "Rustの特徴を3つ教えて" }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content || "");
}
curl https://api.teai.io/v1/chat/completions \
-H "Authorization: Bearer te_your_api_key" \
-H "Content-Type: application/json" \
-N \
-d '{
"model": "claude-sonnet-4-6",
"messages": [{"role": "user", "content": "Rustの特徴を3つ教えて"}],
"stream": true
}'
SSE Event Format
ストリーミング時、各チャンクは以下のフォーマットで返されます。各行は data: プレフィックスで始まり、最終行は data: [DONE] です。
# コンテンツチャンク
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1710000000,"model":"gpt-4o","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}
# 終了チャンク
data: {"id":"chatcmpl-abc","object":"chat.completion.chunk","created":1710000000,"model":"gpt-4o","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
# ストリーム終端
data: [DONE]
data: プレフィックスを除去し、[DONE] をストリーム終端として扱ってください。
Credits
teai.io はクレジット制を採用しています。1 クレジットはコスト単位であり、トークン数と直接は一致しません。モデルごとに 1K トークンあたりのクレジット消費量が異なります。
クレジット消費の目安
| モデル | Input (per 1K tokens) | Output (per 1K tokens) |
|---|---|---|
| qwen/qwen3.7-flash | 1 credit | 1 credit |
| gemini-2.5-flash | 1 credit | 3 credits |
| deepseek-chat | 1 credit | 1 credit |
| gpt-4o | 5 credits | 15 credits |
| claude-sonnet-4-6 | 6 credits | 18 credits |
- Free プラン: 登録だけで 100 クレジット付与(カード不要)+ Qwen3.7 Flash は激安(入力$0.03/100万token)
- 有効期限なし: クレジットは期限切れになりません
- 残高確認: レスポンスの
X-Credits-Remainingヘッダー、またはGET /api/v1/auth/meで確認できます
# 残高確認
curl https://api.teai.io/api/v1/auth/me \
-H "Authorization: Bearer te_your_api_key"
# レスポンス例
{
"user_id": "usr_abc",
"credits": 87,
"plan": "free"
}
GET /v1/models
利用可能な全モデルの一覧を返します。
curl https://api.teai.io/v1/models \
-H "Authorization: Bearer te_your_api_key"
GET /v1/models/pricing
各モデルの料金情報を含む詳細一覧を返します。
curl https://api.teai.io/v1/models/pricing \
-H "Authorization: Bearer te_your_api_key"
詳細な料金はPricingページを参照してください。
Tool Calling (Function Calling)
OpenAI互換のFunction Calling形式でツールを定義できます。
response = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": "東京の天気は?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
}
}],
)
Python SDK
Installation
pip install openai
Setup
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.teai.io/v1",
api_key=os.environ["TEAI_API_KEY"],
)
# auto(自動モデル選択)を使用
r = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": "日本の首都は?"}],
)
print(r.choices[0].message.content)
# Claude Sonnetに切り替え(コード変更は1箇所だけ)
r = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Pythonでクイックソートを書いて"}],
)
print(r.choices[0].message.content)
# 激安モデル(Qwen3.7 Flash)
r = client.chat.completions.create(
model="qwen/qwen3.7-flash",
messages=[{"role": "user", "content": "自己紹介して"}],
)
print(r.choices[0].message.content)
Node.js SDK
Installation
npm install openai
Setup
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.teai.io/v1",
apiKey: process.env.TEAI_API_KEY,
});
// モデルを自由に切り替え
const models = ["gpt-4o", "claude-sonnet-4-6", "gemini-2.5-flash"];
for (const model of models) {
const r = await client.chat.completions.create({
model,
messages: [{ role: "user", content: "1+1=" }],
});
console.log(`${model}: ${r.choices[0].message.content}`);
}
Go SDK
Installation
go get github.com/sashabaranov/go-openai
Setup
package main
import (
"context"
"fmt"
"os"
openai "github.com/sashabaranov/go-openai"
)
func main() {
config := openai.DefaultConfig(os.Getenv("TEAI_API_KEY"))
config.BaseURL = "https://api.teai.io/v1"
client := openai.NewClientWithConfig(config)
resp, err := client.CreateChatCompletion(
context.Background(),
openai.ChatCompletionRequest{
Model: "auto",
Messages: []openai.ChatCompletionMessage{
{Role: openai.ChatMessageRoleUser, Content: "Hello!"},
},
},
)
if err != nil {
panic(err)
}
fmt.Println(resp.Choices[0].Message.Content)
}
Java SDK
Maven
<dependency>
<groupId>com.openai</groupId>
<artifactId>openai-java</artifactId>
<version>0.8.0</version>
</dependency>
Setup
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.*;
OpenAIClient client = OpenAIOkHttpClient.builder()
.baseUrl("https://api.teai.io/v1")
.apiKey(System.getenv("TEAI_API_KEY"))
.build();
ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
.model("auto")
.addUserMessage("Hello!")
.build();
client.chat().completions().create(params)
.choices()
.forEach(c -> System.out.println(c.message().content()));
curl
# 環境変数にAPIキーを設定
export TEAI_API_KEY="te_your_api_key"
# Chat Completion
curl https://api.teai.io/v1/chat/completions \
-H "Authorization: Bearer $TEAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "auto",
"messages": [{"role": "user", "content": "Hello!"}]
}'
# モデル一覧
curl https://api.teai.io/v1/models \
-H "Authorization: Bearer $TEAI_API_KEY"
# ストリーミング
curl https://api.teai.io/v1/chat/completions \
-H "Authorization: Bearer $TEAI_API_KEY" \
-H "Content-Type: application/json" \
-N \
-d '{
"model": "deepseek-chat",
"messages": [{"role": "user", "content": "日本の歴史を要約して"}],
"stream": true
}'
Error Handling
全てのエラーレスポンスは統一的なJSON形式で返されます。
| Status | error.type | Description | 対処法 |
|---|---|---|---|
| 400 | invalid_request | リクエスト形式が不正 | パラメータを確認 |
| 401 | authentication_error | APIキーが無効または未指定 | APIキーを確認・再発行 |
| 402 | insufficient_credits | クレジット残高不足 | クレジットを追加購入 |
| 404 | model_not_found | 指定モデルが存在しない | /v1/models で確認 |
| 429 | rate_limit_exceeded | レート制限超過 | Retry-Afterヘッダーに従う |
| 500 | internal_error | サーバー内部エラー | エクスポネンシャルバックオフでリトライ |
| 502 | upstream_error | 上流プロバイダーエラー | 別モデルを試す or リトライ |
| 503 | service_unavailable | メンテナンス中 | ステータスページを確認 |
エラーレスポンス形式
{
"error": {
"type": "rate_limit_exceeded",
"message": "Rate limit exceeded. Retry after 30 seconds.",
"code": 429,
"retry_after": 30
}
}
リトライ戦略
最初の接続確認ではSDKの自動再試行を無効にし、エラーを1回ずつ確認します。401・402は設定や残高の確認が先です。429はRetry-After、5xxは稼働状況を確認してから再試行を判断してください。
import os
from openai import OpenAI, APIStatusError, APIConnectionError
client = OpenAI(
base_url="https://api.teai.io/v1",
api_key=os.environ["TEAI_API_KEY"],
max_retries=0,
timeout=60.0,
)
try:
response = client.chat.completions.create(
model="auto",
messages=[{"role": "user", "content": "Hello!"}],
max_tokens=256,
)
except APIStatusError as error:
print("HTTP", error.status_code)
print("Retry-After:", error.response.headers.get("retry-after", "not provided"))
raise
except APIConnectionError:
print("Connection failed; server-side completion is unknown. No automatic retry.")
raise
else:
content = response.choices[0].message.content if response.choices else None
if not content or not content.strip():
raise RuntimeError("Empty answer; check the model and output limit before retrying.")
print(content)
Rate Limits
| Plan | Requests/hour | Requests/day |
|---|---|---|
| Free (認証済み) | 120 | 500 |
| Guest (未認証) | 30 | 30 |
| Pro | 7,200 | なし |
| Business | カスタム | 無制限 |
レート制限に達した場合、エラーメッセージが返されます。レスポンスボディのerrorフィールドを確認し、適切な間隔をあけてリトライしてください。
APIキーごとの使用上限
Dashboardの「APIキー」で、キーごとに1分・1時間・1日・1ヶ月の使用上限をクレジットで設定できます。上限に達するとそのキーのリクエストは 402(api_key_minute_limit_exceeded など期間ごとのコード)で止まり、次の区切り(日・月はUTC基準)で自動的に再開します。空欄は上限なしです。Senteでは再開時刻が表示されます。
Timeouts
| Parameter | Value | Description |
|---|---|---|
| 接続タイムアウト | 10秒 | TCP接続の確立まで |
| 非ストリーミング | 25秒 | レスポンス完了まで |
| ストリーミング | 25秒(各チャンク間) | 各チャンク間の最大待ち時間 |
| アイドルタイムアウト | 30秒 | SSEチャンク間の最大待ち時間 |
stream: trueの使用を推奨します。
Model Versioning
モデルIDの指定方法により、バージョン固定の有無を制御できます。
| 指定方法 | 例 | 動作 |
|---|---|---|
| エイリアス(推奨) | gpt-4o | プロバイダーの最新安定版を自動追従 |
| バージョン固定 | gpt-4o-2024-08-06 | 指定バージョンに固定。廃止予定時は30日前に通知 |
- バージョン変更通知: エイリアスが指すバージョンが変更される場合、Changelogで事前告知します
- 旧バージョン保持: 廃止されたバージョンは最低90日間サポートを継続
- 本番環境: 回帰テストの安定性が重要な場合はバージョン固定を推奨
Failover Behavior
teai.ioの自動フェイルオーバーはリクエストの指定方法により動作が異なります。
teai.ioの内部ルーティングはLoadBalancedProviderにより、サーキットブレーカー + ラウンドロビンで自動フェイルオーバーを実現しています。
- 明示的モデル指定:
"model": "gpt-4o"のように指定した場合、そのモデルを使用します。プロバイダー障害時はティア内の次のモデルにフェイルオーバーします。 - ティアベースの自動選択: economy / normal / powerful ティアに応じて最適なモデルが自動選択されます。
- 全プロバイダー障害時: セルフホストモデルが最終フォールバックとして動作します。
レスポンスの model_used フィールド
レスポンスボディのmodelフィールドに、実際に使用されたモデル名が返されます。フェイルオーバーが発生したかを確認できます。
{
"model": "claude-sonnet-4-6", // 実際に使用されたモデル
"choices": [...]
}
Models
主要モデルの一覧です。全モデルと詳細な料金はPricingページを参照してください。
| Model ID | Provider | Context | Credits/1K Input | Credits/1K Output |
|---|---|---|---|---|
| qwen/qwen3.7-flash | Alibaba (OpenRouter) | 1M | 1 | 1 |
| gpt-4o | OpenAI | 128K | 0.375 | 1.50 |
| claude-sonnet-4-6 | Anthropic | 200K | 0.375 | 1.50 |
| gemini-2.5-flash | 1M | 0.075 | 0.30 | |
| deepseek-chat | DeepSeek | 64K | 0.135 | 0.54 |
qwen/qwen3.7-flash は入力$0.03/100万tokenの激安モデルです。全モデルの詳細スペックと最新料金は /pricing を参照してください。