Saltar al contenido
Volver a Nymbot

base de conocimientos desarrolladores

Chat, Respuestas y Mensajes

Tres maneras de preguntar a un modelo algo, en los tres formatos los clientes ya hablan, todos ejecutando en los mismos modelos y facturando de la misma manera.

Complementos de chat

El formato de chat OpenAI, y el que soporta casi todas las herramientas. Envíe la conversación hasta ahora y recibe el siguiente mensaje de vuelta.

POST https://nymbot.ai/api/v1/chat/completions Necesita una llave de fuego.

Sólo model y messages Un parámetro de muestreo que el modelo elegido no toma se cae sin un error, por lo que un cuerpo de solicitud funciona a través de los modelos. supported_parametersLo que se rechaza en lugar de caer es algo que el modelo no puede hacer en absoluto: imágenes para un modelo que no puede ver, herramientas para un modelo que no puede llamarlas.

CampoTipoRequiereDescripción
modelStringSínymbot/auto (o el auto) para el enrutamiento de Nymbot en el saldo estándar, o un identificador de modelo de catálogo como anthropic/claude-sonnet-5 en el balance Pro. Los nombres cortos y alias de la aplicación también se aceptan. Suficiente.
messagesArraySíLa conversación, los roles system, developer (Tratado como el sistema) user, assistant y toolEl contenido es una cadena o una lista de text y image_url partes; imágenes sólo en los mensajes de usuario. input_audio Las partes del archivo se rechazan.
streamBooleanNoEnvíe la respuesta tal y como está escrita. El streaming.
stream_optionsObjetoNo{"include_usage": true} añade una parte final con las cuentas de token y el coste.
max_tokens
max_completion_tokens
EntierroNoLa mayoría de los tokens para escribir. Bajo el máximo del modelo si es mayor. También establece cuánto se mantiene de su saldo, por lo que un número más pequeño necesita menos crédito para comenzar.
temperature
top_p
númeroNoControles de muestreo: temperature De 0 a 2, top_p De 0 a 1.
stopArray o arrayNoTexto que termina la respuesta: una cadena o un máximo de 4 cadenas, cada una de 256 caracteres. nymbot/auto.
seedEntierroNoPara el muestreo repetible, donde el modelo lo apoya.
presence_penalty
frequency_penalty
númeroNoControles de repetición, cada uno de -2 a 2.
response_formatObjetoNo{"type": "json_object"} o {"type": "json_schema", "json_schema": {…}}donde el modelo lo apoya. no se utiliza por nymbot/auto.
tools
tool_choice
parallel_tool_calls
array, string o objeto, booleanoNoFunción llamando. ver Herramientas de llamadas. a web_search La herramienta se vuelve búsqueda webA un máximo de 128 herramientas y 512 KB de definiciones, enmarcadas en un máximo de 64 niveles de profundidad; más es una 400.
reasoning_effort
reasoning
Cuerpo, ObjetoNo"minimal", "low", "medium" o "high", o {"effort": "high"}. "none" o {"enabled": false} Descarga el enlace. ver Razonamiento.
pluginsArrayNo[{"id": "web", "max_results": 5}] Busca siempre primero en la web. Hasta 10 resultados.
nEntierroNo1.- Todo lo demás vuelve 400.
logit_bias
user
metadata
Objeto, String y ObjetoNoaceptado y no enviado. logit_bias mapas con un máximo de 300 identificadores de token a números de -100 a 100; user Tiene un máximo de 256 caracteres. metadata Tiene un máximo de 16 valores de cadena, claves de hasta 64 caracteres y valores de hasta 512.

La respuesta es ordinaria chat.completionCon el coste en usage.cost (en dólares) y en el nymbot El objeto. model es el modelo resuelto id, por lo que un nombre corto vuelve como el completo. Si el modelo razonó antes de responder, su razonamiento está en message.reasoning_contentseparados de la respuesta.

Respuesta

{
  "id": "chatcmpl-5f1c0a9e27d84b3c",
  "object": "chat.completion",
  "created": 1790726400,
  "model": "anthropic/claude-sonnet-5",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "A Lightning invoice is a one-time payment request..."
      },
      "logprobs": null,
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 1240,
    "completion_tokens": 380,
    "total_tokens": 1620,
    "prompt_tokens_details": { "cached_tokens": 0 },
    "completion_tokens_details": { "reasoning_tokens": 0 },
    "cost": 0.01895
  },
  "nymbot": {
    "balance": "pro",
    "charged_credits": 0.162,
    "charged_sats": 16.2,
    "balance_credits": 412.425,
    "balance_sats": 41242.5
  }
}

finish_reason es elaborado a partir de lo que regresó, ya que los proveedores lo reportan de manera diferente: tool_calls Cuando el modelo pidió herramientas, length cuando la respuesta usó todos los tokens permitidos (o el modelo los gastó todos en razonamiento y no escribió ninguna respuesta), content_filter cuando el proveedor se niega, y stop De lo contrario. usage.completion_tokens_details.reasoning_tokens siempre es 0: los tokens de razonamiento ocultos se cuentan, y se cargan, en completion_tokens.

