Base di conoscenza sviluppatori
Chat, risposte e messaggi
Tre modi per chiedere a un modello qualcosa, nei tre formati i clienti già parlano, tutti in esecuzione sugli stessi modelli e fatturati nello stesso modo.
Questa pagina è tradotta automaticamente per comodità. Si applica l'originale inglese.
Chat di completamento
Il formato di chat OpenAI, e quello che supporta quasi ogni strumento. Invia la conversazione finora e ricevi il prossimo messaggio.
POST https://nymbot.ai/api/v1/chat/completions Necessita di una chiave API.
solo model E messages Un parametro di campionamento che il modello scelto non prende viene abbandonato senza un errore, quindi un corpo di richiesta funziona tra i modelli. supported_parametersCiò che viene rifiutato piuttosto che abbandonato è qualcosa che il modello non può fare affatto: immagini per un modello che non può vedere, strumenti per un modello che non può chiamarli.
| campo | Tipo | richiesto | Descrizione |
|---|---|---|---|
model | Stringa | SÌ | nymbot/auto (o di auto) per il routing di Nymbot sul saldo standard, o un modello di catalogo id come anthropic/claude-sonnet-5 sul saldo Pro. I nomi brevi e gli alias dell'app sono anche accettati. abbastanza. |
messages | Array | SÌ | La conversazione, i ruoli system, developer (trattato come sistema) user, assistant E toolIl contenuto è una stringa o un elenco di text E image_url parti; immagini solo nei messaggi degli utenti. input_audio I file sono rifiutati. |
stream | booleano | non | Invia la risposta come è scritta.Vedi Streaming. |
stream_options | oggetto | non | {"include_usage": true} aggiunge un ultimo pezzo con i conti dei token e il costo. |
max_tokensmax_completion_tokens | integrale | non | La maggior parte dei token da scrivere. Abbassa al massimo del modello se più alto. Imposta anche quanto è tenuto dal tuo saldo, quindi un numero più piccolo ha bisogno di meno credito per iniziare. |
temperaturetop_p | Numero | non | Controlli di campionamento: temperature da 0 a 2, top_p da 0 a 1. |
stop | String o array | non | Testo che termina la risposta: una stringa o un massimo di 4 stringhe, ciascuna con un massimo di 256 caratteri. nymbot/auto. |
seed | integrale | non | Per il campionamento ripetibile, dove il modello lo supporta. |
presence_penaltyfrequency_penalty | Numero | non | Controlli di ripetizione, ciascuno da -2 a 2. |
response_format | oggetto | non | {"type": "json_object"} o {"type": "json_schema", "json_schema": {…}}, dove il modello lo supporta. Non utilizzato da nymbot/auto. |
toolstool_choiceparallel_tool_calls | array, stringa o oggetto, booleano | non | Funzione di chiamata. vedi Strumenti di chiamatae a web_search Lo strumento diventa Ricerca webA un massimo di 128 strumenti e 512 KB di definizioni, incastonati a un massimo di 64 livelli profondi; più è un 400. |
reasoning_effortreasoning | String, oggetto | non | "minimal", "low", "medium" o "high", o {"effort": "high"}. "none" o {"enabled": false} Si spegne. vedi Il ragionamento. |
plugins | Array | non | [{"id": "web", "max_results": 5}] Cerca sempre il sito prima.Fino a 10 risultati. |
n | integrale | non | 1) Tutto il resto ritorna 400. |
logit_biasusermetadata | String, String e oggetto | non | Accettato e non inviato. logit_bias mappe con un massimo di 300 token id a numeri da -100 a 100; user Possono contenere fino a 256 caratteri; metadata ha un massimo di 16 valori di stringa, chiavi fino a 64 caratteri e valori fino a 512. |
La risposta è ordinaria chat.completionCon il costo in usage.cost
(in dollari) e nel nymbot di oggetto. model è l'id del modello risolto, quindi un nome breve ritorna come quello completo. Se il modello ha ragionato prima di rispondere, il suo ragionamento è message.reasoning_contentseparata dalla risposta.
Risposta
{
"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 è stato elaborato da ciò che è tornato, dal momento che i fornitori lo riferiscono in modo diverso: tool_calls Quando il modello chiede gli strumenti, length quando la risposta ha usato ogni token consentito (o il modello li ha speso tutti ragionando e non ha scritto nessuna risposta), content_filter quando il fornitore rifiuta, e stop
altrimenti usage.completion_tokens_details.reasoning_tokens è sempre 0: i token di ragionamento nascosti sono contati e addebitati, in completion_tokens.
| Statuto | Quando |
|---|---|
400 | non model o messages (missing_required_parameter); una parte audio o file, o immagini per un modello che non può vederli (unsupported_content(più di 20 immagini)too_many_images); un parametro di campionamento del tipo sbagliato o fuori gamma (invalid_value); un link foto che non è pubblico (invalid_image_url); strumenti su un modello che non può chiamarli (unsupported_tool); n Altro che 1; a :thinking un modello che non può ragionare (model_not_found(o il fornitore ha rifiutato la richiesta)upstream_rejected). |
402 | Il saldo che il modello spende non può coprire il possesso. |
403 | Il peggior caso non si adatta al cappello della chiave (key_limit_reached) più basso max_tokens Oppure alzare il capo. |
404 | Nessun modello con questo nome (model_not_found). |
429 | Il limite di tasso della chiave, o il limite del fornitore (upstream_rate_limited). |
502, 503 | Il fornitore ha fallito (upstream_error(o è sovraccaricato)upstream_overloaded, con Retry-AfterNiente viene addebitato a meno che il fornitore non abbia addebitato per il tentativo. |
I codici di stato di ogni azione di endpoint sono elencati sotto errori.
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
con "stream": true La risposta arriva come evento inviato dal server mentre il modello lo scrive. chat.completion.chunk è a data: linee, e il flusso termina con data: [DONE]Il ragionamento arriva in
delta.reasoning_contentLa risposta in delta.content.
Stream tutto ciò che può richiedere più di circa 100 secondi, ad esempio una risposta lunga, una
max_tokens o un modello di ragionamento. Una richiesta che non viene trasmessa in streaming non invia nulla fino a quando la risposta non è completa, e la rete tra voi e Nymbot può chiudere una connessione inutile dopo circa 100 secondi; il modello finisce ancora e ciò che ha scritto viene caricato, ma la risposta è persa.
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]
- Le linee che iniziano con
:I commenti sono tenuti in vita, inviati ogni 15 secondi mentre il modello sta pensando. - Chiedi per
"stream_options": {"include_usage": true}per ottenere l'ultimo pezzo sopra, con un vuotochoices, il token conta, il costo e ilnymbotdi oggetto. - Se chiudi la connessione in anticipo, il modello non si ferma: Nymbot legge il resto del flusso del provider, per un massimo di 25 secondi, per ottenere il suo conteggio dei token, e paghi ciò che il provider riferisce.
- Un errore prima del primo pezzo, come
401o402, ritorna come normale JSON con il suo codice di stato, non come un flusso.data: {"error": {…}}evento, e il flusso finisce senza[DONE]. - Le richieste con gli strumenti e i modelli sul trasporto delle risposte di OpenAI non vengono trasmesse dal provider.Rispondono ancora con un flusso valido, inviato una volta che la risposta è 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);
}
Strumenti di chiamata
Descrivi le funzioni in tools e il modello può chiedere a qualcuno di essere chiamato invece di rispondere. Esegui la funzione, aggiungi il suo risultato come tool Messaggio con lo stesso
tool_call_idNymbot non esegue mai le tue funzioni; trasmette la richiesta del modello di nuovo a te.
tool_choice Prende "auto", "none",
"required" o {"type": "function", "function": {"name": "…"}}L'elenco dei modelli indica quali modelli possono chiamare strumenti (capabilities.toolsGli strumenti sono rifiutati con 400 unsupported_tool è nymbot/auto e sui pochi modelli di catalogo che funzionano sul trasporto di OpenAI Responses, a cui Nymbot non può passare gli strumenti.
con "stream": true, una richiesta con strumenti viene eseguita in un pezzo e viene quindi inviata come una normale sequenza di pezzi: il ruolo, un pezzo che trasporta ogni chiamata strumento con il suo indice, id, nome e argomenti e il pezzo di finitura.
La risposta, in 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);
Immagini in richiesta
Modelli con capabilities.vision Puoi leggere le immagini.Aggiungi un image_url
parte a un messaggio utente, con un pubblico https:// collegamento o a
data:image/…;base64, URL. Fino a 20 immagini per richiesta. le immagini SVG sono rifiutate, e così è un link di oltre 4.096 caratteri o uno con un nome utente o una password in esso (400 invalid_image_urlUn’opzione detail è
auto, low o high.
con nymbot/auto, una richiesta con un'immagine in esso viene indirizzata a un modello standard che può vedere. capabilities.vision Rifiuta le foto con
400 unsupported_contentUn link deve puntare a un host pubblico; Nymbot trasmette l'immagine al fornitore del modello e non la conserva.
Un'immagine viene addebitata come i token di input che il provider conta per esso, come il resto della richiesta.
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);
ragionamento
Modelli con capabilities.reasoning può pensare prima di rispondere. chiedere di più o di meno con reasoning_effort ("minimal", "low",
"medium" o "high") o "reasoning": {"effort": "high"}o aggiungere :thinking il nome del modello, che significa grande sforzo. su un modello senza ragionamento, la impostazione viene ignorata. nymbot/auto, :thinking Invia la richiesta al percorso di ragionamento standard.
Sui modelli antropici l'impegno diventa un budget di pensiero di circa 1.000, 2.000, 8.000 o 16.000 token, mai più di max_tokens Il pensiero è abbandonato quando
tool_choice Forza uno strumento, e quando la richiesta continua un loop degli strumenti (il suo ultimo messaggio è un risultato degli strumenti), perché Anthropic ha bisogno del pensiero precedentemente firmato per riprendere.
Il ragionamento ritorna in message.reasoning_content, o
delta.reasoning_content quando lo streaming, mai mescolato nella risposta. Il ragionamento è l'uscita e viene caricato come tale, all'interno completion_tokensAlcuni fornitori non restituiscono il testo del ragionamento e viene comunque addebitato.
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);
Modello di suffisso
Un suffisso sul nome del modello modifica il modo in cui viene gestita la richiesta, senza un altro campo. Funzionano su ID completi e nomi brevi allo stesso modo, come in anthropic/claude-sonnet-5:online.
| abbastanza | effetto |
|---|---|
:online | Cerca il web prima, come plugins: [{"id": "web"}]Sì Ricerca web. |
:thinking | Un grande sforzo di ragionamento; su nymbot/autoil percorso del ragionamento. su un modello che non può ragionare, 400 model_not_found con “no endpoints found”. |
:nitro, :floor, :exacto, :extended | Ogni modello di catalogo ha un percorso, quindi non c'è uno più veloce, più economico o più lungo da scegliere; i suffissi sono consentiti in modo che i nomi dei modelli copiati da altri servizi funzionino ancora. |
Qualsiasi altro suffisso viene ignorato. Il nome intero viene provato prima, quindi un modello il cui ID contiene veramente un colon funziona ancora; altrimenti, i suffissi vengono tolti dalla fine uno alla volta fino a quando un modello non corrisponde. Un nome del modello può avere un massimo di 200 caratteri con un massimo di 4 suffissi; uno più lungo è rifiutato 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);
Ricerca web
Nymbot cerca l'ultimo messaggio dell'utente (i suoi primi 2.000 caratteri), legge le migliori pagine e le dà al modello con la domanda, contrassegnato come contenuto esterno dal quale il modello non dovrebbe prendere istruzioni.
- Cerca sempre:
"plugins": [{"id": "web", "max_results": 5}], o a:onlinesuffix sul modello. - Cerca quando aiuta:
"tools": [{"type": "web_search", "parameters": {"max_results": 5}}]Accettato anche comeweb_search_previewoopenrouter:web_searchNymbot cerca solo quando la domanda sembra aver bisogno di informazioni attuali, lo stesso test che l'app utilizza.
max_results è 5 per impostazione predefinita e al massimo 10. le fonti tornano in
nymbot.web_search.sourcesOgnuno con un title, snippet E
urlE come url_citation Annotazioni sul messaggio.
Ogni ricerca che corre costa $ 0,008, convertito in sats, sopra i token, e fa parte del hold.Le pagine che legge sono token di input anche, quindi una risposta dal web costa più della stessa domanda chiesta fredda, a volte più volte.
La risposta, in 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);
Risposte API
Il formato più recente di OpenAI, utilizzato dall'OpenAI Agents SDK e da Codex. Esegue gli stessi modelli, fatturazione e funzionalità di Chat Completions.
POST https://nymbot.ai/api/v1/responses Necessita di una chiave API.
| campo | Tipo | richiesto | Descrizione |
|---|---|---|---|
model | Stringa | SÌ | Come per Chat di completamentoI suffissi sono inclusi. |
input | String o array | SÌ | Una stringa, o un elenco di elementi: messaggi ( ruoli user, assistant, system, developer) con input_text, input_image E output_text delle parti, e function_call E function_call_output articoli per gli strumenti. input_image Prende un image_url link o URL dei dati, non un file id. reasoning E web_search_call gli oggetti sono scartati; item_reference è rifiutato |
instructions | Stringa | non | Istruzioni di sistema. |
max_output_tokens | integrale | non | La maggior parte dei tokens da scrivere. |
temperaturetop_p | Numero | non | Controlli di campionamento, dove il modello li prende. |
toolstool_choiceparallel_tool_calls | array, stringa o oggetto, booleano | non | Le funzioni, nella forma delle risposte ({"type": "function", "name": …, "parameters": …}) a web_search o web_search_preview Lo strumento diventa Ricerca web quando aiuta. Altri strumenti incorporati sono rifiutati. |
reasoning | oggetto | non | {"effort": "minimal" | "low" | "medium" | "high"}. xhigh E max Significa high; none Lo spegniamo. |
text.formatresponse_format | oggetto | non | In questo caso, come schema JSON o json_object. |
metadata | oggetto | non | Ritorna invariato nella risposta. a un massimo di 16 valori di stringa, chiavi fino a 64 caratteri e valori fino a 512. |
stream | booleano | non | Stream eventi come descritto di seguito. |
store | booleano | non | Niente è memorizzato, e la risposta dice sempre "store": false. |
previous_response_idconversationbackground | String, oggetto e booleano | non | Non è supportato: 400 unsupported_parameterLe risposte non vengono memorizzate, quindi inviare l'intera conversazione in input ogni volta |
Risposta
{
"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 richiesta di strumento appare in output come a function_call Il punto con
call_id, name E argumentsinviare il risultato di nuovo come a
function_call_output Articolo con lo stesso call_idIl ragionamento, quando il modello lo restituisce, è un reasoning Il punto con reasoning_text Il contenuto è elencato prima. status è incomplete Quando la risposta colpisce
max_output_tokens Il fornitore ha rifiutato, con
incomplete_details.reason Impostazione max_output_tokens o
content_filterLa risposta risponde anche alle impostazioni della richiesta (temperatura, strumenti, scelta degli strumenti e così via) come lo fa OpenAI, e porta la nymbot Costo di oggetto.
Insomma, ogni evento è un event: linea e a data: Linea con A
sequence_numberIn questo ordine: response.created,
response.in_progress, response.output_item.added,
response.content_part.addedQualsiasi numero di response.output_text.delta,
response.output_text.done, response.content_part.done,
response.output_item.donee infine response.completed con l'uso e il costo. una risposta tagliata a fine breve con response.incomplete e un fallimento dopo che il flusso ha iniziato con response.failedIl ragionamento dei flussi come oggetto proprio con response.reasoning_text.delta E .doneChiamate gli strumenti dopo il messaggio, ognuno come elemento con response.function_call_arguments.delta
E .done.
| Statuto | Quando |
|---|---|
400 | non model o input; previous_response_id, conversation, background o un item_reference (unsupported_parameter); uno strumento o un tipo di contenuto non supportato. |
402, 403, 404, 429, 502, 503 | Per quanto riguarda i chat completati. |
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);
Messaggi antropologici
Il formato di Anthropic, per gli Anthropic SDK e Claude Code. Funziona con tutti i modelli nel catalogo, non solo Claude: la richiesta viene tradotta, eseguita attraverso lo stesso pipeline e tradotta indietro.
POST https://nymbot.ai/api/v1/messages - ha bisogno di una chiave API, come x-api-key o Authorization: Bearer.
Il anthropic-version E anthropic-beta I nomi dei modelli antropici sono abbinati al catalogo, quindi Claude Code e gli SDK funzionano con i nomi già usati:
- Un nome che il catalogo conosce, come
claude-sonnet-5oanthropic/claude-opus-5È usato come è. - Altrimenti una data (
-20260514),-latestUna versione come quella-v1Un giorno di fastidio come[1m]e unanthropic/oanthropic.Il prefix è tolto, e i punti e le dash nella versione sono provati in entrambi i modi (claude-haiku-4-5Trovaclaude-haiku-4.5). - Se ciò non corrisponde, viene utilizzata la famiglia (Opus, Sonnet o Haiku), a condizione che la versione del catalogo sia la stessa o più recente di quella richiesta.
- Un nome che non corrisponde a nulla ritorna
404not_found_error.
| campo | Tipo | richiesto | Descrizione |
|---|---|---|---|
model | Stringa | SÌ | Un catalogo modello id, o un nome modello antropico. |
max_tokens | integrale | SÌ | La maggior parte dei tokens da scrivere. |
messages | Array | SÌ | user E assistant Torna, con text, image (base64 o fonte URL) tool_use E tool_result dei blocchi. thinking I blocchi dei turni precedenti vengono accettati e abbandonati. |
system | String o array | non | Prompt di sistema, come una stringa o blocchi di testo. |
temperaturetop_p | Numero | non | Controlli di campionamento, dove il modello li prende. top_k è accettata e abbandonata. |
stop_sequences | Array di string | non | Testo che termina la risposta. Al massimo 4 stringhe, ciascuna con un massimo di 256 caratteri. |
toolstool_choice | Array, oggetto | non | Strumenti con name, description E input_schemae a web_search Lo strumento di server si Ricerca webGli altri strumenti incorporati di Anthropic (bash, editor di testo, uso del computer) sono rifiutati con unsupported_tool. tool_choice Prende auto, any, tool o none, e disable_parallel_tool_use. |
thinking | oggetto | non | {"type": "enabled", "budget_tokens": 8192}, {"type": "adaptive"} o {"type": "disabled"}Il budget sceglie un livello di sforzo: sotto 2.048 minimo, da 2.048 basso, da 8.192 medio, da 16.384 alto. output_config.efforto in alto. |
stream | booleano | non | Stream in formato evento di Anthropic. |
metadata | oggetto | non | accettato e ignorato. |
Risposta
{
"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 Può anche tenere tool_use Blocco e a thinking
Blocco, di cui signature è vuoto stop_reason è
end_turn, max_tokens, tool_use o refusalHa lavorato nello stesso modo in cui finish_reason è
Chat di completamento; stop_sequence è sempre
null, anche quando una sequenza di stop ha terminato la risposta. input_tokens contano solo le entrate fresche; le entrate in cache si trovano nei due campi di cache.
nymbot L’oggetto e il X-Nymbot-Cost-Sats di Header.
Streamed, gli eventi sono Anthropic's: message_start,
content_block_start, ping, content_block_delta
(text_delta, input_json_delta o thinking_delta),
content_block_stop, message_delta con la ragione d’arresto, l’uso e il nymbot costo dell’oggetto e message_stope a ping viene anche inviato ogni 15 secondi mentre il modello è in funzione. Le chiamate di strumento arrivano dopo il testo, ognuno come
tool_use blocco con l'intero ingresso in un input_json_delta.
Gli errori su questo endpoint usano il formato di Anthropic:
{"type": "error", "error": {"type": "not_found_error", "message": "…"}}Un breve equilibrio è 402 billing_errorUn fornitore sovraccaricato
503 overloaded_errorUn fallimento dopo che il flusso è iniziato viene inviato come un error Il 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);
Contare i token
Una stima di quanti token di input una richiesta Messaggi utilizzerebbe, in modo che un client possa controllare prima di inviare.
POST https://nymbot.ai/api/v1/messages/count_tokens - ha bisogno di una chiave API. gratuito.
Il corpo è lo stesso per Messaggisenza max_tokensIl conteggio è una stima: i caratteri del prompt del sistema, i messaggi, le chiamate degli strumenti e le definizioni degli strumenti divisi per quattro, più 1.600 per ogni immagine. Non è il tokenizer proprio del provider, quindi il conteggio reale può variare.
Risposta
{ "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);
Elenco dei modelli
Ogni modello e generatore accetta l'API, con ciò che costa.L'elenco viene letto dallo stesso catalogo dal vivo come il picker dell'app, quindi è sempre quello che il server eseguirà.
GET https://nymbot.ai/api/v1/models - nessuna chiave necessaria. Nascosto per cinque minuti.
GET /api/v1/models/{id} Ritorna un ingresso.
| campo | Tipo | richiesto | Descrizione |
|---|---|---|---|
type | String di ricerca (Query) | non | chat e il default, image, video, audio, embedding o allAlcuni possono essere assegnati, come image,video. |
I prezzi sono ciò che paghi, con la tassa e il margine già in, in dollari e in sats al prezzo Bitcoin corrente. balance Dice quale bilancio il modello spende.
nymbot_key è il nome corto del modello nell'app. created è sempre 0, poiché il catalogo non registra quando un modello è stato aggiunto. per_request Invece.
nymbot/auto è sempre prima, a prezzo di variable, con un
routes Elenco che elenca le tariffe di ciascun percorso standard. Elenca la visione e il ragionamento, ma non gli strumenti.
GET /api/v1/models/{id} accetta gli stessi nomi e alias come richiesta, e restituisce l'entrata per il modello a cui si risolve.
Risposta
{
"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"
}
]
}
Gli altri tipi:
- Immagine Le entrate hanno
capabilities(accepts_image_url,requires_image_url,edite un prezzoper_generation. - Il video Le entrate hanno
max_duration_secondsEresolutionse un prezzoper_secondper ogni risoluzione. - audio Le entrate hanno
audio_typespeechotranscriptionIl prezzoper_1k_charsoper_minute. - Inserimento Le entrate hanno
dimensions,context_length,max_inputse un prezzo per milione di token di input.
Prezzi segnati "estimated": true è la stima dell'app per un generatore il cui prezzo non è pubblicato. type Ritorno 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);