Tổng Quan

Bắt Đầu Nhanh

TokSpan tương thích với OpenAI — chỉ cần thay đổi base URL để truy cập hơn 200 mô hình ngay lập tức. Claude Code / Anthropic gốc và OpenAI Responses API cũng được hỗ trợ, và tính năng tạo video Doubao Seedance dùng chung một khóa, xem bên dưới.

1

Đăng ký và đăng nhập

Đăng ký bằng email tại trang đăng ký của chúng tôi.

2

Tạo khóa API

Tạo khóa sk- trên trang API Keys trong Bảng điều khiển.

3

Thay đổi Base URL

Trỏ base URL của SDK đến một trong các URL bên dưới và gọi bằng khóa của bạn.

4

Cập nhật / Thêm Model ID

Đi tới Model Plaza để lấy ID của mô hình, sau đó cập nhật nó.

URL Cơ Sở API

TokSpan hỗ trợ nhiều giao thức API. Chọn giao thức SDK của bạn đã dùng — mọi định dạng đều chấp nhận cùng một khóa và truy cập hơn 200 mô hình.

Tương thích OpenAI
https://api.tokspan.com/v1

SDK OpenAI đã bao gồm /v1 và tự động thêm /chat/completions.

Anthropic Gốc
https://api.tokspan.com

Dùng đường dẫn gốc của máy chủ — Claude Code và SDK Anthropic tự thêm /v1/messages.

Video Generation API
https://api.tokspan.com/v1/videos

POST /v1/videos tạo một tác vụ và trả về id của tác vụ; hãy thăm dò trạng thái cho đến khi video sẵn sàng, rồi tải nội dung về.

Responses API
https://api.tokspan.com/v1

Dùng lại base URL tương thích OpenAI và gọi /v1/responses.

Tương thích OpenAI

python
from openai import OpenAI

client = OpenAI(
    api_key="sk-your-api-key",
    base_url="https://api.tokspan.com/v1",  # ← OpenAI-compatible base URL
)

response = client.chat.completions.create(
    model="MODEL_NAME",  # Replace MODEL_NAME with any model from the catalog
    messages=[{"role": "user", "content": "Hello!"}],
)

print(response.choices[0].message.content)

Anthropic Gốc

python
from anthropic import Anthropic

client = Anthropic(
    api_key="sk-your-api-key",
    base_url="https://api.tokspan.com",  # ← Native Anthropic base URL (host root; SDK appends /v1/messages)
)

response = client.messages.create(
    model="MODEL_NAME",  # Replace MODEL_NAME with any Claude model from the catalog
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)

print(response.content[0].text)

Video Generation API

python
"""
Doubao Seedance video generation - Python example.

Video generation is asynchronous: submit a task, poll it, then download the
result. Requires `pip install requests`.
"""

import time
from typing import Any, Dict, Optional

import requests

# ---------------------------------------------------------------------------
# Configuration
# ---------------------------------------------------------------------------
# Site origin only - no trailing slash and no "/v1/videos" (the paths below are
# appended by the code, e.g. f"{BASE_URL}/v1/videos").
BASE_URL = "https://api.tokspan.com"
API_KEY = "YOUR_API_KEY"               # user token from Console -> Tokens
MODEL = "volcengine/doubao-seedance-2-5-v2"

PROMPT = "A ginger cat walking through a sunlit garden, cinematic, shallow depth of field"
SECONDS = 5             # 1-3600; upstream default is about 10s
RESOLUTION = "1080p"    # 480p / 720p / 1080p / 4k; upstream default is 720p
IMAGE_URL = None        # reference image URL for image-to-video; None = text-to-video

POLL_INTERVAL = 10      # seconds between status checks
POLL_TIMEOUT = 15 * 60  # give up after this many seconds

# A trailing slash would produce "https://host//v1/videos", which the gateway
# answers with its HTML front page (HTTP 200), so normalize it away.
BASE_URL = BASE_URL.rstrip("/")

# Available models, with list price per 1M tokens (billed on actual usage):
#   volcengine/doubao-seedance-2-5-v2            $10.19   best quality
#   volcengine/doubao-seedance-2-0-260128         $6.00
#   volcengine/doubao-seedance-2-0-fast-260128    $4.35   fastest, cheapest


def _headers() -> Dict[str, str]:
    """Auth header. `requests` sets Content-Type automatically for json= bodies."""
    return {"Authorization": f"Bearer {API_KEY}"}


def _check(resp: requests.Response, action: str) -> None:
    """Raise a readable error for any non-2xx response.

    Error codes you may hit:
        pre_consume_token_quota_failed  token balance below the pre-charge
        model_not_found                 no channel serves this model
        get_channel_failed              channel selection failed
        fail_to_fetch_task              upstream error (details inside `message`)
    """
    if resp.ok:
        return
    try:
        body = resp.json()
    except ValueError:
        body = {"message": resp.text[:200]}
    err = body.get("error", body) if isinstance(body, dict) else {"message": str(body)}
    raise RuntimeError(
        f"{action} failed: HTTP {resp.status_code} "
        f"[{err.get('code', '')}] {err.get('message', '')}"
    )


def create_video(
    prompt: str,
    model: str = MODEL,
    seconds: Optional[int] = None,
    resolution: Optional[str] = None,
    image_url: Optional[str] = None,
) -> str:
    """Submit a generation task and return its task id."""
    payload: Dict[str, Any] = {"model": model, "prompt": prompt}
    if seconds is not None:
        payload["seconds"] = seconds
    if resolution is not None:
        payload["resolution"] = resolution
    if image_url:
        payload["input_reference"] = image_url   # "image" is an accepted alias

    resp = requests.post(f"{BASE_URL}/v1/videos", headers=_headers(), json=payload, timeout=60)
    _check(resp, "Submit")

    task_id = resp.json()["id"]
    print(f"Submitted task: {task_id}")
    return task_id


def wait_for_video(task_id: str) -> Dict[str, Any]:
    """Poll until the task finishes: queued -> in_progress -> completed / failed."""
    deadline = time.time() + POLL_TIMEOUT
    while time.time() < deadline:
        resp = requests.get(f"{BASE_URL}/v1/videos/{task_id}", headers=_headers(), timeout=60)
        _check(resp, "Poll")

        data = resp.json()
        status = str(data.get("status", "")).lower()
        print(f"  status={status} progress={data.get('progress', 0)}%")

        if status == "completed":
            return data
        if status in {"failed", "cancelled", "expired"}:
            reason = (data.get("error") or {}).get("message", "unknown reason")
            raise RuntimeError(f"Generation failed: {reason}")

        time.sleep(POLL_INTERVAL)

    raise TimeoutError(f"Timed out after {POLL_TIMEOUT}s, task {task_id} still running")


def download_video(task_id: str, save_path: str) -> str:
    """Download the finished video to `save_path`."""
    resp = requests.get(
        f"{BASE_URL}/v1/videos/{task_id}/content",
        headers=_headers(),
        stream=True,
        timeout=300,
    )
    _check(resp, "Download")

    with open(save_path, "wb") as fh:
        for chunk in resp.iter_content(chunk_size=1 << 16):
            fh.write(chunk)

    print(f"Saved video: {save_path}")
    return save_path


if __name__ == "__main__":
    tid = create_video(PROMPT, seconds=SECONDS, resolution=RESOLUTION, image_url=IMAGE_URL)
    wait_for_video(tid)
    download_video(tid, f"{tid}.mp4")

Thanh toán: hạn mức được trừ trước khi gửi (seconds × resolution) và đối soát theo mức sử dụng thực tế khi hoàn tất. 5 giây ở 720p ≈ $1.10, 1080p ≈ $2.48, 4k ≈ $9.90. Token có số dư thấp hơn khoản trừ trước sẽ bị từ chối trước khi tác vụ được tạo.

Responses API

python
from openai import OpenAI

client = OpenAI(
    api_key="sk-your-api-key",
    base_url="https://api.tokspan.com/v1",  # ← Same base URL as OpenAI-compatible
)

response = client.responses.create(
    model="MODEL_NAME",  # Replace MODEL_NAME with any model from the catalog
    input="Hello!",
)

print(response.output_text)
Một khóa, mọi định dạng. Mọi định dạng đều dùng chung một khóa TokSpan. Số dư và mức sử dụng được chia sẻ — chỉ cần gọi tên mô hình bạn muốn.

Sử dụng TokSpan API

Không cần SDK — gửi yêu cầu trực tiếp đến endpoint tương thích OpenAI bằng HTTP thuần:

Tất cả yêu cầu sử dụng cùng định dạng: POST https://api.tokspan.com/v1/chat/completions với khóa API của bạn trong header Authorization.

python
import requests

def chat(prompt: str, model: str = "MODEL_NAME"):  # Replace MODEL_NAME with any model from the catalog
    response = requests.post(
        "https://api.tokspan.com/v1/chat/completions",
        headers={
            "Authorization": "Bearer sk-your-api-key",
            "Content-Type": "application/json",
        },
        json={
            "model": model,
            "messages": [{"role": "user", "content": prompt}],
        },
    )
    return response.json()["choices"][0]["message"]["content"]

print(chat("Hello! What models are available?"))
typescript
const chat = async (prompt: string, model = 'MODEL_NAME') => {  // Replace MODEL_NAME with any model from the catalog
  const res = await fetch('https://api.tokspan.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sk-your-api-key',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      model,
      messages: [{ role: 'user', content: prompt }],
    }),
  });
  const data = await res.json();
  return data.choices[0].message.content;
};
shell
curl -X POST "https://api.tokspan.com/v1/chat/completions" \
  -H "Authorization: Bearer sk-your-api-key" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "MODEL_NAME",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

Chuyển Đổi Định Dạng Chéo

TokSpan tự động chuyển đổi giữa các định dạng API khác nhau ở phía sau. Bạn luôn gửi yêu cầu theo định dạng OpenAI Chat Completions — TokSpan xử lý việc chuyển đổi sang định dạng gốc của nhà cung cấp ngược dòng:

  • OpenAI → Claude Messages API — System prompt, hội thoại nhiều lượt và định nghĩa công cụ được ánh xạ lại tự động
  • OpenAI → Gemini API — Phần nội dung, cài đặt an toàn và cấu hình tạo được chuyển đổi minh bạch
  • Claude → định dạng OpenAI — Phản hồi gốc của Claude được chuẩn hóa về cấu trúc phản hồi Chat Completions tiêu chuẩn

Điều này có nghĩa là bạn có thể sử dụng OpenAI Python/Node SDK, LangChain hoặc bất kỳ thư viện tương thích OpenAI nào để gọi bất kỳ mô hình nào — bất kể định dạng API gốc của nó.

Phạm Vi & Quyền Của Khóa

Mỗi khóa API có thể được giới hạn phạm vi với các quyền cụ thể:

  • Mô Hình: Giới hạn những mô hình mà khóa có thể truy cập
  • Giới hạn chi tiêu: Đặt hạn mức cứng — khóa tự động bị vô hiệu hóa khi hết hạn mức
  • Giới hạn IP: Chỉ cho phép yêu cầu từ các dải IP cụ thể
Lưu ý bảo mật: Không bao giờ để lộ khóa API trong mã phía client. Sử dụng biến môi trường hoặc proxy backend an toàn. Tất cả yêu cầu đến TokSpan được mã hóa bằng TLS 1.3.

Tiếp Theo Là Gì?