EstatusCuando
400No model o messages (missing_required_parameter); una parte de audio o archivo, o imágenes para un modelo que no las puede ver (unsupported_content); más de 20 imágenes (too_many_images); un parámetro de muestreo del tipo equivocado o fuera de rango (invalid_value); un enlace de imagen que no es público (invalid_image_url); herramientas en un modelo que no pueden llamarlos (unsupported_tool); n Más que 1; a :thinking Sufixo sobre un modelo que no puede razonar (model_not_found); o el proveedor rechazó la solicitud (upstream_rejected).
402El saldo que el modelo gasta no puede cubrir la posesión.
403El peor de los casos no se ajusta al capó de la clave (key_limit_reached) más bajo max_tokens O levantar el cap.
404No hay modelo con ese nombre (model_not_found).
429El límite de tasa de la clave, o el límite del proveedor (upstream_rate_limited).
502, 503El proveedor falló (upstream_error) o está sobrecargado (upstream_overloaded, con Retry-AfterNada se cobra a menos que el proveedor haya facturado por el intento.

Los códigos de estado de cada acción de punto final están listados en Errores.

cURL

curl https://nymbot.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "messages": [
      {"role": "system", "content": "Answer in one short paragraph."},
      {"role": "user", "content": "What is a Lightning invoice?"}
    ],
    "max_tokens": 400
  }'

Python

import os
from openai import OpenAI

client = OpenAI(base_url="https://nymbot.ai/api/v1", api_key=os.environ["NYMBOT_API_KEY"])

reply = client.chat.completions.create(
    model="anthropic/claude-sonnet-5",
    messages=[
        {"role": "system", "content": "Answer in one short paragraph."},
        {"role": "user", "content": "What is a Lightning invoice?"},
    ],
    max_tokens=400,
)
print(reply.choices[0].message.content)
print(reply.usage.cost)

JavaScript

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://nymbot.ai/api/v1", apiKey: process.env.NYMBOT_API_KEY });

const reply = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5",
  messages: [
    { role: "system", content: "Answer in one short paragraph." },
    { role: "user", content: "What is a Lightning invoice?" },
  ],
  max_tokens: 400,
});
console.log(reply.choices[0].message.content);
console.log(reply.usage.cost);

El Streaming

con "stream": true La respuesta llega como un evento enviado por el servidor mientras el modelo lo escribe. chat.completion.chunk es a data: línea, y el flujo termina con data: [DONE]El razonamiento entra en delta.reasoning_contentLa respuesta en delta.content.

Stream cualquier cosa que pueda tardar más de 100 segundos, como una respuesta larga, una gran max_tokens Una solicitud que no se transmite no envía nada hasta que la respuesta sea completa, y la red entre usted y Nymbot puede cerrar una conexión ininterrumpida después de aproximadamente 100 segundos; el modelo todavía termina y lo que escribió se carga, pero la respuesta se pierde.

El flujo

data: {"id":"chatcmpl-5f1c0a9e27d84b3c","object":"chat.completion.chunk","created":1790726400,"model":"anthropic/claude-sonnet-5","choices":[{"index":0,"delta":{"role":"assistant","content":""},"finish_reason":null}]}

data: {"id":"chatcmpl-5f1c0a9e27d84b3c","object":"chat.completion.chunk","created":1790726400,"model":"anthropic/claude-sonnet-5","choices":[{"index":0,"delta":{"content":"A Lightning invoice"},"finish_reason":null}]}

: keep-alive

data: {"id":"chatcmpl-5f1c0a9e27d84b3c","object":"chat.completion.chunk","created":1790726400,"model":"anthropic/claude-sonnet-5","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}

data: {"id":"chatcmpl-5f1c0a9e27d84b3c","object":"chat.completion.chunk","created":1790726400,"model":"anthropic/claude-sonnet-5","choices":[],"usage":{"prompt_tokens":1240,"completion_tokens":380,"total_tokens":1620,"cost":0.01895},"nymbot":{"balance":"pro","charged_credits":0.162,"charged_sats":16.2,"balance_credits":412.425,"balance_sats":41242.5}}

data: [DONE]
  • Líneas que comienzan con : Los comentarios se envían cada 15 segundos mientras el modelo está pensando. los clientes de SSE los saltan.
  • Preguntar por "stream_options": {"include_usage": true} para obtener el último trozo arriba, con un vacío choices, el token cuenta, el coste y el nymbot El objeto.
  • Si cierras la conexión temprano, el modelo no se detiene: Nymbot lee el resto del flujo del proveedor, durante hasta 25 segundos, para obtener su cuenta de token, y pagas lo que el proveedor informa.
  • Un error antes del primer chunk, como 401 o 402, vuelve como JSON ordinario con su código de estado, no como un flujo. data: {"error": {…}} acontecimiento, y el flujo termina sin [DONE].
  • Las solicitudes con herramientas y modelos en el transporte de Respuestas de OpenAI no fluyen desde el proveedor.Todavía responden con un flujo válido, enviado una vez que la respuesta está completa.

cURL

curl -N https://nymbot.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nymbot/auto",
    "stream": true,
    "stream_options": {"include_usage": true},
    "messages": [{"role": "user", "content": "Write a haiku about sats."}]
  }'

Python

import os
from openai import OpenAI

client = OpenAI(base_url="https://nymbot.ai/api/v1", api_key=os.environ["NYMBOT_API_KEY"])

stream = client.chat.completions.create(
    model="nymbot/auto",
    stream=True,
    stream_options={"include_usage": True},
    messages=[{"role": "user", "content": "Write a haiku about sats."}],
)
for chunk in stream:
    if chunk.choices:
        print(chunk.choices[0].delta.content or "", end="", flush=True)
    elif chunk.usage:
        print("\ncost:", chunk.usage.cost)

JavaScript

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://nymbot.ai/api/v1", apiKey: process.env.NYMBOT_API_KEY });

const stream = await client.chat.completions.create({
  model: "nymbot/auto",
  stream: true,
  stream_options: { include_usage: true },
  messages: [{ role: "user", content: "Write a haiku about sats." }],
});
for await (const chunk of stream) {
  if (chunk.choices.length) process.stdout.write(chunk.choices[0].delta.content || "");
  else if (chunk.usage) console.log("\ncost:", chunk.usage.cost);
}

Herramientas de llamadas

Describe las funciones en tools y el modelo puede pedir que uno sea llamado en lugar de responder. Executa la función, agrega su resultado como un tool Un mensaje con el mismo tool_call_idNymbot nunca ejecuta sus funciones; transmite la solicitud del modelo de vuelta a usted.

tool_choice Toma "auto", "none", "required" o {"type": "function", "function": {"name": "…"}}La lista de modelos marca qué modelos pueden llamar herramientas (capabilities.toolsLas herramientas se rechazan con 400 unsupported_tool es nymbot/auto y en los pocos modelos de catálogo que se ejecutan en el transporte de Responses de OpenAI, a los que Nymbot no puede pasar herramientas.

con "stream": true, una solicitud con herramientas se ejecuta en una pieza y luego se envía como una secuencia de piezas normales: el rol, una pieza que lleva cada llamada de herramienta con su índice, id, nombre y argumentos, y la pieza final.

La respuesta, en parte

"choices": [
  {
    "index": 0,
    "message": {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_7d2e",
          "type": "function",
          "function": { "name": "get_invoice_status", "arguments": "{\"invoice_id\":\"a41f\"}" }
        }
      ]
    },
    "finish_reason": "tool_calls"
  }
]

cURL

curl https://nymbot.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "messages": [{"role": "user", "content": "Has invoice a41f been paid?"}],
    "tools": [{
      "type": "function",
      "function": {
        "name": "get_invoice_status",
        "description": "Look up whether an invoice is paid.",
        "parameters": {
          "type": "object",
          "properties": {"invoice_id": {"type": "string"}},
          "required": ["invoice_id"]
        }
      }
    }]
  }'

Python

import json, os
from openai import OpenAI

client = OpenAI(base_url="https://nymbot.ai/api/v1", api_key=os.environ["NYMBOT_API_KEY"])

tools = [{
    "type": "function",
    "function": {
        "name": "get_invoice_status",
        "description": "Look up whether an invoice is paid.",
        "parameters": {
            "type": "object",
            "properties": {"invoice_id": {"type": "string"}},
            "required": ["invoice_id"],
        },
    },
}]
messages = [{"role": "user", "content": "Has invoice a41f been paid?"}]

reply = client.chat.completions.create(model="anthropic/claude-sonnet-5", messages=messages, tools=tools)
call = reply.choices[0].message.tool_calls[0]
args = json.loads(call.function.arguments)

messages.append(reply.choices[0].message)
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps({"paid": True})})

final = client.chat.completions.create(model="anthropic/claude-sonnet-5", messages=messages, tools=tools)
print(final.choices[0].message.content)

JavaScript

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://nymbot.ai/api/v1", apiKey: process.env.NYMBOT_API_KEY });

const tools = [{
  type: "function",
  function: {
    name: "get_invoice_status",
    description: "Look up whether an invoice is paid.",
    parameters: {
      type: "object",
      properties: { invoice_id: { type: "string" } },
      required: ["invoice_id"],
    },
  },
}];
const messages = [{ role: "user", content: "Has invoice a41f been paid?" }];

const reply = await client.chat.completions.create({ model: "anthropic/claude-sonnet-5", messages, tools });
const call = reply.choices[0].message.tool_calls[0];
const args = JSON.parse(call.function.arguments);

messages.push(reply.choices[0].message);
messages.push({ role: "tool", tool_call_id: call.id, content: JSON.stringify({ paid: true }) });

