Přejít na obsah
Zpět na Nymbot

Znalostní základna Vývojáři

Balance, top-upy a klíče

Zkontrolujte, co máte, nahoru nad Lightning, nahoru automaticky z vlastní peněženky, vidět, co každá žádost stojí, a spravovat klíče z kódu.

Zkontrolujte rovnováhu

Oba vaše rovnováhy, a kolik z tohoto klíče je použit.

GET https://nymbot.ai/api/v1/credits/balance Potřebujete API klíč. POST To platí i pro zákazníky, kteří to očekávají.

balance je dvě rovnováhy dohromady v dolarech při současné ceně Bitcoin, pro nástroje, které očekávají jediné číslo (null Zbytek je v kreditech a sázkách, což je způsob, jakým jsou zůstatky skutečně udržovány. key Klíč, který dosáhl své hranice, může stále zkontrolovat zůstatek.

Odpověď

{
  "balance": 49.18,
  "balance_sats": 42037,
  "standard": { "credits": 120.4, "sats": 1204 },
  "pro": { "credits": 408.33, "sats": 40833 },
  "key": {
    "id": "4f0c9a1be27d3856",
    "name": "laptop scripts",
    "limit_sats": 20000,
    "period_used_sats": 3412,
    "total_used_sats": 18230,
    "reset_period": "monthly",
    "reset_at": "2026-10-01T00:00:00Z"
  }
}
statusuKdy
401Klíč je chybějící, neznámý, zrušený nebo vypršený.

cURL

curl https://nymbot.ai/api/v1/credits/balance \
  -H "Authorization: Bearer $NYMBOT_API_KEY"

Python

import os
import requests

res = requests.get(
    "https://nymbot.ai/api/v1/credits/balance",
    headers={"Authorization": "Bearer " + os.environ["NYMBOT_API_KEY"]},
)
balance = res.json()
print(balance["standard"]["sats"], balance["pro"]["sats"])

JavaScript

const res = await fetch("https://nymbot.ai/api/v1/credits/balance", {
  headers: { "Authorization": "Bearer " + process.env.NYMBOT_API_KEY },
});
const balance = await res.json();
console.log(balance.standard.sats, balance.pro.sats);

Platební metody

Jak to zvládnout a jak to zvládnout: Lightning je jediná metoda.

GET https://nymbot.ai/api/v1/topup/payment-methods Není potřeba žádný klíč.

Top-up je 10 až 1 000 000 sats; Pro top-up musí koupit alespoň jeden Pro kredit, takže začíná na 100 sats. bulk_bonus uvádí dodatečný kredit na větší top-upy, stejný jako v aplikaci: 10%, 15% nebo 20% více na standardní top-upy od 500, 1000 nebo 5000 sats, a na Pro top-upy od 5000, 10.000 nebo 50 000 sats.

Odpověď

{
  "supported_methods": [
    {
      "method": "btc-lightning",
      "display_name": "Bitcoin Lightning",
      "supported_currencies": ["SATS", "USD", "BTC"],
      "limits": {
        "SATS": { "min": 10, "max": 1000000 },
        "USD": { "min": 0.02, "max": 1170 },
        "BTC": { "min": 1e-7, "max": 0.01 }
      },
      "tiers": ["standard", "pro"],
      "default_tier": "pro",
      "tier_min_sats": { "standard": 10, "pro": 100 },
      "sats_per_credit": { "standard": 10, "pro": 100 },
      "bulk_bonus": [
        { "bonus": 0.1, "standard_sats": 500, "pro_sats": 5000 },
        { "bonus": 0.15, "standard_sats": 1000, "pro_sats": 10000 },
        { "bonus": 0.2, "standard_sats": 5000, "pro_sats": 50000 }
      ]
    }
  ]
}

cURL

curl https://nymbot.ai/api/v1/topup/payment-methods

Python

import requests

methods = requests.get("https://nymbot.ai/api/v1/topup/payment-methods").json()
print(methods["supported_methods"][0]["limits"])

JavaScript

const methods = await (await fetch("https://nymbot.ai/api/v1/topup/payment-methods")).json();
console.log(methods.supported_methods[0].limits);

Stoupání nad bleskem

Vytváří účtenku Lightning, která přidává kredit k nimmu, ke kterému klíč patří. Zkontrolujte to K tomu je třeba přidat úvěr.

POST https://nymbot.ai/api/v1/topup/create/btc-lightning Potřebujete API klíč.

poleTypPožadovánoPopisek
amountČísloAnoKolik toho, v currencyCelé číslo pro sázku.
currencyStringovéneSATS (na základě deficitu USD nebo BTCDolary se převádějí za současnou cenu Bitcoinu.
tierStringovénepro (předpokládané ztráty nebo standardNa jakou úvěrovou bilanci se vztahuje.

Standardní kredit je 10 sats a Pro kredit 100 sats, plus jakýkoliv objemový bonus; credits Řekněte, co k tomuto účtu přidáte.

Odpověď

{
  "invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
  "payment_request": "lnbc100u1p5...",
  "amount_sats": 10000,
  "credits": 115,
  "tier": "pro",
  "expires_at": "2026-09-30T09:27:00Z",
  "status": "pending"
}
statusuKdy
400Jiná metoda v cestě (unsupported_method, neznámá měna (unsupported_currencya) částku, která je nižší než minimální částka, nebo částku, která je nižší nežamount_too_smallvíce než 1 000 000 Kč (amount_too_large) nebo odmítnutý peněženkou Lightning (amount_out_of_range).
429Více než 60 faktur pro tento nym, nebo 120 z této adresy, za hodinu (rate_limit_exceeded, s Retry-After).
502V současné době nelze provést žádnou registraci (invoice_unavailable, s Retry-After).

cURL

curl https://nymbot.ai/api/v1/topup/create/btc-lightning \
  -H "Authorization: Bearer $NYMBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount": 10000, "currency": "SATS", "tier": "pro"}'

Python

import os
import requests

res = requests.post(
    "https://nymbot.ai/api/v1/topup/create/btc-lightning",
    headers={"Authorization": "Bearer " + os.environ["NYMBOT_API_KEY"]},
    json={"amount": 10000, "currency": "SATS", "tier": "pro"},
)
invoice = res.json()
print(invoice["payment_request"])

JavaScript

const res = await fetch("https://nymbot.ai/api/v1/topup/create/btc-lightning", {
  method: "POST",
  headers: {
    "Authorization": "Bearer " + process.env.NYMBOT_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ amount: 10000, currency: "SATS", tier: "pro" }),
});
const invoice = await res.json();
console.log(invoice.payment_request);

Prohlédněte si top-up

Zeptá se, zda faktura byla zaplacena a jakmile je, přidává úvěr. Kontrola je to, co kredity, takže po zaplacení, zkontrolujte, dokud stav je creditedKontrolovat znovu poté je bezpečné: úvěr přistane jednou, bez ohledu na to, kolikrát se zeptáte.

GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - potřebuje klíč od nym, který vytvořil fakturu.

status je pending (zatím není zaplaceno) paid (platí, ale zatím není kreditováno; zkontrolujte znovu), credited (na vaší rovnováze) nebo expired (Neplacené včas). polia bilance jsou pro úroveň, na které se faktura vyšplhá.

Odpověď

{
  "invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
  "status": "credited",
  "amount_sats": 10000,
  "credits": 115,
  "tier": "pro",
  "expires_at": null,
  "balance_credits": 523.33,
  "balance_sats": 52333
}
statusuKdy
400ID není 64-charakterový ID z vytvořeného hovoru.
404Žádná faktura podle tohoto ID pro váš nym (invoice_not_found).

cURL

curl https://nymbot.ai/api/v1/topup/status/$INVOICE_ID \
  -H "Authorization: Bearer $NYMBOT_API_KEY"

Python

import os, time
import requests

headers = {"Authorization": "Bearer " + os.environ["NYMBOT_API_KEY"]}
url = "https://nymbot.ai/api/v1/topup/status/" + invoice["invoice_id"]

while True:
    status = requests.get(url, headers=headers).json()["status"]
    if status in ("credited", "expired"):
        break
    time.sleep(3)
print(status)

JavaScript

const headers = { "Authorization": "Bearer " + process.env.NYMBOT_API_KEY };
const url = "https://nymbot.ai/api/v1/topup/status/" + invoice.invoice_id;

let status;
do {
  await new Promise((r) => setTimeout(r, 3000));
  status = (await (await fetch(url, { headers })).json()).status;
} while (status !== "credited" && status !== "expired");
console.log(status);

Chci dějiny

Jeden řádek na žádost: co to bylo, který model, kolik tokenů a co to stálo. Žádné výzvy nebo odpovědi nejsou uchovávány, takže žádné nejsou vráceny. Řádky jsou uchovávány po dobu 90 dnů, nejnovější první. Klíč, který dosáhl své hranice, může stále číst svou historii.

GET https://nymbot.ai/api/v1/queries/history - potřebuje klíč API, který vidí své vlastní požadavky, nebo Podepsaná žádost z vašeho nym, který vidí každý klíč.

poleTypPožadovánoPopisek
pageinteger (požadavek na rozdíl)neVýchozí 1, maximálně 1000; vyšší stránka je 400 invalid_value.
page_countinteger (požadavek na rozdíl)neRůžky na stránku. Výchozí 20, maximálně 100.
start_date
end_date
Stringová otázka (query)neISO 8601 data a časy.
modelStringová otázka (query)nePouze tento model.
typeStringová otázka (query)nechat, responses, messages, image, video, speech, transcription nebo embedding.
all_keysBoolean (požadavek na to)nes jedním klíčem: true zahrnuje každý klíč stejného nym. Default false.
key_idStringová otázka (query)nes podepsanou žádostí, nebo s all_keys=truePouze tento klíč.

Odpověď

{
  "data": [
    {
      "id": "q_71c4e9a0",
      "timestamp": "2026-09-30T08:12:00Z",
      "model": "anthropic/claude-sonnet-5",
      "type": "chat",
      "input_tokens": 1240,
      "output_tokens": 380,
      "cached_tokens": 0,
      "cost_sats": 16.2,
      "cost_usd": 0.01895,
      "balance": "pro",
      "key_id": "4f0c9a1be27d3856",
      "web_search": false,
      "status": "ok"
    }
  ],
  "pagination": { "page": 1, "page_count": 20, "total": 311, "total_pages": 16 }
}

cURL

curl "https://nymbot.ai/api/v1/queries/history?page_count=50&type=chat" \
  -H "Authorization: Bearer $NYMBOT_API_KEY"

Python

import os
import requests

res = requests.get(
    "https://nymbot.ai/api/v1/queries/history",
    headers={"Authorization": "Bearer " + os.environ["NYMBOT_API_KEY"]},
    params={"page_count": 50, "type": "chat"},
)
for row in res.json()["data"]:
    print(row["timestamp"], row["model"], row["cost_sats"])

JavaScript

const res = await fetch("https://nymbot.ai/api/v1/queries/history?page_count=50&type=chat", {
  headers: { "Authorization": "Bearer " + process.env.NYMBOT_API_KEY },
});
for (const row of (await res.json()).data) console.log(row.timestamp, row.model, row.cost_sats);

Podepsání žádostí o účet

Vytváření, změna a zrušení klíčů, shrnutí účtu a automatické top-upy neberou klíč API. berou podpis z vašeho nym, takže únikový klíč může strávit až do svého limitu, ale nikdy nemůže vytvořit další klíč nebo zvýšit svůj vlastní limit.

Aplikace dělá tohle za vás: vše ve svém Oheň Tuto sekci potřebujete pouze pro správu klíčů z vlastního kódu.

Podpis je událostí Nostr typu 27235 (NIP-98), odeslanou base64-kódovanou v Authorization Header se slovem Nostr Na přední straně:

Událost

{
  "kind": 27235,
  "created_at": 1790726400,
  "tags": [
    ["u", "https://nymbot.ai/api/v1/keys"],
    ["method", "POST"],
    ["nonce", "9c4e21f07a3b...16 random bytes in hex"],
    ["payload", "3f1a0d7c8e2b...sha256 of the exact request body in hex"]
  ],
  "content": "",
  "pubkey": "your public key in hex",
  "id": "...",
  "sig": "..."
}
  • u je úplná adresa URL žádosti, včetně řetězce dotazu, přesně tak, jak byla odeslána.
  • method Je to metoda HTTP.
  • payload je SHA-256 surového požadavku tělesa, v hex. POST a PATCH, a tělo, které odesíláte, musí být bytem za bytem, který jste hashovali.
  • created_at musí být do 60 sekund od hodin serveru.
  • Každá akce probíhá jednou, a GET zahrnuty, takže zachycený nadpis nelze přehrát. Pro každou žádost podepište novou. nonce označte náhodnou hodnotou tak, aby se dvě žádosti podepsané ve stejné sekundě stále lišily.
  • Tělo podepsané žádosti může být maximálně 64 KB a tělo potřebuje Content-Type: application/json.

Ztracená událost se vrací 401 missing_nostr_auth; jeden, který je špatně vytvořený, špatně podepsaný, příliš starý, nebo pro jinou adresu URL, metodu nebo tělo vrátí invalid_nostr_auth, s důvodem v poselství; opakovaně použitý se vrátí nostr_auth_replayedPodpis je kontrolován před tím, než je tělo přečteno, a každá adresa může selhat 30krát za minutu (adresa IPv6 se počítá jako její celek /64); poté dostane 429 s Retry-After.

Prohlížeče mohou tyto koncové body volat pouze z vlastních stránek Nymbotu (https://nymbot.ai, https://nymchat.app Stránka na jakémkoli jiném webu nedostane zpět žádné hlavičky CORS, takže nemůže číst, co vrátí. OriginA nejsou ovlivněny.

Váš tajný klíč

Podpis potřebuje váš nymův tajný klíč (tzv. nsec), který ovládá vše: vaši identitu, historii a rovnováhu. Pouze jej vložte do skriptů na počítači, kterému důvěřujete, přečtěte si ho z prostředí spíše než do souboru a dávejte přednost aplikaci, když můžete.

Tito pomocníci vytvářejí nadpis. Pozdější příklady na této stránce je používají. Přečtou tajný klíč v hexatu z NOSTR_SECRET_HEX; cURL jeden používá Naková nástroj příkazového řádku, který používá klíč nsec nebo hex, a sha256sum V případě macOS, shasum -a 256).

cURL

nostr_auth() {
  method="$1"; url="$2"; body="$3"
  nonce=$(openssl rand -hex 16)
  if [ -n "$body" ]; then
    hash=$(printf '%s' "$body" | sha256sum | cut -d' ' -f1)
    event=$(nak event --sec "$NOSTR_SECRET_HEX" -k 27235 -t "u=$url" -t "method=$method" -t "nonce=$nonce" -t "payload=$hash")
  else
    event=$(nak event --sec "$NOSTR_SECRET_HEX" -k 27235 -t "u=$url" -t "method=$method" -t "nonce=$nonce")
  fi
  printf 'Nostr %s' "$(printf '%s' "$event" | base64 | tr -d '\n')"
}

Python

# pip install coincurve requests
import base64, hashlib, json, os, time
from coincurve import PrivateKey, PublicKeyXOnly

SECRET = bytes.fromhex(os.environ["NOSTR_SECRET_HEX"])

def nostr_auth(method, url, body=b""):
    pubkey = PublicKeyXOnly.from_secret(SECRET).format().hex()
    tags = [["u", url], ["method", method], ["nonce", os.urandom(16).hex()]]
    if body:
        tags.append(["payload", hashlib.sha256(body).hexdigest()])
    created_at = int(time.time())
    serialized = json.dumps([0, pubkey, created_at, 27235, tags, ""], separators=(",", ":"), ensure_ascii=False)
    event_id = hashlib.sha256(serialized.encode()).digest()
    event = {
        "id": event_id.hex(),
        "pubkey": pubkey,
        "created_at": created_at,
        "kind": 27235,
        "tags": tags,
        "content": "",
        "sig": PrivateKey(SECRET).sign_schnorr(event_id).hex(),
    }
    return "Nostr " + base64.b64encode(json.dumps(event).encode()).decode()

JavaScript

// npm install nostr-tools
import { createHash, randomBytes } from "node:crypto";
import { finalizeEvent } from "nostr-tools/pure";

const secret = Buffer.from(process.env.NOSTR_SECRET_HEX, "hex");

export function nostrAuth(method, url, body = "") {
  const tags = [["u", url], ["method", method], ["nonce", randomBytes(16).toString("hex")]];
  if (body) tags.push(["payload", createHash("sha256").update(body).digest("hex")]);
  const event = finalizeEvent(
    { kind: 27235, created_at: Math.floor(Date.now() / 1000), tags, content: "" },
    secret,
  );
  return "Nostr " + Buffer.from(JSON.stringify(event)).toString("base64");
}

Shrnutí účtu

Co ukazuje v horní části listu API aplikace: váš veřejný klíč, obě rovnováhy, kolik klíčů je aktivních (není zrušeno nebo vypršelo) a Automatický top-up nastavení, nebo null Když je server neposkytuje.

GET https://nymbot.ai/api/v1/account Potřebuji a Podepsaná žádost.

Odpověď

{
  "data": {
    "pubkey": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
    "balances": {
      "standard": { "credits": 120.4, "sats": 1204 },
      "pro": { "credits": 408.33, "sats": 40833 }
    },
    "keys_active": 3,
    "nwc_auto_topup": {
      "connected": true, "threshold_sats": 5000, "topup_sats": 20000, "tier": "pro",
      "last_topup_at": null, "last_topup_sats": null, "last_error": null
    }
  }
}

cURL

URL=https://nymbot.ai/api/v1/account
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/account"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json())

JavaScript

const url = "https://nymbot.ai/api/v1/account";
const res = await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } });
console.log(await res.json());

Správa klíčů

Koncové body za seznamem klíčů aplikace. Všechny potřebují Podepsaná žádostKaždý klíč je vrácen v tomto formuláři, s časy v ISO 8601 a částkami v sats:

Klíčový objekt

{
  "id": "4f0c9a1be27d3856",
  "name": "laptop scripts",
  "hint": "sk-nymbot-Qm7x…c2Lw",
  "limit_sats": 20000,
  "reset_period": "monthly",
  "reset_at": "2026-10-01T00:00:00Z",
  "expire_at": null,
  "period_used_sats": 3412,
  "total_used_sats": 18230,
  "created_at": "2026-08-14T09:21:07Z",
  "updated_at": "2026-09-02T17:40:55Z",
  "last_used_at": "2026-09-30T08:12:00Z",
  "revoked_at": null
}

hint klíč je dostatečný k rozpoznání klíče, ale ne k jeho použití. klíč se vrátí pouze jednou, když je vytvořen.

Seznam klíčů

GET https://nymbot.ai/api/v1/keys A podepsal jsem.

poleTypPožadovánoPopisek
include_revokedBoolean (požadavek na to)neObsahuje zrušené klíče. výchozí false.

Odpověď

{ "data": [ { "id": "4f0c9a1be27d3856", "name": "laptop scripts", "hint": "sk-nymbot-Qm7x…c2Lw", "...": "..." } ] }

