Passa al contenuto
Torna a Nymbot

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.

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.

campoTiporichiestoDescrizione
modelStringaSÌ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.
messagesArraySÌ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.
streambooleanononInvia la risposta come è scritta.Vedi Streaming.
stream_optionsoggettonon{"include_usage": true} aggiunge un ultimo pezzo con i conti dei token e il costo.
max_tokens
max_completion_tokens
integralenonLa 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.
temperature
top_p
NumerononControlli di campionamento: temperature da 0 a 2, top_p da 0 a 1.
stopString o arraynonTesto che termina la risposta: una stringa o un massimo di 4 stringhe, ciascuna con un massimo di 256 caratteri. nymbot/auto.
seedintegralenonPer il campionamento ripetibile, dove il modello lo supporta.
presence_penalty
frequency_penalty
NumerononControlli di ripetizione, ciascuno da -2 a 2.
response_formatoggettonon{"type": "json_object"} o {"type": "json_schema", "json_schema": {…}}, dove il modello lo supporta. Non utilizzato da nymbot/auto.
tools
tool_choice
parallel_tool_calls
array, stringa o oggetto, booleanononFunzione 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_effort
reasoning
String, oggettonon"minimal", "low", "medium" o "high", o {"effort": "high"}. "none" o {"enabled": false} Si spegne. vedi Il ragionamento.
pluginsArraynon[{"id": "web", "max_results": 5}] Cerca sempre il sito prima.Fino a 10 risultati.
nintegralenon1) Tutto il resto ritorna 400.
logit_bias
user
metadata
String, String e oggettononAccettato 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.

StatutoQuando
400non 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).
402Il saldo che il modello spende non può coprire il possesso.
403Il peggior caso non si adatta al cappello della chiave (key_limit_reached) più basso max_tokens Oppure alzare il capo.
404Nessun modello con questo nome (model_not_found).
429Il limite di tasso della chiave, o il limite del fornitore (upstream_rate_limited).
502, 503Il 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 vuoto choices, il token conta, il costo e il nymbot di 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 401 o 402, 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.

abbastanzaeffetto
:onlineCerca il web prima, come plugins: [{"id": "web"}]Sì Ricerca web.
:thinkingUn 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, :extendedOgni 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);

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 :online suffix sul modello.
  • Cerca quando aiuta: "tools": [{"type": "web_search", "parameters": {"max_results": 5}}]Accettato anche come web_search_preview o openrouter: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.

campoTiporichiestoDescrizione
modelStringaSÌCome per Chat di completamentoI suffissi sono inclusi.
inputString o arraySÌ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
instructionsStringanonIstruzioni di sistema.
max_output_tokensintegralenonLa maggior parte dei tokens da scrivere.
temperature
top_p
NumerononControlli di campionamento, dove il modello li prende.
tools
tool_choice
parallel_tool_calls
array, stringa o oggetto, booleanononLe 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.
reasoningoggettonon{"effort": "minimal" | "low" | "medium" | "high"}. xhigh E max Significa high; none Lo spegniamo.
text.format
response_format
oggettononIn questo caso, come schema JSON o json_object.
metadataoggettononRitorna invariato nella risposta. a un massimo di 16 valori di stringa, chiavi fino a 64 caratteri e valori fino a 512.
streambooleanononStream eventi come descritto di seguito.
storebooleanononNiente è memorizzato, e la risposta dice sempre "store": false.
previous_response_id
conversation
background
String, oggetto e booleanononNon è 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.

StatutoQuando
400non 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, 503Per 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-5 o anthropic/claude-opus-5È usato come è.
  • Altrimenti una data (-20260514), -latestUna versione come quella -v1Un giorno di fastidio come [1m] e un anthropic/ o anthropic. Il prefix è tolto, e i punti e le dash nella versione sono provati in entrambi i modi (claude-haiku-4-5 Trova claude-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 404 not_found_error.
campoTiporichiestoDescrizione
modelStringaSÌUn catalogo modello id, o un nome modello antropico.
max_tokensintegraleSÌLa maggior parte dei tokens da scrivere.
messagesArraySÌ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.
systemString o arraynonPrompt di sistema, come una stringa o blocchi di testo.
temperature
top_p
NumerononControlli di campionamento, dove il modello li prende. top_k è accettata e abbandonata.
stop_sequencesArray di stringnonTesto che termina la risposta. Al massimo 4 stringhe, ciascuna con un massimo di 256 caratteri.
tools
tool_choice
Array, oggettononStrumenti 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.
thinkingoggettonon{"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.
streambooleanononStream in formato evento di Anthropic.
metadataoggettononaccettato 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.

campoTiporichiestoDescrizione
typeString di ricerca (Query)nonchat 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 prezzo per_generation.
  • Il video Le entrate hanno max_duration_seconds E resolutionse un prezzo per_second per ogni risoluzione.
  • audio Le entrate hanno audio_type speech o transcriptionIl prezzo per_1k_chars o per_minute.
  • Inserimento Le entrate hanno dimensions, context_length, max_inputs e 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);