const final = await client.chat.completions.create({ model: "anthropic/claude-sonnet-5", messages, tools });
console.log(final.choices[0].message.content);

Imágenes en una solicitud

Modelos con capabilities.vision Puedes leer las imágenes.Añadir image_url parte a un mensaje de usuario, con un público https:// Enlace o a data:image/…;base64, URL. Hasta 20 imágenes por solicitud. las imágenes SVG son rechazadas, y así es un enlace de más de 4.096 caracteres o uno con un nombre de usuario o contraseña en él (400 invalid_image_urlUna opción detail es auto, low o high.

con nymbot/auto, una solicitud con una imagen en ella se dirige a un modelo estándar que puede ver. capabilities.vision rechaza las fotos con 400 unsupported_contentUn enlace debe apuntar a un anfitrión público; Nymbot transmite la imagen al proveedor del modelo y no la guarda.

Una imagen se carga como los tokens de entrada que el proveedor cuenta para ella, como el resto de la solicitud.

cURL

curl https://nymbot.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "messages": [{
      "role": "user",
      "content": [
        {"type": "text", "text": "What is in this picture?"},
        {"type": "image_url", "image_url": {"url": "https://example.com/receipt.jpg"}}
      ]
    }]
  }'

Python

import base64, os
from openai import OpenAI

client = OpenAI(base_url="https://nymbot.ai/api/v1", api_key=os.environ["NYMBOT_API_KEY"])

with open("receipt.jpg", "rb") as f:
    data_url = "data:image/jpeg;base64," + base64.b64encode(f.read()).decode()

reply = client.chat.completions.create(
    model="anthropic/claude-sonnet-5",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "What is in this picture?"},
            {"type": "image_url", "image_url": {"url": data_url}},
        ],
    }],
)
print(reply.choices[0].message.content)

JavaScript

import { readFile } from "node:fs/promises";
import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://nymbot.ai/api/v1", apiKey: process.env.NYMBOT_API_KEY });

const dataUrl = "data:image/jpeg;base64," + (await readFile("receipt.jpg")).toString("base64");

const reply = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5",
  messages: [{
    role: "user",
    content: [
      { type: "text", text: "What is in this picture?" },
      { type: "image_url", image_url: { url: dataUrl } },
    ],
  }],
});
console.log(reply.choices[0].message.content);

razonamiento

Modelos con capabilities.reasoning puede pensar antes de responder. pida más o menos de ella con reasoning_effort ("minimal", "low", "medium" o "high") o "reasoning": {"effort": "high"}o añadir :thinking el nombre del modelo, lo que significa gran esfuerzo. En un modelo sin razonamiento, la configuración es ignorada. nymbot/auto, :thinking Envía la solicitud a la ruta de razonamiento estándar.

En los modelos antropológicos, el esfuerzo se convierte en un presupuesto de pensamiento de alrededor de 1.000, 2.000, 8.000 o 16.000 tokens, nunca más que max_tokens El pensamiento es dejado de lado cuando tool_choice fuerza una herramienta, y cuando la solicitud continúa un loop de herramientas (su último mensaje es un resultado de la herramienta), porque Anthropic necesita el pensamiento firmado anteriormente para retomarlo.

El razonamiento vuelve a message.reasoning_content, o delta.reasoning_content cuando se transmite, nunca se mezcla en la respuesta. el razonamiento es la salida y se carga como tal, dentro completion_tokensAlgunos proveedores no devuelven el texto de razonamiento en absoluto, y sigue siendo cargado.

cURL

curl https://nymbot.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "reasoning_effort": "high",
    "messages": [{"role": "user", "content": "Is 2^61 - 1 prime? Show why."}]
  }'

Python

import os
from openai import OpenAI

client = OpenAI(base_url="https://nymbot.ai/api/v1", api_key=os.environ["NYMBOT_API_KEY"])

reply = client.chat.completions.create(
    model="anthropic/claude-sonnet-5",
    reasoning_effort="high",
    messages=[{"role": "user", "content": "Is 2^61 - 1 prime? Show why."}],
)
message = reply.choices[0].message
print(getattr(message, "reasoning_content", None))
print(message.content)

JavaScript

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://nymbot.ai/api/v1", apiKey: process.env.NYMBOT_API_KEY });

const reply = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5",
  reasoning_effort: "high",
  messages: [{ role: "user", content: "Is 2^61 - 1 prime? Show why." }],
});
console.log(reply.choices[0].message.reasoning_content);
console.log(reply.choices[0].message.content);

Modelo de suffixes

Un sufixo en el nombre del modelo cambia la forma en que se trata la solicitud, sin otro campo. anthropic/claude-sonnet-5:online.

SuficienteEfecto
:onlineBusca en la web primero, como plugins: [{"id": "web"}]El SE búsqueda web.
:thinkingUn gran esfuerzo racional; en nymbot/autoEn un modelo que no puede razonar, 400 model_not_found con “no hay resultados encontrados”.
:nitro, :floor, :exacto, :extendedCada modelo de catálogo tiene una ruta, por lo que no hay una más rápida, más barata o más larga para elegir; se permiten los sufixos para que los nombres de modelos copiados de otros servicios sigan funcionando.

Cualquier otro sufixo es ignorado.El nombre entero se intenta primero, por lo que un modelo cuyo id realmente contiene un colon todavía funciona; en caso contrario, los sufixos se retiran del final uno a la vez hasta que un modelo coincida.Un nombre de modelo puede ser de un máximo de 200 caracteres con un máximo de 4 sufixos; un más largo se rechaza con 400 invalid_value.

cURL

curl https://nymbot.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5:thinking",
    "messages": [{"role": "user", "content": "Plan a three-day trip to Lisbon."}]
  }'

Python

import os
from openai import OpenAI

client = OpenAI(base_url="https://nymbot.ai/api/v1", api_key=os.environ["NYMBOT_API_KEY"])

reply = client.chat.completions.create(
    model="anthropic/claude-sonnet-5:thinking",
    messages=[{"role": "user", "content": "Plan a three-day trip to Lisbon."}],
)
print(reply.choices[0].message.content)

JavaScript

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://nymbot.ai/api/v1", apiKey: process.env.NYMBOT_API_KEY });

const reply = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5:thinking",
  messages: [{ role: "user", content: "Plan a three-day trip to Lisbon." }],
});
console.log(reply.choices[0].message.content);

Nymbot busca el último mensaje de usuario (sus primeros 2.000 caracteres), lee las mejores páginas y las da al modelo con la pregunta, marcada como contenido externo del que el modelo no debe tomar instrucciones.

  • Siempre en busca: "plugins": [{"id": "web", "max_results": 5}], o a :online Suficiente para el modelo.
  • Buscar cuando ayuda: "tools": [{"type": "web_search", "parameters": {"max_results": 5}}]También aceptado como web_search_preview o openrouter:web_searchNymbot sólo busca cuando la pregunta parece que necesita información actual, la misma prueba que utiliza la aplicación.

max_results es 5 por defecto y a un máximo de 10. las fuentes vuelven a nymbot.web_search.sourcesCada uno con una title, snippet y urlY como url_citation anotaciones en el mensaje.

Cada búsqueda que corre cuesta $0.008, convertido a sats, en la parte superior de los tokens, y es parte del hold. Las páginas que lee son tokens de entrada también, por lo que una respuesta de la web cuesta más que la misma pregunta preguntada fría, a veces varias veces más.

La respuesta, en parte

"nymbot": {
  "balance": "pro",
  "charged_credits": 0.431,
  "charged_sats": 43.1,
  "balance_credits": 411.994,
  "balance_sats": 41199.4,
  "web_search": {
    "sources": [
      { "title": "Lightning Network - Wikipedia", "snippet": "The Lightning Network is a payment protocol...", "url": "https://en.wikipedia.org/wiki/Lightning_Network" }
    ]
  }
}

cURL

curl https://nymbot.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "plugins": [{"id": "web", "max_results": 5}],
    "messages": [{"role": "user", "content": "What changed in the latest Bitcoin Core release?"}]
  }'

Python

import os
from openai import OpenAI

client = OpenAI(base_url="https://nymbot.ai/api/v1", api_key=os.environ["NYMBOT_API_KEY"])

reply = client.chat.completions.create(
    model="anthropic/claude-sonnet-5",
    messages=[{"role": "user", "content": "What changed in the latest Bitcoin Core release?"}],
    extra_body={"plugins": [{"id": "web", "max_results": 5}]},
)
print(reply.choices[0].message.content)
for source in reply.model_extra["nymbot"]["web_search"]["sources"]:
    print(source["url"])

JavaScript

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://nymbot.ai/api/v1", apiKey: process.env.NYMBOT_API_KEY });

const reply = await client.chat.completions.create({
  model: "anthropic/claude-sonnet-5",
  plugins: [{ id: "web", max_results: 5 }],
  messages: [{ role: "user", content: "What changed in the latest Bitcoin Core release?" }],
});
console.log(reply.choices[0].message.content);
for (const source of reply.nymbot.web_search.sources) console.log(source.url);

Respuestas API

El formato más reciente de OpenAI, utilizado por el OpenAI Agents SDK y por Codex. Se ejecuta en los mismos modelos, facturación y características que Chat Completions.

POST https://nymbot.ai/api/v1/responses Necesita una llave de fuego.