cURL

URL=https://nymbot.ai/api/v1/keys
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/keys"
for key in requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json()["data"]:
    print(key["id"], key["name"], key["period_used_sats"], key["limit_sats"])

JavaScript

const url = "https://nymbot.ai/api/v1/keys";
const { data } = await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json();
for (const key of data) console.log(key.id, key.name, key.period_used_sats, key.limit_sats);

Vytvořte klíč

POST https://nymbot.ai/api/v1/keys Podepsané - zpět 201.

poleTypPožadovánoPopisek
nameStringovéAno1 až 40 znaků, které se liší od ostatních aktivních klíčů (ignorování případu).
limit_satsintegernePůjčka je v ceně, alespoň 1. nechte ji za žádnou cenu.
reset_periodStringovénedaily, weekly nebo monthlyPotřeby limit_satsNechte to ven pro čepici, která se nikdy neobnoví.
expire_atString nebo integerneKdyž klíč přestane pracovat: ISO 8601 čas, nebo milisekundy od roku 1970.

Odpověď (201)

{
  "data": {
    "id": "4f0c9a1be27d3856",
    "name": "laptop scripts",
    "hint": "sk-nymbot-Qm7x…c2Lw",
    "limit_sats": 20000,
    "reset_period": "monthly",
    "key": "sk-nymbot-Qm7x...c2Lw",
    "...": "the rest of the key object"
  }
}
statusuKdy
400Chybějící nebo příliš dlouhé jméno; jméno již používané (duplicate_name); limit, který není celým číslem nejméně 1; resetové období bez limitů; uplynutí platnosti v minulosti; neznámé pole (unknown_parameter); nebo 25 aktivních klíčů již (too_many_keys).
429Více než 60 klíčů vyrobených touto nym, nebo 120 z této adresy, za hodinu (rate_limit_exceeded, s Retry-After).

