Visión General

Inicio Rápido

TokSpan es compatible con OpenAI — cambia la URL base para acceder a más de 200 modelos al instante. También se admiten Claude Code / Anthropic nativo y la API Responses de OpenAI, y la generación de video con Doubao Seedance funciona con la misma clave; consulta más abajo.

1

Regístrate e inicia sesión

Regístrate con tu correo en nuestra página de registro.

2

Crea una clave API

Genera tu clave sk- en la página de API Keys del Panel.

3

Cambia tu URL base

Apunta la URL base de tu SDK a una de las URLs de abajo y llama con tu clave.

4

Actualizar/Agregar ID de modelo

Ve a Model Plaza para obtener el ID del modelo y luego actualízalo.

URLs base de la API

TokSpan habla varios protocolos de API. Elige el que tu SDK ya usa — todos los formatos aceptan la misma clave API y acceden a más de 200 modelos.

Compatible con OpenAI
https://api.tokspan.com/v1

El SDK de OpenAI ya incluye /v1 y agrega /chat/completions automáticamente.

Nativo de Anthropic
https://api.tokspan.com

Usa la raíz del host — Claude Code y el SDK de Anthropic agregan /v1/messages por sí mismos.

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

POST /v1/videos crea una tarea y devuelve su id; consulta el estado hasta que el video esté listo y luego descarga el contenido.

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

Reutiliza la URL base compatible con OpenAI y llama a /v1/responses.

Compatible con 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)

Nativo de Anthropic

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")

Facturación: la cuota se cobra por adelantado al enviar (seconds × resolution) y se concilia con el uso real al completarse. 5s en 720p ≈ $1.10, 1080p ≈ $2.48, 4k ≈ $9.90. Un token con saldo inferior al cargo previo se rechaza antes de crear la tarea.

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)
Una clave, todos los formatos. Todos los formatos usan la misma clave API de TokSpan. Tu saldo y uso son compartidos — solo llama al modelo que quieras.

Uso de la API de TokSpan

Sin SDK — envía solicitudes directamente al endpoint compatible con OpenAI con HTTP puro:

Todas las solicitudes usan el mismo formato: POST https://api.tokspan.com/v1/chat/completions con tu clave API en el encabezado 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!"}]
  }'

Conversión entre formatos

TokSpan convierte automáticamente entre diferentes formatos de API de forma transparente. Tú siempre envía solicitudes en el formato OpenAI Chat Completions: TokSpan se encarga de la traducción al formato nativo del proveedor upstream:

  • OpenAI → Claude Messages API: los prompts de sistema, la conversación de múltiples turnos y las definiciones de herramientas se reasignan automáticamente
  • OpenAI → Gemini API: las partes de contenido, la configuración de seguridad y los parámetros de generación se traducen de forma transparente
  • Claude → formato OpenAI: las respuestas nativas de Claude se normalizan a la estructura estándar de respuesta de Chat Completions

Esto significa que puedes usar el SDK de OpenAI para Python/Node, LangChain o cualquier biblioteca compatible con OpenAI para llamar a cualquier modelo, independientemente de tu formato de API nativo.

Alcance y permisos de claves

Cada clave API puede tener un alcance limitado a permisos específicos:

  • Modelos: Restringe a qué modelos puede acceder la clave
  • Límite de gasto: Establece un límite de cuota fijo; la clave se desactiva automáticamente cuando se agota su cuota
  • Lista blanca de IP: Solo permite solicitudes desde rangos de IP específicos
Nota de seguridad: Nunca expongas tu clave API en código del lado del cliente. Usa variables de entorno o un proxy de backend seguro. Todas las solicitudes a TokSpan se cifran con TLS 1.3.

¿Qué sigue?