CampoTipoRequiereDescripción
modelStringSíComo para Complementos de chatSufixos incluidos.
inputArray o arraySíUna cadena, o una lista de elementos: mensajes (roles user, assistant, system, developer) con input_text, input_image y output_text partes, y function_call y function_call_output elementos para las herramientas. input_image Toma un image_url URL de enlace o de datos, no un identificador de archivo. reasoning y web_search_call Los objetos se saltan; item_reference es rechazado
instructionsStringNoInstrucciones del sistema.
max_output_tokensEntierroNoLos más grandes para escribir.
temperature
top_p
númeroNoControles de muestreo, donde el modelo los lleva.
tools
tool_choice
parallel_tool_calls
array, string o objeto, booleanoNoFunciones de las herramientas, en la forma de Respuestas ({"type": "function", "name": …, "parameters": …}) a web_search o web_search_preview La herramienta se vuelve búsqueda web cuando ayuda. Otras herramientas incorporadas se rechazan.
reasoningObjetoNo{"effort": "minimal" | "low" | "medium" | "high"}. xhigh y max Significa high; none que se apaga.
text.format
response_format
ObjetoNoEl resultado estructurado, como esquema JSON o json_object.
metadataObjetoNoDevuelve sin cambios en la respuesta. a un máximo de 16 valores de cadena, claves de hasta 64 caracteres y valores de hasta 512.
streamBooleanNoStream eventos como se describe a continuación.
storeBooleanNoNada se almacena, y la respuesta siempre dice "store": false.
previous_response_id
conversation
background
String, Objeto y BooleanNoNo se apoya: 400 unsupported_parameterLas respuestas no se almacenan, así que envíe toda la conversación en input cada vez

Respuesta

{
  "id": "resp_8c1e4b0f9a2d4e61",
  "object": "response",
  "created_at": 1790726400,
  "status": "completed",
  "model": "anthropic/claude-sonnet-5",
  "output": [
    {
      "type": "message",
      "id": "msg_2b7f",
      "role": "assistant",
      "status": "completed",
      "content": [{ "type": "output_text", "text": "A Lightning invoice is...", "annotations": [] }]
    }
  ],
  "output_text": "A Lightning invoice is...",
  "usage": {
    "input_tokens": 1240,
    "input_tokens_details": { "cached_tokens": 0 },
    "output_tokens": 380,
    "output_tokens_details": { "reasoning_tokens": 0 },
    "total_tokens": 1620
  },
  "incomplete_details": null,
  "error": null,
  "instructions": null,
  "store": false,
  "previous_response_id": null,
  "metadata": {},
  "nymbot": { "balance": "pro", "charged_credits": 0.162, "charged_sats": 16.2, "balance_credits": 412.425, "balance_sats": 41242.5 }
}

Una herramienta de solicitud aparece en output como a function_call Punto con call_id, name y argumentsdevolver el resultado como a function_call_output Punto con el mismo call_idrazonamiento, cuando el modelo lo devuelve, es un reasoning Punto con reasoning_text Contenido, listado primero status es incomplete Cuando la respuesta golpeó max_output_tokens El proveedor ha rechazado, con incomplete_details.reason Establecimiento max_output_tokens o content_filterLa respuesta también echa eco a las configuraciones de la solicitud (temperatura, herramientas, elección de herramientas y así sucesivamente) como lo hace OpenAI, y lleva el nymbot costos del objeto.

A la derecha, cada evento es un event: línea y a data: Líneas con a sequence_numberEn este orden: response.created, response.in_progress, response.output_item.added, response.content_part.addedCualquier número de response.output_text.delta, response.output_text.done, response.content_part.done, response.output_item.doneY por fin response.completed con el uso y el coste. una respuesta corta termina con response.incomplete en lugar de, y un fracaso después de que el flujo comenzó con response.failedracionando los flujos como su propio objeto con response.reasoning_text.delta y .doneLas llamadas de herramientas vienen después del mensaje, cada uno como un elemento con response.function_call_arguments.delta y .done.

EstatusCuando
400No model o input; previous_response_id, conversation, background o un item_reference (unsupported_parameter); una herramienta o tipo de contenido no soportado.
402, 403, 404, 429, 502, 503En cuanto a los chat completos.

cURL

curl https://nymbot.ai/api/v1/responses \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "anthropic/claude-sonnet-5",
    "instructions": "Answer in one short paragraph.",
    "input": "What is a Lightning invoice?"
  }'

Python

import os
from openai import OpenAI

client = OpenAI(base_url="https://nymbot.ai/api/v1", api_key=os.environ["NYMBOT_API_KEY"])

response = client.responses.create(
    model="anthropic/claude-sonnet-5",
    instructions="Answer in one short paragraph.",
    input="What is a Lightning invoice?",
)
print(response.output_text)

JavaScript

import OpenAI from "openai";

const client = new OpenAI({ baseURL: "https://nymbot.ai/api/v1", apiKey: process.env.NYMBOT_API_KEY });

const response = await client.responses.create({
  model: "anthropic/claude-sonnet-5",
  instructions: "Answer in one short paragraph.",
  input: "What is a Lightning invoice?",
});
console.log(response.output_text);

Mensajes antropológicos

El formato de Anthropic, para los SDK de Anthropic y Claude Code. Funciona con todos los modelos del catálogo, no sólo Claude: la solicitud se traduce, se ejecuta a través del mismo tubo, y se traduce de vuelta.

POST https://nymbot.ai/api/v1/messages - Necesita una clave de API, como x-api-key o Authorization: Bearer.

El anthropic-version y anthropic-beta Los nombres de modelos antropogénicos se ajustan al catálogo, por lo que Claude Code y los SDKs trabajan con los nombres que ya usan:

  • Un nombre que el catálogo conoce, como claude-sonnet-5 o anthropic/claude-opus-5Se utiliza como es.
  • En el caso de una fecha (-20260514), -latest, una versión tag como -v1Un bracketed tag como [1m] y un anthropic/ o anthropic. Los prefixos se eliminan, y los puntos y dashes en la versión se intentan de ambas maneras (claude-haiku-4-5 Encuentra claude-haiku-4.5).
  • Si eso aún no coincide, se utiliza la familia (Opus, Sonnet o Haiku), siempre que la versión del catálogo sea la misma o más nueva que la solicitada.
  • Un nombre que no coincide con nada vuelve 404 not_found_error.
CampoTipoRequiereDescripción
modelStringSíUn identificador de modelo de catálogo o un nombre de modelo antropoide.
max_tokensEntierroSíLos más grandes para escribir.
messagesArraySíuser y assistant Se vuelve, con text, image (base64 o la fuente de URL), tool_use y tool_result los bloques. thinking Los bloques de turnos anteriores son aceptados y descartados.
systemArray o arrayNoInstrucciones de sistema, como una cadena o bloques de texto.
temperature
top_p
númeroNoControles de muestreo, donde el modelo los lleva. top_k Se acepta y se abandona.
stop_sequencesArray de StringsNoTexto que termina la respuesta. a un máximo de 4 cuerdas, cada una de 256 caracteres.
tools
tool_choice
Array, ObjetoNoHerramientas con name, description y input_schema. a web_search La herramienta de servidor se vuelve búsqueda web; Otras herramientas integradas de Anthropic (bash, editor de texto, uso de ordenador) se rechazan con unsupported_tool. tool_choice Toma auto, any, tool o none, y disable_parallel_tool_use.
thinkingObjetoNo{"type": "enabled", "budget_tokens": 8192}, {"type": "adaptive"} o {"type": "disabled"}El presupuesto elige un nivel de esfuerzo: por debajo de 2.048 mínimo, de 2.048 bajo, de 8.192 medio, de 16.384 alto. output_config.efforto de alto.
streamBooleanNoStream en formato de evento de Anthropic.
metadataObjetoNoaceptado y ignorado.

Respuesta

{
  "id": "msg_01c7a2f93e5b4d08",
  "type": "message",
  "role": "assistant",
  "model": "anthropic/claude-sonnet-5",
  "content": [{ "type": "text", "text": "A Lightning invoice is..." }],
  "stop_reason": "end_turn",
  "stop_sequence": null,
  "usage": {
    "input_tokens": 1240,
    "output_tokens": 380,
    "cache_read_input_tokens": 0,
    "cache_creation_input_tokens": 0
  },
  "nymbot": { "balance": "pro", "charged_credits": 0.162, "charged_sats": 16.2, "balance_credits": 412.425, "balance_sats": 41242.5 }
}

content También se puede mantener tool_use Los bloques y a thinking El Bloque, cuyo signature es vacío. stop_reason es end_turn, max_tokens, tool_use o refusalTrabajó de la misma manera que finish_reason es Complementos de chat; stop_sequence Siempre es null, incluso cuando una secuencia de parada terminó la respuesta. input_tokens solo cuenta la entrada fresca; la entrada en caché se encuentra en los dos campos de caché. nymbot Objeto y el X-Nymbot-Cost-Sats El header.

Streamed, los eventos son de Anthropic: message_start, content_block_start, ping, content_block_delta (text_delta, input_json_delta o thinking_delta), content_block_stop, message_delta con la razón de parar, el uso y la nymbot Objeto de costo, y message_stop. a ping también se envía cada 15 segundos mientras el modelo está en funcionamiento. Las llamadas de herramientas llegan después del texto, cada una como una tool_use bloque con toda su entrada en una input_json_delta.

Los errores en este punto final usan el formato de Anthropic: {"type": "error", "error": {"type": "not_found_error", "message": "…"}}El equilibrio corto es 402 billing_errorUn proveedor sobrecargado 503 overloaded_errorUna falla después de que el flujo haya comenzado se envía como un error El Evento.

cURL

curl https://nymbot.ai/api/v1/messages \
  -H "x-api-key: $NYMBOT_API_KEY" \
  -H "anthropic-version: 2023-06-01" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "What is a Lightning invoice?"}]
  }'

Python

import os
import anthropic

client = anthropic.Anthropic(base_url="https://nymbot.ai/api", api_key=os.environ["NYMBOT_API_KEY"])

message = client.messages.create(
    model="claude-sonnet-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "What is a Lightning invoice?"}],
)
print(message.content[0].text)

JavaScript

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({ baseURL: "https://nymbot.ai/api", apiKey: process.env.NYMBOT_API_KEY });

const message = await client.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 1024,
  messages: [{ role: "user", content: "What is a Lightning invoice?" }],
});
console.log(message.content[0].text);

Cuenta los tokens

Una estimación de cuántos tokens de entrada usaría una solicitud de mensajes, para que un cliente pueda comprobar antes de enviar.

POST https://nymbot.ai/api/v1/messages/count_tokens - Necesita una clave de API.

El cuerpo es el mismo que el Mensajesy sin max_tokensEl conteo es una estimación: los caracteres del prompt del sistema, mensajes, llamadas de herramientas y definiciones de herramientas divididos por cuatro, más 1.600 para cada imagen. No es el propio tokenizer del proveedor, por lo que el conteo real puede diferir.

Respuesta

{ "input_tokens": 318 }

cURL

curl https://nymbot.ai/api/v1/messages/count_tokens \
  -H "x-api-key: $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-5",
    "messages": [{"role": "user", "content": "What is a Lightning invoice?"}]
  }'

Python

import os
import anthropic

client = anthropic.Anthropic(base_url="https://nymbot.ai/api", api_key=os.environ["NYMBOT_API_KEY"])

count = client.messages.count_tokens(
    model="claude-sonnet-5",
    messages=[{"role": "user", "content": "What is a Lightning invoice?"}],
)
print(count.input_tokens)

JavaScript

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({ baseURL: "https://nymbot.ai/api", apiKey: process.env.NYMBOT_API_KEY });

const count = await client.messages.countTokens({
  model: "claude-sonnet-5",
  messages: [{ role: "user", content: "What is a Lightning invoice?" }],
});
console.log(count.input_tokens);

Listado de modelos

Cada modelo y generador que la API acepta, con lo que cuesta.La lista se lee desde el mismo catálogo en vivo que el selector de la aplicación, por lo que siempre es lo que el servidor ejecutará.

GET https://nymbot.ai/api/v1/models - No se necesita llave. Ocultado durante cinco minutos.

GET /api/v1/models/{id} Devuelve una entrada.

CampoTipoRequiereDescripción
typeConexión (Query)Nochat (en el caso del defecto), image, video, audio, embedding o allSe pueden dar varias, como image,video.

Los precios son lo que usted paga, con la tarifa y la margen ya en, en dólares y en tarifas al precio actual de Bitcoin. balance Indica cuáles son los gastos del modelo. nymbot_key es el nombre corto del modelo en la aplicación. created siempre es 0, ya que el catálogo no registra cuando se agregó un modelo. per_request en cambio.

nymbot/auto Siempre en primer lugar, el precio variable, con una routes lista que da las tarifas de cada ruta estándar. Enumera la visión y el razonamiento, pero no las herramientas.

GET /api/v1/models/{id} acepta los mismos nombres y alias como una solicitud, y devuelve la entrada para el modelo al que se resuelven.

Respuesta

{
  "object": "list",
  "data": [
    {
      "id": "anthropic/claude-sonnet-5",
      "object": "model",
      "type": "chat",
      "owned_by": "anthropic",
      "name": "Claude Sonnet 5",
      "created": 0,
      "context_length": 1000000,
      "max_output_tokens": 64000,
      "architecture": { "input_modalities": ["text", "image"], "output_modalities": ["text"] },
      "supported_parameters": ["max_tokens", "temperature", "tools", "tool_choice", "reasoning", "response_format", "stop"],
      "capabilities": { "vision": true, "video": false, "tools": true, "reasoning": true, "web_search": true },
      "balance": "pro",
      "pricing": {
        "type": "per_token",
        "currency": "USD",
        "input_per_1M_tokens": 4.725,
        "output_per_1M_tokens": 23.625,
        "cache_read_per_1M_tokens": 0.4725,
        "sats_input_per_1M_tokens": 4038,
        "sats_output_per_1M_tokens": 20192
      },
      "description": "...",
      "nymbot_key": "claude-sonnet"
    }
  ]
}

Los otros tipos:

  • Imagen Las entradas tienen capabilities (accepts_image_url, requires_image_url, edit) y un precio per_generation.
  • Vídeo Las entradas tienen max_duration_seconds y resolutionsY un precio per_second por cada resolución.
  • Audios Las entradas tienen audio_type speech o transcriptionEl precio per_1k_chars o per_minute.
  • Embajador Las entradas tienen dimensions, context_length, max_inputs Un precio por millón de entradas.

Precios marcados "estimated": true es la estimación de la aplicación para un generador cuyo precio no se publica. type Regreso 400.

cURL

curl "https://nymbot.ai/api/v1/models?type=chat"

Python

import requests

models = requests.get("https://nymbot.ai/api/v1/models", params={"type": "chat"}).json()["data"]
for m in models:
    print(m["id"], m["balance"], m["pricing"].get("input_per_1M_tokens"))

JavaScript

const res = await fetch("https://nymbot.ai/api/v1/models?type=chat");
const { data } = await res.json();
for (const m of data) console.log(m.id, m.balance, m.pricing.input_per_1M_tokens);