cURL

URL=https://nymbot.ai/api/v1/keys
BODY='{"name":"laptop scripts","limit_sats":20000,"reset_period":"monthly"}'
curl "$URL" \
  -H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
  -H "Content-Type: application/json" \
  -d "$BODY"

Python

import json
import requests

url = "https://nymbot.ai/api/v1/keys"
body = json.dumps({"name": "laptop scripts", "limit_sats": 20000, "reset_period": "monthly"}).encode()
res = requests.post(
    url,
    data=body,
    headers={"Authorization": nostr_auth("POST", url, body), "Content-Type": "application/json"},
)
print(res.json()["data"]["key"])

JavaScript

const url = "https://nymbot.ai/api/v1/keys";
const body = JSON.stringify({ name: "laptop scripts", limit_sats: 20000, reset_period: "monthly" });
const res = await fetch(url, {
  method: "POST",
  headers: { "Authorization": nostrAuth("POST", url, body), "Content-Type": "application/json" },
  body,
});
console.log((await res.json()).data.key);

Čtení jednoho klíče

GET https://nymbot.ai/api/v1/keys/{id} A podepsal jsem.

Návraty {"data": {…}} s klíčovým objektem, nebo 404 key_not_found pokud žádný z vašich klíčů nemá toto ID.

cURL

URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json()["data"])

JavaScript

const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
console.log((await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json()).data);

Změna klíče

PATCH https://nymbot.ai/api/v1/keys/{id} A podepsal jsem.

Posílejte jakýkoliv name, limit_sats, reset_period a expire_atStejná pravidla jako při výběru klíče. null vyčistí pole: žádné omezení, žádné resetování, žádné vypršení platnosti. Změna období resetování zahajuje nové období od nuly.400 key_revoked• Návraty {"data": {…}} s aktualizovaným klíčovým objektem.

cURL

URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
BODY='{"limit_sats":50000,"expire_at":null}'
curl -X PATCH "$URL" \
  -H "Authorization: $(nostr_auth PATCH "$URL" "$BODY")" \
  -H "Content-Type: application/json" \
  -d "$BODY"

Python

import json
import requests

url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
body = json.dumps({"limit_sats": 50000, "expire_at": None}).encode()
res = requests.patch(
    url,
    data=body,
    headers={"Authorization": nostr_auth("PATCH", url, body), "Content-Type": "application/json"},
)
print(res.json()["data"])

JavaScript

const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
const body = JSON.stringify({ limit_sats: 50000, expire_at: null });
const res = await fetch(url, {
  method: "PATCH",
  headers: { "Authorization": nostrAuth("PATCH", url, body), "Content-Type": "application/json" },
  body,
});
console.log((await res.json()).data);

Zrušení klíče

DELETE https://nymbot.ai/api/v1/keys/{id} A podepsal jsem.

Zastaví klíč okamžitě, pro dobro. Zůstává v seznamu s revoked_at vyhlídky a lze je vidět s include_revoked=trueZrušení klíče, který již byl zrušen, odpovídá stejným způsobem. Pouze posledních 50 zrušených klíčů je zachováno; starší klíče jsou odstraněny, když je zrušen další klíč.

Odpověď

{ "data": { "id": "4f0c9a1be27d3856", "revoked": true } }

cURL

URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
curl -X DELETE "$URL" -H "Authorization: $(nostr_auth DELETE "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
print(requests.delete(url, headers={"Authorization": nostr_auth("DELETE", url)}).json())

JavaScript

const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
const res = await fetch(url, { method: "DELETE", headers: { "Authorization": nostrAuth("DELETE", url) } });
console.log(await res.json());

NWC Auto-top-up přehrávač

Připojte peněženku Lightning s aplikací Nostr Wallet Connect a Nymbot si sám vytvoří rovnováhu, když je výdaje na API nízké. Podepsaná žádost.

Jak to funguje: poté, co je žádost o API účtována do zůstatku, který jste se rozhodli sledovat, pokud tento zůstatek klesne pod váš prah, Nymbot vyhotoví fakturu za vaši částku, požádá vaši peněženku, aby ji zaplatila, a přidá kredit. To se zvyšuje maximálně jednou za každých 5 minut pro každý nym a zůstatek, takže výbuch žádostí nemůže vyčerpat peněženku. Výdaje v aplikacích ji nezpůsobí. Čas a velikost posledního top-up a poslední chyba jsou v nastavení; pokud platba prošla po chybě, zkontrolujte svou fakturu s Nejvyšší stav Kredity na to.

Než připojíte peněženku

Nymbot ji ukládá zašifrovanou a používá ji pouze k placení svých vlastních faktur, ale vytvořte připojení jen pro to, s výdajovým rozpočtem ve vaší peněžence, takže nejvíce, co kdy mohl zaplatit, je číslo, které jste si vybrali. pay_invoice.

Připojení peněženky

POST https://nymbot.ai/api/v1/nwc-auto-topup/connect A podepsal jsem.

