Migración

Una URL base y una clave trasladan un cliente de OpenAI. Esta página también indica lo que la API no hace, porque una migración que descubre eso en producción no es una migración.

La forma de sustitución directa

Apunta la URL base del cliente a https://api.llmeu.com/v1 y dale una clave de API de la consola. La forma de la solicitud no cambia.

from openai import OpenAI

client = OpenAI(base_url="https://api.llmeu.com/v1", api_key="llmeu_live_xxxxxxxx.your-secret")

resp = client.chat.completions.create(
    model="llmeu-auto",
    messages=[{"role": "user", "content": "Say hello from EU hosting."}],
)
print(resp.choices[0].message.content)

Lo que acepta el endpoint de chat

El validador de solicitudes en apps/api/src/app.mjs comprueba lo siguiente; lo que no comprueba se deja pasar o se ignora en lugar de rechazarse, de modo que un cliente más reciente sigue funcionando.

  • model y messages son obligatorios; messages debe ser un array no vacío.
  • Cada mensaje necesita un rol (system, user, assistant, tool o developer) y content como una cadena o un array de partes.
  • stream debe ser un booleano cuando esté presente.
  • temperature, top_p, max_tokens, presence_penalty, frequency_penalty, seed y n deben ser números cuando estén presentes.
  • max_tokens debe ser al menos 1.
  • n debe ser exactamente 1; cualquier otro valor se rechaza.
  • stop puede ser una cadena o un array de cadenas.
  • tools debe ser un array cuando esté presente.
  • llmeu debe ser un objeto; nunca es obligatorio.
  • tool_choice y response_format se reenvían al backend junto con los campos anteriores; un campo extra desconocido no se rechaza.

Extras de solicitud en llmeu

Un objeto llmeu con espacio de nombres en el cuerpo de la solicitud; un cliente que ignora campos desconocidos puede enviarlo sin problema.

Campo Valor Efecto
residencyeu-hosted | eu-owned | de | anyRestringe el enrutamiento a los endpoints de esa residencia; un conjunto elegible vacío devuelve 409 no_endpoint_for_policy en lugar de ampliar el filtro.
taskun nombre de tareaLa tarea a la que el enrutador ajusta el modelo.
retentionzeroSolo está implementado el cero. Pedir más de lo que permite la política devuelve 403 retention_exceeds_policy; un valor efectivo permitido distinto de cero devuelve 501 retention_not_implemented.
data_classpublic | internal | confidential | restrictedSe comprueba contra las clases de datos permitidas por la política: una clase fuera de ellas devuelve 403 data_class_not_allowed, y una clase desconocida devuelve 400 invalid_data_class.
policy_iduuidNombra una política de la misma organización; un id desconocido devuelve 404 policy_not_found.
max_usd_per_1mun númeroUn límite de precio por millón de tokens para esta solicitud.
allow_partnerstrue | falseSi se pueden usar endpoints de socios para esta solicitud.

Las claves desconocidas dentro de llmeu se ignoran; una clave conocida con un valor no válido se rechaza, porque un data_class incorrecto debe fallar de forma cerrada en lugar de significar silenciosamente ninguna clase de datos.

curl https://api.llmeu.com/v1/chat/completions \
  -H "Authorization: Bearer $LLMEU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "llmeu-auto",
    "messages": [{"role": "user", "content": "Summarise this contract."}],
    "llmeu": {"residency": "eu-owned", "data_class": "confidential", "retention": "zero"}
  }'

Lo que no existe

Estas respuestas son deliberadas, y un cliente que las espera ve el código de error en lugar de una sustitución silenciosa.

Solicitud Resultado
POST /v1/completions501 not_implemented — el endpoint heredado de completions no se ofrece; use /v1/chat/completions.
n > 1400 unsupported_n — solo se admite n = 1.
POST /v1/embeddingsLos embeddings necesitan un modelo de embeddings, y el id solicitado por defecto es bge-m3. No se sirve ninguno en este despliegue, así que la ruta no se ofrece aquí en lugar de devolver vectores de relleno.
/v1/files, /v1/batches, /v1/assistants, /v1/fine_tuning, /v1/audio, /v1/images404 unknown_route — no se enruta en absoluto; una ruta /v1 que el enrutador no conoce responde 404 unknown_route, y cualquier otra ruta responde 404 not_found.

Extraer tus datos

La exportación de cuenta me.json contiene campos de cuenta seleccionados, organizaciones, metadatos de claves de API sin secretos, políticas actuales, las últimas 200 trazas por organización y agregados de uso diario de 365 días. No es una copia completa de todos los datos personales ni un registro histórico de políticas.

La exportación de auditoría en NDJSON usa 7 días por defecto, permite como máximo 90 días y limita las trazas a 5000; su manifiesto incluye counts.truncated, que marca una exportación que alcanzó el límite.

GET /app/exports/me.json
GET /app/exports/audit.ndjson?days=7
GET /app/exports/traces.json
GET /app/exports/usage.json
GET /app/exports/policies.json

La eliminación de la cuenta en sí se realiza en la página de perfil y está sujeta a la regla de propiedad de la página de la consola.

Una cookie de sesión no es una credencial de API

Una sesión de navegador autentica la consola, no la API. Un cliente de OpenAI que envíe una recibe un rechazo con 403 api_key_required y tiene que usar una clave de API en su lugar.

Un rechazo aquí nombra un código, de modo que una migración puede ramificar según él, y el bloque llmeu de cada respuesta indica qué ocurrió realmente.