Base de connaissances Développeurs
Chat, messages et réponses
Trois façons de demander quelque chose à un modèle, dans les trois formats que les clients parlent déjà, tous fonctionnant sur les mêmes modèles et facturés de la même manière.
Cette page est traduite automatiquement pour plus de commodité. La version originale anglaise est la version qui s’applique.
Chat complémentaire
Le format de chat OpenAI, et celui que presque tous les outils prennent en charge. Envoyer la conversation jusqu'ici et recevoir le prochain message.
POST https://nymbot.ai/api/v1/chat/completions Vous avez besoin d’une clé API.
uniquement model et messages Un paramètre d'échantillonnage que le modèle choisi ne prend pas est laissé tomber sans erreur, de sorte qu'un corps de demande fonctionne à travers les modèles. supported_parametersCe qui est refusé plutôt que abandonné est tout ce que le modèle ne peut pas faire du tout: des images pour un modèle qui ne peut pas voir, des outils pour un modèle qui ne peut pas les appeler.
| champs | Type | Nécessaire | Description |
|---|---|---|---|
model | String à | Oui | nymbot/auto (ou de auto) pour le routage de Nymbot sur le solde standard, ou un modèle de catalogue id tel que anthropic/claude-sonnet-5 sur le bilan Pro. Les noms courts et alias de l'application sont également acceptés. suffisante. |
messages | Array | Oui | La conversation, les rôles system, developer (traité comme un système), user, assistant et toolLe contenu est une chaîne ou une liste de text et image_url parties ; images uniquement dans les messages de l'utilisateur. input_audio Les fichiers sont refusés. |
stream | Bouléen | Non pas | Envoyez la réponse comme elle est écrite. voir Le streaming. |
stream_options | Objet | Non pas | {"include_usage": true} ajoute un dernier morceau avec les comptes de jetons et le coût. |
max_tokensmax_completion_tokens | Intégrale | Non pas | La plupart des jetons à écrire. abaissé au maximum du modèle si plus élevé. Détermine également combien est détenu de votre solde, de sorte qu'un nombre plus petit a besoin de moins de crédit pour commencer. |
temperaturetop_p | Numéro | Non pas | Contrôle des échantillons : temperature De 0 à 2, top_p De 0 à 1. |
stop | String ou array | Non pas | Texte qui termine la réponse: une chaîne ou au maximum 4 chaînes, chacune au maximum 256 caractères. nymbot/auto. |
seed | Intégrale | Non pas | Pour l’échantillonnage répétitif, où le modèle le soutient. |
presence_penaltyfrequency_penalty | Numéro | Non pas | Contrôles de répétition, chacun de -2 à 2. |
response_format | Objet | Non pas | {"type": "json_object"} ou {"type": "json_schema", "json_schema": {…}}, où le modèle le prend en charge. Non utilisé par nymbot/auto. |
toolstool_choiceparallel_tool_calls | array, chaîne ou objet, boolean | Non pas | Fonction d’appel. voir Les outils d’appel• A web_search L’outil devient Recherche webAu maximum 128 outils et 512 KB de définitions, niché au maximum 64 niveaux de profondeur; plus est un 400. |
reasoning_effortreasoning | String, objet | Non pas | "minimal", "low", "medium" ou "high"ou {"effort": "high"}. "none" ou {"enabled": false} Il s’éteint. voir Le raisonnement. |
plugins | Array | Non pas | [{"id": "web", "max_results": 5}] cherche toujours le web en premier. Jusqu'à 10 résultats. |
n | Intégrale | Non pas | 1 - Tout le reste revient 400. |
logit_biasusermetadata | Objet, String et Objet | Non pas | accepté et non envoyé. logit_bias cartes à un maximum de 300 identifiants de jetons à des nombres de -100 à 100; user Un maximum de 256 caractères metadata possède un maximum de 16 valeurs de chaîne, des clés jusqu'à 64 caractères et des valeurs jusqu'à 512. |
La réponse est ordinaire chat.completionAvec le coût de usage.cost
(en dollars) et dans les nymbot l’objet . model est le modèle id résolu, donc un nom court revient comme le nom complet. Si le modèle a raisonné avant de répondre, son raisonnement est dans message.reasoning_contentséparée de la réponse.
Réponse
{
"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 est élaboré à partir de ce qui est revenu, car les fournisseurs le rapportent différemment: tool_calls Lorsque le modèle a demandé des outils, length lorsque la réponse a utilisé tous les jetons autorisés (ou que le modèle les a tous raisonnés et n'a pas écrit de réponse), content_filter lorsque le fournisseur a refusé, et stop
autrement . usage.completion_tokens_details.reasoning_tokens est toujours 0 : les jetons de raisonnement cachés sont comptés, et facturés, dans completion_tokens.
| Statut | Quand |
|---|---|
400 | Non pas model ou messages (missing_required_parameter) ; une partie audio ou un fichier, ou des images pour un modèle qui ne peut pas les voir (unsupported_content(plus de 20 photos)too_many_images) ; un paramètre d'échantillonnage du type incorrect ou hors gamme (invalid_value) ; un lien photo qui n'est pas public (invalid_image_url) ; outils sur un modèle qui ne peut pas les appeler (unsupported_tool); n autre que 1 ; a :thinking suffix sur un modèle qui ne peut pas raisonner (model_not_found(ou le fournisseur a refusé la demande)upstream_rejected). |
402 | Le solde que le modèle dépense ne peut pas couvrir la détention. |
403 | Le pire des cas ne correspond pas au cap de la clé (key_limit_reached) plus bas max_tokens Soulever le cap. |
404 | Il n'y a pas de modèle avec ce nom (model_not_found). |
429 | La limite de taux de la clé, ou celle du fournisseur (upstream_rate_limited). |
502, 503 | Le fournisseur a échoué (upstream_error) ou est surchargé (upstream_overloaded, avec Retry-AfterRien n'est facturé à moins que le fournisseur n'ait facturé pour la tentative. |
Les codes d'état de chaque action d'endpoint sont répertoriés sous erreurs.
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);
Streaming
avec "stream": true La réponse arrive en tant qu'événement envoyé par le serveur alors que le modèle l'écrit. chat.completion.chunk est a data: ligne, et le flux se termine avec data: [DONE]Le raisonnement entre en
delta.reasoning_contentLa réponse dans delta.content.
Faites circuler tout ce qui peut prendre plus de 100 secondes, comme une réponse longue, une grande
max_tokens ou un modèle de raisonnement. Une demande qui n'est pas diffusée n'envoie rien jusqu'à ce que la réponse soit complète, et le réseau entre vous et Nymbot peut fermer une connexion vide après environ 100 secondes; le modèle est toujours terminé et ce qu'il a écrit est chargé, mais la réponse est perdue.
Stream
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]
- Les lignes commençant par
:sont des commentaires vivants, envoyés toutes les 15 secondes pendant que le modèle réfléchit. - Demandez pour
"stream_options": {"include_usage": true}pour obtenir le dernier morceau en haut, avec un videchoices, le token compte, le coût et lenymbotl’objet . - Si vous fermez la connexion tôt, le modèle n'est pas arrêté: Nymbot lit le reste du flux du fournisseur, pendant jusqu'à 25 secondes, pour obtenir son comptage de jetons, et vous payez ce que le fournisseur rapporte.
- Une erreur avant le premier chunk, telle que
401ou402, revient comme JSON ordinaire avec son code d'état, pas comme un flux. Une erreur après le début du flux arrive comme un dernierdata: {"error": {…}}l'événement, et le flux se termine sans[DONE]. - Les demandes avec des outils, et les modèles sur le transport des réponses d'OpenAI, ne circulent pas du fournisseur.
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);
}
outil d'appel
Décrivez les fonctions dans tools et le modèle peut demander à l'un d'eux d'être appelé au lieu de répondre. Vous exécutez la fonction, ajoutez son résultat comme un tool Un message avec le même
tool_call_idNymbot n'exécute jamais vos fonctions ; il transmet la demande du modèle à vous.
tool_choice prend "auto", "none",
"required" ou {"type": "function", "function": {"name": "…"}}La liste des modèles indique quels modèles peuvent appeler des outils (capabilities.toolsLes outils sont refusés 400 unsupported_tool est nymbot/auto et sur les quelques modèles de catalogue qui fonctionnent sur le transport Responses d'OpenAI, auxquels Nymbot ne peut pas passer des outils.
avec "stream": true, une requête avec des outils s'exécute en une seule pièce et est ensuite envoyée comme une séquence normale: le rôle, un morceau portant chaque appel à outil avec son index, son id, son nom et ses arguments, et le morceau de fin.
La réponse, en partie
"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);
Images dans une demande
Modèles avec capabilities.vision Peut lire des images.Ajouter un image_url
partie à un message utilisateur, avec un public https:// Lien ou A
data:image/…;base64, URL. Jusqu'à 20 images par demande. images SVG sont refusées, et ainsi est un lien de plus de 4 096 caractères ou un avec un nom d'utilisateur ou un mot de passe dans celui-ci (400 invalid_image_urlUne option detail est
auto, low ou high.
avec nymbot/auto, une demande avec une image en elle est redirigée vers un modèle standard qui peut voir. capabilities.vision Refuser les photos avec
400 unsupported_contentUn lien doit pointer vers un hôte public; Nymbot transmet l'image au fournisseur du modèle et ne la conserve pas.
Une image est facturée comme les jetons d'entrée que le fournisseur compte pour elle, comme le reste de la demande.
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);
Le raisonnement
Modèles avec capabilities.reasoning peut réfléchir avant qu'ils ne répondent. demande plus ou moins avec reasoning_effort ("minimal", "low",
"medium" ou "high") ou "reasoning": {"effort": "high"}ou ajouter :thinking au nom du modèle, ce qui signifie un effort élevé. Sur un modèle sans raisonnement, le paramètre est ignoré. nymbot/auto, :thinking Envoie la demande à l'itinéraire de raisonnement standard.
Sur les modèles Anthropic, l’effort devient un budget de réflexion d’environ 1 000, 2 000, 8 000 ou 16 000 jetons, jamais plus que max_tokens La pensée est laissée de côté quand
tool_choice force un outil, et lorsque la demande continue une boucle d'outils (son dernier message est un résultat d'outil), parce que Anthropic a besoin de la pensée précédemment signée pour la reprendre.
Le raisonnement revient en message.reasoning_contentou
delta.reasoning_content lors du streaming, jamais mélangé dans la réponse. Le raisonnement est la sortie et est chargé en tant que tel, à l'intérieur completion_tokensCertains fournisseurs ne retournent pas du tout le texte de raisonnement, et il est toujours facturé.
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);
Modèle de suffixes
Un suffix sur le nom du modèle change la façon dont la demande est traitée, sans un autre champ. Ils fonctionnent sur les ids complets et les noms courts de la même manière, comme dans anthropic/claude-sonnet-5:online.
| suffisant | Effet |
|---|---|
:online | Recherche d'abord sur le web, comme plugins: [{"id": "web"}]Voir Recherche web. |
:thinking | Un grand effort de raisonnement ; sur nymbot/autosur un modèle qui ne peut pas raisonner, 400 model_not_found avec “no endpoints found”. |
:nitro, :floor, :exacto, :extended | Chaque modèle de catalogue a un itinéraire, de sorte qu'il n'y a pas de plus rapide, moins cher ou plus long à choisir; les suffixes sont autorisées de sorte que les noms de modèle copiés d'autres services fonctionnent toujours. |
Tout autre suffixe est ignoré. Le nom entier est essayé en premier, de sorte qu'un modèle dont l'identifiant contient vraiment un colon fonctionne toujours; en l'absence de cela, les suffixes sont retirées de la fin une à la fois jusqu'à ce qu'un modèle correspond. Un nom de modèle peut être au maximum 200 caractères long avec au maximum 4 suffixes; un plus long est refusé avec 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);
Recherche web
Nymbot recherche le dernier message de l'utilisateur (ses 2 000 premiers caractères), lit les meilleures pages et les donne au modèle avec la question, marquée comme contenu extérieur dont le modèle ne devrait pas prendre des instructions.
- Toujours chercher:
"plugins": [{"id": "web", "max_results": 5}]ou a:onlinesuffix sur le modèle. - Rechercher quand ça aide:
"tools": [{"type": "web_search", "parameters": {"max_results": 5}}]Il est également accepté commeweb_search_previewouopenrouter:web_searchNymbot recherche seulement lorsque la question semble avoir besoin d'informations actuelles, le même test que l'application utilise.
max_results est 5 par défaut et au maximum 10. les sources reviennent dans
nymbot.web_search.sourcesChacun avec une title, snippet et
urlEt comme url_citation Notes sur le message.
Chaque recherche qui fonctionne coûte 0,008 $, convertie en sats, au-dessus des jetons, et cela fait partie du hold.Les pages qu'il lit sont aussi des jetons d'entrée, donc une réponse du web coûte plus cher que la même question posée froidement, parfois plusieurs fois plus.
La réponse, en partie
"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);
Réponse à API
Le format plus récent d'OpenAI, utilisé par l'OpenAI Agents SDK et par Codex. Il fonctionne sur les mêmes modèles, facturation et fonctionnalités que Chat Completions.
POST https://nymbot.ai/api/v1/responses Vous avez besoin d’une clé API.
| champs | Type | Nécessaire | Description |
|---|---|---|---|
model | String à | Oui | comme pour Chat complémentaireLes suffixes sont inclus. |
input | String ou array | Oui | Une chaîne, ou une liste d’éléments : messages (rôles) user, assistant, system, developer) avec input_text, input_image et output_text des parties, et function_call et function_call_output Articles pour outils. input_image Prenez un image_url Un lien ou une URL de données, pas un identifiant de fichier reasoning et web_search_call Les objets sont déchirés ; item_reference est refusée . |
instructions | String à | Non pas | Instructions du système. |
max_output_tokens | Intégrale | Non pas | Le plus gros morceau à écrire. |
temperaturetop_p | Numéro | Non pas | Contrôles d'échantillonnage, où le modèle les prend. |
toolstool_choiceparallel_tool_calls | array, chaîne ou objet, boolean | Non pas | Les outils de fonctionnement, dans la forme des réponses ({"type": "function", "name": …, "parameters": …}) A web_search ou web_search_preview L’outil devient Recherche web Lorsque cela aide, d'autres outils intégrés sont refusés. |
reasoning | Objet | Non pas | {"effort": "minimal" | "low" | "medium" | "high"}. xhigh et max signifie high; none Tourne le dessus. |
text.formatresponse_format | Objet | Non pas | Une sortie structurée, comme un schéma JSON ou json_object. |
metadata | Objet | Non pas | Retourné inchangé dans la réponse. Pour un maximum de 16 valeurs de chaîne, des clés jusqu'à 64 caractères et des valeurs jusqu'à 512. |
stream | Bouléen | Non pas | Événements de streaming comme décrit ci-dessous. |
store | Bouléen | Non pas | Rien n'est stocké, et la réponse dit toujours "store": false. |
previous_response_idconversationbackground | String, Objet et Boolean | Non pas | Non soutenu : 400 unsupported_parameterLes réponses ne sont pas enregistrées, alors envoyez toute la conversation dans input à chaque fois. |
Réponse
{
"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 }
}
Une requête d'outil apparaît dans output comme a function_call Point avec
call_id, name et argumentsEnvoyer le résultat comme a
function_call_output Un article avec le même call_idLe raisonnement, quand le modèle le renvoie, est un reasoning Point avec reasoning_text Contenu enregistré en premier. status est incomplete Quand la réponse frappe
max_output_tokens Le vendeur a refusé, avec
incomplete_details.reason Mise à max_output_tokens ou
content_filterLa réponse échoit également les paramètres de la demande (température, outils, choix d'outils, etc.) comme le fait OpenAI, et porte le nymbot coût de l’objet.
En streaming, chaque événement est un event: ligne et a data: Ligne avec A
sequence_numberDans cet ordre : response.created,
response.in_progress, response.output_item.added,
response.content_part.addedN’importe quel nombre de response.output_text.delta,
response.output_text.done, response.content_part.done,
response.output_item.doneEt enfin response.completed avec l'usage et le coût. Une réponse court avec response.incomplete au lieu de cela, et un échec après que le flux a commencé avec response.failedRésoudre les flux comme son propre objet avec response.reasoning_text.delta et .doneLes appels d'outils viennent après le message, chacun en tant qu'élément avec response.function_call_arguments.delta
et .done.
| Statut | Quand |
|---|---|
400 | Non pas model ou input; previous_response_id, conversation, background ou un item_reference (unsupported_parameterUn outil ou un type de contenu non pris en charge. |
402, 403, 404, 429, 502, 503 | Pour les compléments de chat. |
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);
Messages anthropologiques
Le format Anthropic, pour les SDK Anthropic et Claude Code. Il fonctionne avec tous les modèles du catalogue, pas seulement Claude : la demande est traduite, exécutée par le même pipeline, et traduite en arrière.
POST https://nymbot.ai/api/v1/messages Vous avez besoin d'une clé API, comme x-api-key ou Authorization: Bearer.
Le anthropic-version et anthropic-beta Les noms de modèles anthropes sont associés au catalogue, de sorte que Claude Code et les SDKs fonctionnent avec les noms qu’ils utilisent déjà :
- Un nom que le catalogue connaît, comme
claude-sonnet-5ouanthropic/claude-opus-5Il est utilisé comme il est. - Une autre date (
-20260514),-latestUne version telle que-v1Un bracelet comme[1m]et unanthropic/ouanthropic.les préfixes sont supprimés, et les points et les dashes dans la version sont essayés dans les deux sens (claude-haiku-4-5Trouverclaude-haiku-4.5). - Si cela ne correspond toujours pas, la famille (Opus, Sonnet ou Haiku) est utilisée, tant que la version du catalogue est la même ou plus récente que celle demandée.
- Un nom qui ne correspond à rien revient
404not_found_error.
| champs | Type | Nécessaire | Description |
|---|---|---|---|
model | String à | Oui | Un nom de modèle de catalogue ou un nom de modèle anthropologique. |
max_tokens | Intégrale | Oui | Le plus gros morceau à écrire. |
messages | Array | Oui | user et assistant tourne, avec text, image (base64 ou source URL) tool_use et tool_result des blocs. thinking Les blocs des tours précédents sont acceptés et jetés. |
system | String ou array | Non pas | Système prompt, comme une chaîne ou des blocs de texte. |
temperaturetop_p | Numéro | Non pas | Contrôles d'échantillonnage, où le modèle les prend. top_k Il est accepté et abandonné. |
stop_sequences | Résumé de Strings | Non pas | Texte qui termine la réponse. Au maximum 4 chaînes, chacune au maximum 256 caractères. |
toolstool_choice | Array, objet | Non pas | Des outils avec name, description et input_schema• A web_search L’outil de serveur s’affiche Recherche webLes autres outils intégrés d'Anthropic (bash, éditeur de texte, utilisation informatique) sont refusés avec unsupported_tool. tool_choice prend auto, any, tool ou noneet disable_parallel_tool_use. |
thinking | Objet | Non pas | {"type": "enabled", "budget_tokens": 8192}, {"type": "adaptive"} ou {"type": "disabled"}Le budget choisit un niveau d’effort : en dessous de 2 048 minimum, de 2 048 bas, de 8 192 moyen, de 16 384 haut. output_config.effortOu très haut. |
stream | Bouléen | Non pas | Stream dans le format d'événement d'Anthropic. |
metadata | Objet | Non pas | Accepté et ignoré. |
Réponse
{
"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 On peut aussi tenir tool_use blocs et a thinking
Le bloc, dont signature Il est vide. stop_reason est
end_turn, max_tokens, tool_use ou refusalIl a travaillé de la même manière que finish_reason est
Chat complémentaire; stop_sequence est toujours
null, même quand une séquence d'arrêt a terminé la réponse. input_tokens ne compte que les entrées fraîches ; les entrées en cache sont dans les deux champs de cache.
nymbot Objet et le X-Nymbot-Cost-Sats du header.
Streamed, les événements sont Anthropic's : message_start,
content_block_start, ping, content_block_delta
(text_delta, input_json_delta ou thinking_delta),
content_block_stop, message_delta avec la raison d’arrêt, l’usage et le nymbot coût de l’objet, et message_stop• A ping est également envoyé toutes les 15 secondes pendant que le modèle fonctionne. Les appels à outils arrivent après le texte, chacun en tant que
tool_use bloc avec toute son entrée dans un input_json_delta.
Erreurs sur cet endpoint utilisent le format d'Anthropic:
{"type": "error", "error": {"type": "not_found_error", "message": "…"}}Un court équilibre est 402 billing_errorUn fournisseur surchargé
503 overloaded_errorUne défaillance après le début du flux est envoyée comme un error événement .
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);
Compter les tokens
Une estimation du nombre de jetons d'entrée qu'une demande Messages utiliserait, afin qu'un client puisse vérifier avant d'envoyer.
POST https://nymbot.ai/api/v1/messages/count_tokens Vous avez besoin d’une clé API.
Le corps est le même que le Messageset sans max_tokens; le nom du modèle doit résoudre. Le comptage est une estimation: les caractères de la prompt du système, les messages, les appels à outils et les définitions d'outils divisés par quatre, plus 1 600 pour chaque image. Ce n'est pas le tokenizer propre du fournisseur, de sorte que le compte réel peut différer.
Réponse
{ "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);
Liste des modèles
Chaque modèle et générateur de l'API accepte, avec ce qu'il coûte.La liste est lue du même catalogue en direct que le sélectionneur de l'application, donc c'est toujours ce que le serveur exécutera.
GET https://nymbot.ai/api/v1/models Aucune clé n'est nécessaire. Caché pendant cinq minutes.
GET /api/v1/models/{id} Retourner une entrée.
| champs | Type | Nécessaire | Description |
|---|---|---|---|
type | String (recherche) | Non pas | chat (Le défaut est image, video, audio, embedding ou allPlusieurs d’entre elles peuvent être utilisées, comme image,video. |
Les prix sont ce que vous payez, avec la redevance et la marge déjà en, en dollars et en taux au prix Bitcoin actuel. balance indique le montant que dépense le modèle.
nymbot_key est le nom court du modèle dans l'application. created est toujours 0, car le catalogue n'enregistre pas le moment où un modèle a été ajouté. per_request plutôt.
nymbot/auto est toujours le premier, prix comme variable, avec une
routes Liste donnant les tarifs de chaque itinéraire standard. Il liste la vision et le raisonnement, mais pas les outils.
GET /api/v1/models/{id} accepte les mêmes noms et alias en tant que demande, et renvoie l'entrée pour le modèle auquel ils se résolvent.
Réponse
{
"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"
}
]
}
Les autres types :
- Imagerie Les entrées ont
capabilities(accepts_image_url,requires_image_url,edit(et un prixper_generation. - Vidéo Les entrées ont
max_duration_secondsetresolutionset un prixper_secondpour chaque résolution. - Audio Les entrées ont
audio_typespeechoutranscriptionLe prixper_1k_charsouper_minute. - Intégration Les entrées ont
dimensions,context_length,max_inputset un prix par million de jetons d'entrée.
Prix marqués "estimated": true est l'estimation de l'application pour un générateur dont le prix n'est pas publié. type retournés 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);