poleTypPožadovánoPopisek
nwc_urlStringovéAnoSpojovací řetězec, počínaje nostr+walletconnect://Nymbot požádá o peněženku get_info před uložením a ukládá je zašifrované.
threshold_satsintegerAnoVyšší, když zůstatek klesne pod tyto mnoho sats. nejméně 1000.
topup_satsintegerAnoKolik přidat pokaždé. 1000 až 1 000 000 sázek.
tierStringovénepro (předpokládané ztráty nebo standard: rovnováha sledovat a nahoru.

Odpověď

{
  "data": {
    "connected": true,
    "threshold_sats": 5000,
    "topup_sats": 20000,
    "tier": "pro",
    "last_topup_at": null,
    "last_topup_sats": null,
    "last_error": null
  }
}
statusuKdy
400Není spojovací řetězec (invalid_nwc_url); peněženka neodpověděla na svůj relé (nwc_unreachable) nebo odmítl kontrolu (nwc_rejected); připojení nemůže platit faktury (nwc_missing_permission(nebo částku mimo omezení.
501Automatické top-upy nejsou pro tento server zapnuté (nwc_unavailableTotéž platí pro ostatní dva koncové body.

cURL

URL=https://nymbot.ai/api/v1/nwc-auto-topup/connect
BODY='{"nwc_url":"nostr+walletconnect://...","threshold_sats":5000,"topup_sats":20000,"tier":"pro"}'
curl "$URL" \
  -H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
  -H "Content-Type: application/json" \
  -d "$BODY"

Python

import json, os
import requests

url = "https://nymbot.ai/api/v1/nwc-auto-topup/connect"
body = json.dumps({
    "nwc_url": os.environ["NWC_URL"],
    "threshold_sats": 5000,
    "topup_sats": 20000,
    "tier": "pro",
}).encode()
res = requests.post(
    url,
    data=body,
    headers={"Authorization": nostr_auth("POST", url, body), "Content-Type": "application/json"},
)
print(res.json())

JavaScript

const url = "https://nymbot.ai/api/v1/nwc-auto-topup/connect";
const body = JSON.stringify({
  nwc_url: process.env.NWC_URL,
  threshold_sats: 5000,
  topup_sats: 20000,
  tier: "pro",
});
const res = await fetch(url, {
  method: "POST",
  headers: { "Authorization": nostrAuth("POST", url, body), "Content-Type": "application/json" },
  body,
});
console.log(await res.json());

Čtení nastavení

GET https://nymbot.ai/api/v1/nwc-auto-topup A podepsal jsem.

Vrátí stejný objekt jako připojení, s connected: false a ostatních polích null Když není připojena žádná peněženka, samotný řetězec připojení se nikdy nevrátí.

cURL

URL=https://nymbot.ai/api/v1/nwc-auto-topup
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/nwc-auto-topup"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json())

JavaScript

const url = "https://nymbot.ai/api/v1/nwc-auto-topup";
console.log(await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json());

Odpojení

DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection A podepsal jsem.

Vymaže uložený řetězec připojení. Žádné další top-upy nejsou vytvořeny. Chcete-li být jisti, můžete také zrušit připojení ve vaší peněžence.

Odpověď

{ "data": { "connected": false, "threshold_sats": null, "topup_sats": null, "tier": null, "last_topup_at": null, "last_topup_sats": null, "last_error": null } }

cURL

URL=https://nymbot.ai/api/v1/nwc-auto-topup/connection
curl -X DELETE "$URL" -H "Authorization: $(nostr_auth DELETE "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/nwc-auto-topup/connection"
print(requests.delete(url, headers={"Authorization": nostr_auth("DELETE", url)}).json())

JavaScript

const url = "https://nymbot.ai/api/v1/nwc-auto-topup/connection";
const res = await fetch(url, { method: "DELETE", headers: { "Authorization": nostrAuth("DELETE", url) } });
console.log(await res.json());

Platba na vyžádání bez klíče

Koncové body s pevnou cenou lze zaplatit za jednu žádost najednou přes Lightning, bez klíče, bez účtu a bez zůstatku: POST /images/generations, POST /images/edits, POST /videos, POST /audio/speech, POST /audio/transcriptions, POST /audio/translations a POST /embeddingsChat, Odpovědi a Zprávy vždy potřebují klíč. Žádost, která nese klíč, je účtována do zůstatku jako obvykle; platební tok začíná pouze tehdy, když není odeslán žádný klíč.

Nymbot mluví dvě verze stejné myšlenky, z jednoho backend: Lightning Labs ' ČT402 (také přijat pod jeho starým jménem, LSATa návrh IETF Platba HTTP autentizační schéma s lightning Metoda a charge Používejte to, co váš zákazník chápe.

Spuštění vlastního serveru

Platit bez klíče je pouze tehdy, když API_L402_SECRET obsahuje alespoň 32 náhodných bajtů, jako je hex (64 znaků) nebo base64 (44). openssl rand -hex 32Krátší nebo odhadovatelná hodnota vypne funkci a zaznamená proč. Chcete-li ji otočit, přesuňte starou hodnotu na API_L402_SECRET_PREVIOUS po dobu jednoho dne: pověření, stavové adresy URL a výzvy provedené pod ním pokračují v práci, dokud nevyprší.

Výzva

Pošlete žádost s NE Authorization header. Pokud je platná, nic nefunguje a dostanete 402 Payment Required s fakturou za přesně to, co tato žádost stojí: stejnou cenu, kterou by klíč zaplatil, převedený na 10 sats na standardní kredit nebo 100 sats na Pro kredit a zaokrouhlený na celý sat (nejméně 1 sat a nejméně 0,05 kreditní minimum). WWW-Authenticate Problémy se stejným účtem:

HTTP/1.1 402 Payment Required
Content-Type: application/problem+json; charset=utf-8
Cache-Control: no-store
WWW-Authenticate: L402 macaroon="AgJC...", invoice="lnbc2370n1..."
WWW-Authenticate: LSAT macaroon="AgJC...", invoice="lnbc2370n1..."
WWW-Authenticate: Payment id="kM9x...", realm="nymbot", method="lightning", intent="charge",
    request="eyJhbW91bnQiOiIyMzciLC...", description="Nymbot API POST /images/generations (237 sats)",
    digest="sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:", expires="2026-09-30T12:15:00.000Z",
    opaque="eyJlbmRwb2ludCI6IlBPU1QgL2ltYWdlcy9nZW5lcmF0aW9ucyJ9"

{
  "type": "https://paymentauth.org/problems/payment-required",
  "title": "Payment Required",
  "status": 402,
  "detail": "This request costs 237 sats. Pay the Lightning invoice, then send the identical request again ...",
  "challengeId": "kM9x...",
  "amount_sats": 237,
  "invoice": "lnbc2370n1...",
  "payment_hash": "9db1370f...",
  "expires_at": "2026-09-30T12:15:00.000Z",
  "error": { "message": "This request costs 237 sats. ...", "type": "payment_required", "code": "payment_required", "param": null }
}

Platba je request Základní parametr je base64url JSON: {"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.

Výzva je vázána na koncový bod, na Content-Type (jeho typ média a, pro více částí, jeho hranice) a na SHA-256 přesných tělesných bajtů, které jste poslali, a trvá 15 minut. identické Další požadavek: stejný Content-Type a stejné JSON bajty, nebo pro multipartové koncové body (/images/edits, /audio/transcriptions, /audio/translationsVětšina HTTP knihoven volí novou hranici pokaždé, když zakódují formulář, takže jej zakódujte jednou a pošlete tyto bajty dvakrát.

Každá adresa může požádat o 30 výzev za minutu (adresa IPv6 se počítá jako celek /64). Žádosti, jejichž adresa není známa, sdílejí přísnější 10 za minutu a existuje celková hranice na výzvy Nymbot problémů napříč všemi adresami; žádost odmítnutá před výzvou je učiněna (například s tělem, které není platné JSON) se k ní nezapočítává. 429 s Retry-AfterPlacené koncové body volané bez klíče nebo pověření se také počítají směrem k obecnému limitu 120 neautentifikovaných žádostí za minutu na adresu. Content-Type Není application/json (nebo multipart/form-data pro uploady) je odmítnuto s 415 Nikdy nedostanete fakturu.

Embeddings jsou ceněny z odhadu tokenů v vstupu, s marginou 1,5 krát, protože skutečný počet je znám až poté. Vrácení tokenu.

Odesílání platby

Zaplatit fakturu s libovolnou Lightning peněženku. Peněženka vám dává předobraz, 64 hexadecimálních znaků. Poté pošlete stejnou žádost s jedním z těchto:

SchémaHeaderová
ČT402Authorization: L402 <macaroon>:<preimage> (LSAT Taky to funguje)
PlatbaAuthorization: Payment <base64url JSON>Kde je JSON {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}}

Placená žádost odpovídá přesně jako ta, která byla učiněna s klíčem, s výjimkou toho, že nymbot Objekt nemá rovnovážná pole: {"payment": "l402", "tier": "pro", "paid_sats": 237, "charged_sats": 237}A není tam žádný X-Nymbot-Balance-Sats Žádost zaplacená prostřednictvím platební schématu také obdrží Payment-Receipt header (base64url JSON s ID výzvy, hash platby jako reference, status a timestampPlacené požadavky nejsou vázány na žádný nym, takže se v historii dotazů nezobrazují.

statusuKdy
402 payment_already_usedKaždá platba platí za jednu žádost. Odpověď je novou výzvou pro tuto žádost, takže klient, který vyrovnává své poslední pověření (jako lnget Jednoduše se opět vrátí k zemi.
402 payment_mismatchNásledně byla vyhláška vydána pro jiný koncový bod. Content-Type nebo tělo, nebo platí méně, než tato žádost nyní stojí. Nová výzva pro tuto žádost přichází s tím; pokud byla platba příliš malá, to, co jste zaplatili, se vrátí jako Vrácení tokenu (refund_token a refund_sats v našem těle).
402 payment_expiredOd této výzvy uplynulo více než 15 minut. Přichází s ní nová výzva. Pokud předobraz ukazuje, že jste zaplatili, vrátí se to, co jste zaplatili. Vrácení tokenu (refund_token a refund_sats v těle), jednou; poté je pověření vyčerpáno.
401 invalid_preimagePředobraz není hash na fakturační platební hash. Platba není použita.
401 invalid_payment_credentialPovolení je nesprávně vytvořené, bylo změněno poté, co ho Nymbot vydal, nebo jmenuje platební hash Nymbot nikdy nevydal fakturu.
429 rate_limit_exceededVíce než 30 pověření nebo klíčů, které se nepodařilo ověřit, přišlo z této adresy během jedné minuty, nebo jeden token na vrácení peněz byl odeslán více než 60krát za minutu. Retry-After.

cURL

BODY='{"model":"nano-banana","prompt":"a lighthouse at dusk","response_format":"b64_json"}'
URL=https://nymbot.ai/api/v1/images/generations

# 1. Get the challenge
CH=$(curl -s -D - -o /dev/null "$URL" -H "Content-Type: application/json" -d "$BODY" | grep -i '^www-authenticate: L402')
MAC=$(echo "$CH" | sed -E 's/.*macaroon="([^"]+)".*/\1/')
INVOICE=$(echo "$CH" | sed -E 's/.*invoice="([^"]+)".*/\1/')

# 2. Pay $INVOICE with your wallet and copy the preimage
PREIMAGE=...

# 3. Send the identical request with the credential
curl "$URL" -H "Content-Type: application/json" -H "Authorization: L402 $MAC:$PREIMAGE" -d "$BODY"

lnget

# lnget (Lightning Labs) pays L402 challenges from your own lnd node and retries for you
lnget -X POST -H "Content-Type: application/json" \
  -d '{"model":"nano-banana","prompt":"a lighthouse at dusk","response_format":"b64_json"}' \
  https://nymbot.ai/api/v1/images/generations

Python

import base64, json, re
import requests

url = "https://nymbot.ai/api/v1/images/generations"
body = json.dumps({"model": "nano-banana", "prompt": "a lighthouse at dusk", "response_format": "b64_json"}).encode()
headers = {"Content-Type": "application/json"}

challenge = requests.post(url, data=body, headers=headers)
assert challenge.status_code == 402
info = challenge.json()
print("Pay", info["amount_sats"], "sats:", info["invoice"])

preimage = pay_with_your_wallet(info["invoice"])  # 64 hex characters

# L402
mac = re.search(r'L402 macaroon="([^"]+)"', challenge.headers["WWW-Authenticate"]).group(1)
res = requests.post(url, data=body, headers={**headers, "Authorization": f"L402 {mac}:{preimage}"})
print(res.json()["nymbot"])

JavaScript

const url = "https://nymbot.ai/api/v1/images/generations";
const body = JSON.stringify({ model: "nano-banana", prompt: "a lighthouse at dusk", response_format: "b64_json" });
const headers = { "Content-Type": "application/json" };

const challenge = await fetch(url, { method: "POST", headers, body });
const www = challenge.headers.get("www-authenticate");

// The Payment scheme: echo every challenge parameter back with the preimage
const start = www.indexOf("Payment ");
const params = Object.fromEntries([...www.slice(start + 8).matchAll(/(\w+)="((?:[^"\\]|\\.)*)"/g)].map((m) => [m[1], m[2]]));
const { invoice } = JSON.parse(Buffer.from(params.request, "base64url").toString()).methodDetails;
const preimage = await payWithYourWallet(invoice);

const credential = Buffer.from(JSON.stringify({ challenge: params, payload: { preimage } })).toString("base64url");
const res = await fetch(url, { method: "POST", headers: { ...headers, Authorization: `Payment ${credential}` }, body });
console.log((await res.json()).nymbot, res.headers.get("payment-receipt"));

Zákazníci jsou postavení na mppx se Lightningovou metodou vypořádat s výzvou Payment sami; ukažte je na koncový bod a nechte je platit.

Videa

a placené POST /videos Odpovědi 202 jako klíčový jeden, plus a status_url: GET To je podepsáno a funguje po dobu 24 hodin, pokud je práce udržována.

{
  "id": "vid_...",
  "status": "in_progress",
  "status_url": "https://nymbot.ai/api/v1/videos/vid_...?exp=1790000000&sig=...",
  "nymbot": {
    "payment": "l402", "tier": "pro", "paid_sats": 4800, "charged_sats": 4800,
    "refund_token": "REFUND-5E0B..."
  }
}

Udržujte si refund_token z této odpovědi: je zobrazen pouze zde. Je prázdný, zatímco video zobrazuje (GET /api/v1/l402/refunds Odpovědi "status": "pending"); pokud render selže bez účtování, platba na něm přistane. refund_sats pro vrácenou práci, ale nikdy token, takže sdílení URL stavu nesdílí vrácení peněz.

Vrácení

Pokud placená žádost selže a poskytovatel účtuje Nymbot za pokus, platba se ponechá a chyba tak říká, s charged_sats, přesně jako pro klíčovou žádost. Pokud selže, aniž by byla fakturována, chyba nese Vrácení tokenu Stojí za to, co jste zaplatili:

{
  "error": {
    "message": "The image generator failed. Nothing was charged. Please try again. The 237 sats you paid are on refund token REFUND-...",
    "type": "api_error",
    "code": "upstream_error",
    "refund_token": "REFUND-0C15DBED145D59131BA70298A413ADEB3D9B9AB082C476EA70A5BD38FCA5DE6D",
    "refund_sats": 237,
    "refund_expires_at": "2026-10-30T12:00:00.000Z"
  }
}

Nepoužité díly se vracejí stejným způsobem: pokud jste požádali o dva obrázky a jeden se nepodařilo vyúčtovat, úspěšná odpověď nymbot objekt nese token na vrácení peněz za chybějící token; transkripce, jejíž délku nelze číst dopředu, je cenována za nejdelší dobu, kterou může být soubor (nikdy více než 30 minut), a rozdíl ve skutečné délce se vrací jako token na vrácení peněz; pokud se ukáže, že je delší než 30 minut, je odmítnut s 413 a celá platba se vrátí.Zahrnutí vrátí to, co odhad držel zpět.Neúspěšné video vrátí token, jehož předložení bylo vráceno.

Token na vrácení peněz je náhodný 256-bitový kód. Nymbot ukládá pouze svůj hash a vyprší po 30 dnech.

  • Zaplaťte s ním. Poslat Authorization: Bearer REFUND-… Na základě výše uvedených údajů (např. na základě výše uvedených údajů) se jedná o výše uvedenou částku (např. na základě výše uvedených údajů).refund_token_sats V tom nymbot Objekt). token v hodnotě menší než odpovědi na požadavky 402 refund_insufficientNeúčtované selhání staví sázku zpět na stejný token.
  • Zkontrolujte si to. GET /api/v1/l402/refunds se stejným headerem se vrací {"sats": 237, "status": "open", "expires_at": "..."}.
  • Jeden token lze použít maximálně 60krát za minutu.
  • Přesuňte ji na nym. Vložte ji do Vyměňte dárek v aplikaci Nymbot nebo volejte POST /api/v1/l402/refunds/redeem S A Podepsaná žádost a {"refund_token": "REFUND-...", "balance": "standard"} (nebo "pro"Celé kredity jdou do zůstatku (10 sázek každý na standard, 100 na Pro); sázky, které nedělají celý kredit zůstat na tokenu pro požadavky API.

cURL

URL=https://nymbot.ai/api/v1/l402/refunds/redeem
BODY='{"refund_token":"REFUND-...","balance":"standard"}'
curl "$URL" \
  -H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
  -H "Content-Type: application/json" \
  -d "$BODY"

Odpověď

{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }