Baza znanja Razvijači
Ravnoteža, top-up i ključevi
Provjerite što imate, nadogradite se preko Lightning-a, nadogradite se automatski iz vlastitog novčanika, vidite koliko košta svaki zahtjev i upravljajte ključima iz koda.
Ova stranica je strojno prevedena radi praktičnosti. Engleski original je verzija koja se primjenjuje.
Proverite ravnotežu
Oba vaša bilance, i koliko je kape ovog ključa se koristi.
GET https://nymbot.ai/api/v1/credits/balance Potreban vam je API ključ. POST Radi i za kupce koji to očekuju.
balance je dva salda zajedno u dolarima po trenutnoj ceni Bitcoina, za alate koji očekuju jedan broj (null ako se cijena ne može pročitati). ostatak je u kreditima i ratama, što je način na koji se ravnoteže zapravo drže. key opisuje ključ koji je zatražen. ključ koji je dostigao svoj limit još uvijek može provjeriti ravnotežu.
Odgovor
{
"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"
}
}
| Status | Kada |
|---|---|
401 | Ključ je nedostajao, nepoznat, opozvan ili istekao. |
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);
Načini plaćanja
Kako možete popuniti, i granice. munja je jedina metoda.
GET https://nymbot.ai/api/v1/topup/payment-methods Nije potreban ključ.
Top-up je 10 do 1.000.000 sats; Pro top-up mora kupiti barem jedan Pro kredit, tako da počinje na 100 sats. bulk_bonus navodi dodatni kredit na većim top-upovima, isti kao u aplikaciji: 10%, 15% ili 20% više na standardnim top-upima od 500, 1.000 ili 5.000 sats, i na Pro top-upima od 5.000, 10.000 ili 50.000 sats.
Odgovor
{
"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);
Uspon preko munje
Napravlja Lightning račun koji dodaje kredit na nym ključ pripada. Plaća ga iz bilo koje Lightning novčanik, a zatim Proverite ga Da biste dobili dodatni kredit.
POST https://nymbot.ai/api/v1/topup/create/btc-lightning Potreban vam je API ključ.
| Polje | Vrste | Potrebno | Opis |
|---|---|---|---|
amount | Broj | Da | Koliko je, u currencyCijeli broj za sats. |
currency | Struktura | Ne | SATS (u slučaju neispunjavanja obaveza), USD ili BTCDolar se pretvara po trenutnoj ceni Bitcoina. |
tier | Struktura | Ne | pro (u slučaju neispunjenja obaveza) ili standard: u koju ravnotežu ide kredit. |
Standardni kredit je 10 sats i Pro kredit 100 sats, plus bilo koji masovni bonus;
credits kaže šta će ovaj račun dodati.
Odgovor
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"payment_request": "lnbc100u1p5...",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": "2026-09-30T09:27:00Z",
"status": "pending"
}
| Status | Kada |
|---|---|
400 | Druga metoda na putu (unsupported_method), nepoznata valuta (unsupported_currency) ili tier, manji iznos, ili iznos ispod minimalnog (amount_too_small), preko 1 000 000 sats (amount_too_large) ili odbijen od strane Lightning novčanika (amount_out_of_range). |
429 | Više od 60 faktura za ovaj nimm, ili 120 sa ove adrese, u satu (rate_limit_exceeded, sa Retry-After). |
502 | U ovom trenutku nije moguće izraditi račun (invoice_unavailable, sa 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);
Provjerite top-up
Pita da li je faktura plaćena i, kada je, dodaje kredit. Provjera je ono što je kredit, tako da nakon plaćanja, provjerite dok status nije creditedProvjeravanje ponovo nakon toga je sigurno: kredit se sleti jednom, bez obzira na to koliko puta tražite.
GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - treba ključ od nim koji je napravio fakturu.
status je pending (Još uvek nije plaćena) paid (plaćen, ali još nije kreditiran; provjerite ponovo), credited (na vašoj ravnoteži) ili expired (ne plaća se na vrijeme). Polja bilance su za razinu na kojoj se računi vrše.
Odgovor
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"status": "credited",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": null,
"balance_credits": 523.33,
"balance_sats": 52333
}
| Status | Kada |
|---|---|
400 | ID nije 64-karakterski id iz poziva za kreiranje. |
404 | Nema računa za taj id za vaš nim (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);
Želite istoriju
Jedan red po zahtjevu: šta je to bilo, koji model, koliko tokena i koliko košta. Ne zadržavaju se upite ili odgovori, tako da se nijedan ne vraća. Redovi se čuvaju 90 dana, najnovije prvo. Ključ koji je dostigao svoju granicu još uvijek može pročitati svoju istoriju.
GET https://nymbot.ai/api/v1/queries/history — treba API ključ, koji vidi vlastite zahteve, ili Potpisani zahtev od vašeg nim, koji vidi svaki ključ.
| Polje | Vrste | Potrebno | Opis |
|---|---|---|---|
page | Uslovi korišćenja (query) | Ne | Podrazumevano 1, najviše 1000; viša stranica je 400 invalid_value. |
page_count | Uslovi korišćenja (query) | Ne | Redovi po stranici. Podrazumevano 20, najviše 100. |
start_dateend_date | String (preuzimanje pitanja) | Ne | ISO 8601 datumi ili vremena. |
model | String (preuzimanje pitanja) | Ne | Samo ovaj model. |
type | String (preuzimanje pitanja) | Ne | chat, responses, messages, image, video, speech, transcription ili embedding. |
all_keys | Uslovi korišćenja (query) | Ne | Uz jedan ključ: true uključuje svaki ključ istog nym. podrazumevano false. |
key_id | String (preuzimanje pitanja) | Ne | Uz potpisan zahtjev, ili all_keys=trueSamo ovaj ključ. |
Odgovor
{
"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);
Potpisivanje zahteva za račun
Stvaranje, promjena i opoziv ključeva, sažetak računa i automatski top-up ne uzimaju API ključ. Oni uzimaju potpis od vašeg nym, tako da ispušten ključ može potrošiti do svoje kapije, ali nikada ne može napraviti drugi ključ ili podići svoj kapije.
Aplikacija radi ovo za vas: sve u svom vatra Ovaj odjeljak je potreban samo da biste upravljali ključima iz vlastitog koda.
Potpis je Nostr događaj vrste 27235 (NIP-98), poslan baz64-kodiran u
Authorization Header sa rečju Nostr Na prednjem delu:
događaj
{
"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": "..."
}
uje potpuni URL zahtjeva, uključujući niz upita, tačno kao što je poslan.methodTo je HTTP metoda.payloadje SHA-256 sirovog zahteva tijela, u hex.POSTiPATCH, a tijelo koje šaljete mora biti bajt za bajt ono što ste hashed.created_atmora biti u roku od 60 sekundi od sata servera.- Svaki događaj radi jednom, a
GETuključen, tako da se zabeležena glava ne može ponovo igrati. Potpišite novu za svaki zahtev.nonceTag sa slučajnom vrijednošću tako da se dva zahteva potpisana u istoj sekundi i dalje razlikuju. - Tijelo potpisanog zahtjeva može biti najviše 64 KB, a tijelo treba
Content-Type: application/json.
Nedostajući događaj se vraća 401 missing_nostr_auth; jedan koji je loše formiran, loše potpisan, previše star, ili za drugačiji URL, metod ili tijelo vraća
invalid_nostr_auth, s razlogom u poruci; ponovno korišten jedan vraća
nostr_auth_replayedPotpis se provjerava pre nego što se tijelo pročita, a svaka adresa može da ga ne uspije 30 puta u minuti (IPv6 adresa se računa kao cijela /64); nakon toga dobija 429 sa
Retry-After.
Pregledači mogu pozvati ove krajnje tačke samo sa Nymbotovih sopstvenih stranica (https://nymbot.ai,
https://nymchat.app Stranica na bilo kojoj drugoj stranici ne dobija CORS glave natrag, tako da ne može pročitati ono što vraćaju.
OriginOni nisu pogođeni.
Potpisivanje treba tajni ključ vašeg nyma (na nsec), koji kontrolira sve: vaš identitet, vašu istoriju i vašu bilancu. Samo ga stavite u skript na mašini kojoj verujete, pročitajte ga iz okoline umjesto da ga napišete u datoteku, i preferirajte aplikaciju kada možete.
Ovi pomoćnici grade glavu. Kasniji primjeri na ovoj stranici koriste ih. Oni čitaju tajni ključ u šestom redu iz NOSTR_SECRET_HEX; cURL jedan koristi
Neki alat za komandnu liniju, koji uzima nsec ili hex ključ, i sha256sum za 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");
}
Sažetak računa
Šta API list aplikacije prikazuje na vrhu: vaš javni ključ, oba balansira, koliko ključeva je aktivno (nije opozvano ili je istekao), i Automatski top-up postavljanje, ili
null kada ih server ne nudi.
GET https://nymbot.ai/api/v1/account Potrebno je a Potpisani zahtev.
Odgovor
{
"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());
Upravljanje ključima
Krajnje tačke iza liste ključa aplikacije. Svi oni trebaju Potpisani zahtevSvaki ključ se vraća u ovom obrascu, sa vremenima u ISO 8601 i iznosima u sats:
Ključni objekti
{
"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 To je dovoljno da prepoznate ključ, ali ne i da ga koristite, a sam ključ se vraća samo jednom, kada je napravljen.
Ključne reči
GET https://nymbot.ai/api/v1/keys Potpisan je.
| Polje | Vrste | Potrebno | Opis |
|---|---|---|---|
include_revoked | Uslovi korišćenja (query) | Ne | Uključuje poništene ključeve. podrazumevano false. |
Odgovor
{ "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);
Stvaranje ključa
POST https://nymbot.ai/api/v1/keys Povratak - povratak 201.
| Polje | Vrste | Potrebno | Opis |
|---|---|---|---|
name | Struktura | Da | 1 do 40 znakova, različiti od vaših drugih aktivnih ključeva (ignoring slučaj). |
limit_sats | Integracija | Ne | Potrošnja kap u sats, najmanje 1. ostavite ga bez kap. |
reset_period | Struktura | Ne | daily, weekly ili monthlyPotrebe limit_satsOstavite ga za kapu koja se nikada ne ponavlja. |
expire_at | String ili integer | Ne | Kada ključ prestane raditi: ISO 8601 puta, ili milisekundama od 1970. |
Odgovor na pitanje (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"
}
}
| Status | Kada |
|---|---|
400 | Nedostatak ili previše dugo ime; ime već u upotrebi (duplicate_name); cap koji nije čitav broj od najmanje 1; reset period bez cap; istek u prošlosti; nepoznato polje (unknown_parameter); ili 25 aktivnih ključeva već (too_many_keys). |
429 | Više od 60 ključeva napravljenih ovom nimom, ili 120 od ove adrese, u satu (rate_limit_exceeded, sa 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);
Čitanje jednog ključa
GET https://nymbot.ai/api/v1/keys/{id} Potpisan je.
Povratak {"data": {…}} sa ključnim predmetom, ili 404
key_not_found ako vaš ključ nema taj 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);
Promena ključa
PATCH https://nymbot.ai/api/v1/keys/{id} Potpisan je.
Pošaljite bilo koju name, limit_sats, reset_period i
expire_at, sa istim pravilima kao i prilikom pravljenja ključa. null Izbriše polje: nema ograničenja, nema resetovanja, nema isteka. Promjena perioda resetovanja započinje novi period na nuli.400 key_revoked• Povratak
{"data": {…}} sa ažuriranim ključnim objektom.
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);
Otkazivanje ključa
DELETE https://nymbot.ai/api/v1/keys/{id} Potpisan je.
Zaustavlja ključ odjednom, za dobro. ostaje na listi sa revoked_at postavljen, a može se vidjeti sa include_revoked=truePovlačenje ključa koji je već povučen odgovara na isti način. Samo se zadržava 50 najnovijih povučenih ključa; stariji ključi se brišu kada se povuče drugi ključ.
Odgovor
{ "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 uređaji
Povežite Lightning novčanik sa Nostr Wallet Connect i Nymbot samostalno podiže ravnotežu kada troškovi API-ja budu niski. API list aplikacije ima iste postavke; to su krajnje točke iza njega. Potpisani zahtev.
Kako to funkcioniše: nakon što se API zahtjev naplaćuje na saldo koji ste odabrali da gledate, ako je taj saldo pao ispod vašeg praga, Nymbot napravi fakturu za vaš top-up iznos, traži od vašeg novčanika da ga plati i dodaje kredit. To se popne najviše jednom svakih 5 minuta za svaki nym i saldo, tako da izbijanje zahteva ne može isprazniti novčanik. Trošenje u aplikacijama ga ne pokreće. Vrijeme i veličina posljednjeg top-up, i posljednja greška, su u postavkama; ako je plaćanje prošlo nakon greške, provjerite njegovu fakturu sa Top-up situacija Krediti za to.
Nymbot ga skladišti šifrovanim i samo ga koristi za plaćanje vlastitih računa, ali napravite vezu samo za to, sa budžetom za potrošnju u novčaniku, tako da je najviše što bi ikada moglo platiti broj koji ste odabrali. pay_invoice.
Povezivanje novčanika
POST https://nymbot.ai/api/v1/nwc-auto-topup/connect Potpisan je.
| Polje | Vrste | Potrebno | Opis |
|---|---|---|---|
nwc_url | Struktura | Da | Struktura poveznice, početak nostr+walletconnect://Nymbot traži novčanik za get_info prije nego što ga sačuvate, a skladišti ga šifrirano. |
threshold_sats | Integracija | Da | Top up kada ravnoteža padne ispod ovih mnogo sats. |
topup_sats | Integracija | Da | Koliko da dodam svaki put. 1000 do 1.000.000 sats. |
tier | Struktura | Ne | pro (u slučaju neispunjenja obaveza) ili standard: ravnoteža za gledanje i top up. |
Odgovor
{
"data": {
"connected": true,
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
"last_topup_at": null,
"last_topup_sats": null,
"last_error": null
}
}
| Status | Kada |
|---|---|
400 | nije povezan sa mrežnom mrežom (invalid_nwc_url); novčanik nije odgovorio na svoj relej (nwc_unreachable) ili odbio kontrolu (nwc_rejected); veza ne može platiti račune (nwc_missing_permission); ili iznos izvan granica. |
501 | Auto-top-up nije uključen za ovaj server (nwc_unavailableIsto vrijedi i za druge dvije krajnje točke. |
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());
Čitanje postavki
GET https://nymbot.ai/api/v1/nwc-auto-topup Potpisan je.
Vraća isti objekt kao povezivanje, sa connected: false i ostala polja
null kada nema povezanog novčanika. Sam lanac veze se nikada ne vraća.
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());
Isključivanje
DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection Potpisan je.
Brisanje skladištenog niza veza. Ne kreira se više top-up. Da biste bili sigurni, takođe možete opozvati vezu u novčaniku.
Odgovor
{ "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());
Plaćanje po zahtevu bez ključa
Krajnje točke fiksne cene mogu se platiti za jedan zahtev u jednom trenutku preko Lightning-a, bez ključa, bez računa i bez salda: POST /images/generations, POST /images/edits,
POST /videos, POST /audio/speech, POST /audio/transcriptions,
POST /audio/translations i POST /embeddingsChat, odgovori i poruke uvek trebaju ključ.Zahtjev koji nosi ključ obračunava se na saldo kao i obično; tok plaćanja počinje samo kada nije poslan ključ.
Nymbot govori dve verzije iste ideje, iz jednog backend: Lightning Labs'
Struktura402 (takođe prihvaćen pod svojim starim imenom, LSAT) i nacrta IETF
Plaćanje HTTP autentifikacioni sistem sa lightning Metoda i
charge Koristite ono što vaš kupac razumije.
Plaćanje bez ključa je uključeno samo kada API_L402_SECRET sadrži najmanje 32 slučajne bajte, kao što su hex (64 znakova) ili base64 (44). openssl rand -hex 32Kratka ili nagađajuća vrijednost isključuje funkciju i bilježi zašto. API_L402_SECRET_PREVIOUS za jedan dan: akreditacije, status URL-ovi i izazovi pod njim nastaviti raditi dok ne istekne.
izazov
Pošaljite zahtjev sa ne Authorization ako je važeća, ništa ne radi, a dobijate 402 Payment Required sa fakturom za točno ono što traži troškove: istu cenu ključ bi platio, pretvoren u 10 sats standardni kredit ili 100 sats Pro kredit i zaokružen na cijeli sat (najmanje 1 sat, a najmanje 0.05 kredit minimum). WWW-Authenticate izazovi za istu fakturu:
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 }
}
Plaćanje request parametar je base64url JSON:
{"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.
Izazov je vezan za krajnju tačku, za Content-Type (njegova vrsta medija i, za više dijelova, njegova granica) i na SHA-256 tačnog tela bajtova koje ste poslali, i traje 15 minuta. identične Ponovno upućivanje: isto
Content-Type i iste JSON bajte, ili za višestruke krajnje tačke (/images/edits, /audio/transcriptions, /audio/translationsVećina HTTP biblioteka odabire novu granicu svaki put kada kodiraju obrazac, pa ga kodirajte jednom i pošaljite te bajte dva puta.
Svaka adresa može zatražiti 30 izazova po minuti (IPv6 adresa se računa kao cijela /64). Zahtjevi čija adresa nije poznata dijele strože 10 po minuti, i postoji ukupni limit na izazove Nymbot problema u svim adresama; zahtjev odbijen pre nego što je izazov napravljen (na primjer, sa tijelom koji nije valjan JSON) ne računa prema njemu. 429 sa Retry-AfterPlaćene krajnje točke poziva bez ključa ili povjerenja takođe se računaju prema općem ograničenju od 120 neautentificiranih zahtjeva po minuti po adresi. Content-Type nije application/json ili
multipart/form-data za upload) je odbijen sa 415 i nikada ne dobija račun.
Ugradnje su cijenjene na osnovu procjene tokena u ulazu, sa marginom od 1,5 puta, budući da je stvarni broj poznat tek nakon toga. Povratak tokena.
Slanje plaćanja
Plaćanje računa sa bilo koji Lightning novčanik. Novčanik vam daje predobrazbu, 64 šezdeset znakova. Zatim pošaljite isti zahtjev s jednim od ovih:
| Šeme | Glavni |
|---|---|
| Struktura402 | Authorization: L402 <macaroon>:<preimage> (LSAT takođe radi) |
| Plaćanje | Authorization: Payment <base64url JSON>, gde je JSON {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}} |
Plaćen zahtjev odgovara baš kao onaj koji je napravljen s ključem, osim da je nymbot
objekat nema polja ravnoteže: {"payment": "l402", "tier": "pro", "paid_sats": 237,
"charged_sats": 237}, a ne postoji X-Nymbot-Balance-Sats Zahtjev koji se plaća pomoću sheme plaćanja dobija i Payment-Receipt glava (base64url JSON sa id izazova, hash plaćanja kao reference, status i
timestampPlaćeni upiti nisu vezani za nijedan nim, tako da se ne pojavljuju u istoriji upita.
| Status | Kada |
|---|---|
402 payment_already_used | Svaki plaćanje plaća za jedan zahtev. odgovor je novi izazov za ovaj zahtev, tako da klijent koji cache svoje posljednje povjerljivosti (kao lnget Da) jednostavno zemlja opet. |
402 payment_mismatch | Kredencijal je izdan za drugu krajnju točku, Content-Type ili tijelo, ili plaća manje nego što ovaj zahtjev sada košta. Novi izazov za ovaj zahtev dolazi s njim; ako je plaćanje bilo premalo, ono što ste platili vraća se kao Povratak tokena (refund_token i refund_sats u svom telu). |
402 payment_expired | Više od 15 minuta je prošlo od izazova. Novi izazov dolazi s njim. Ako predobraza pokazuje da ste platili, ono što ste platili vraća se kao Povratak tokena (refund_token i refund_sats u tijelu), jednom; tada se kredencijal iskoristi. |
401 invalid_preimage | Preobrazba ne hash računa plaćanja hash. plaćanje se ne koristi. |
401 invalid_payment_credential | Povjerljivost je deformirana, promijenjena nakon što ju je izdao Nymbot, ili imena za plaćanje za koje Nymbot nikada nije izdao fakturu. |
429 rate_limit_exceeded | Više od 30 akreditacija ili ključeva koji nisu bili verifikovani došli su s ove adrese u minuti, ili je jedan token za vraćanje poslao više od 60 puta u minuti. 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"));
Klijenti su izgrađeni na mppx sa Metoda munje rukovati izazov plaćanja sami; Pokaži ih na krajnju tačku i pusti ih da plate.
Video snimci
Plaćanje POST /videos Odgovori 202 kao ključ jedan, plus a
status_url: GET bez ikakvog ključa za praćenje posla. Potpisan je i radi 24 sata, sve dok se posao drži.
{
"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..."
}
}
Održavajte refund_token od ovog odgovora: to je prikazano samo ovdje. To je prazno dok video prikazuje (GET /api/v1/l402/refunds Odgovori "status": "pending"); ako se render ne napravi bez računa, plaćanje će sletjeti na njega.
refund_sats za vraćeni posao, ali nikada žeton, tako da dijeljenje statusa URL-a ne dijeli povrat.
Povratak
Ako plaćeni zahtjev ne uspije i davatelj je naplaćivao Nymbot za pokušaj, plaćanje se zadržava i greška kaže da je tako, sa charged_sats, baš kao i kod ključanog zahtjeva. Ako ne uspije bez obračuna, greška nosi Povratak tokena Vredi ono što ste platili:
{
"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"
}
}
Neiskorišćeni dijelovi se vraćaju na isti način: ako ste zatražili dvije slike, a jedna nije bila obračunata, odgovor je uspješan. nymbot objekt nosi token za povrat novca za nedostajući; transkripcija čija se dužina ne može pročitati unaprijed je cijenjena za najduže što datoteka može biti (nikada više od 30 minuta), a razlika do stvarne dužine vraća se kao token za povrat novca; ako se ispostavi da je duža od 30 minuta, to se odbija sa 413
i cela isplata se vraća. Ugradnje vraćaju ono što je procjena zadržala. Neuspjeli video vraća token njegovu podnesku vratio.
Token za povrat novca je slučajni 256-bitni kod. Nymbot pohranjuje samo svoj haš, a isteče nakon 30 dana.
- Plaćajte s njim. Pošaljite
Authorization: Bearer REFUND-…U svakom slučaju, potrebno je imati na umu da je to jedan od najvažnijih faktora koji se odnose na ljudsko zdravlje, a koji se odnosi na zdravlje ljudi (refund_token_satsU ovomnymbotobjekat). žeton vrijedi manje od odgovora na upit402refund_insufficient; neispravan neuspjeh stavlja sats natrag na isti token. - Provjerite ga.
GET /api/v1/l402/refundsIsti header se vraća{"sats": 237, "status": "open", "expires_at": "..."}. - Jedan token može se koristiti najviše 60 puta u minuti.
- Premjestite ga u nym. Stavite ga u Oporavak poklona u aplikaciji Nymbot, ili pozovite
POST /api/v1/l402/refunds/redeemsa a Potpisani zahtev i{"refund_token": "REFUND-...", "balance": "standard"}ili"pro"Cijeli krediti idu na ravnotežu (10 sats svaki na standard, 100 na Pro); sats koji ne čine čitav kredit ostaje na žetonu za API zahteve.
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"
Odgovor
{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }