Baza znanja Razvijatelji
Ravnoteža, top-up i ključevi
Provjerite što imate, nadoknadite Lightning, automatski nadoknadite iz vlastitog novčanika, pogledajte što svaki zahtjev košta i upravljajte ključima iz koda.
Ova stranica je strojno prevedena radi praktičnosti. Engleski izvornik je verzija koja se primjenjuje.
Provjerite ravnotežu
Oba vaša ravnoteža, i koliko se koristi poklopac ovog ključa.
GET https://nymbot.ai/api/v1/credits/balance Treba vam ključ od vatre. POST Također radi, za kupce koji to očekuju.
balance je dvije ravnoteže zajedno u dolarima po trenutnoj cijeni Bitcoina, za alate koji očekuju jedan broj (null ako se cijena ne može čitati). ostatak je u kreditima i ratama, što je način na koji se ravnoteže zapravo drže. key Ključ koji je dosegao svoju granicu 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 nadmašiti, 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 Prikazuje 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, a 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);
Slijedeći članakTopping Up Over Lightning
Napravi Lightning račun koji dodaje kredit na nym ključ pripada. Provjerite ga Treba dodati i kredit.
POST https://nymbot.ai/api/v1/topup/create/btc-lightning Treba vam ključ od vatre.
| polje | Vrsta | Potrebno | Opis |
|---|---|---|---|
amount | Broj | Da | Koliko je, u currencyCijeli broj za stavku. |
currency | String | Ne | SATS (u slučaju neispunjenja obveze) USD ili BTCDolar se pretvara po trenutnoj cijeni Bitcoina. |
tier | String | Ne | pro (u slučaju neispunjenja obveze) ili standard: u kojoj je ravnoteži kredit. |
Standardni kredit je 10 stotina i Pro kredit 100 stotina, plus bilo koji bonus.
credits Riječ je o tome što će taj 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(b) iznos koji je manji od iznosa koji je manji od iznosa koji je manji od iznosa koji je manji od iznosa koji je manji od iznosa koji je manji od iznosa koji je manji)amount_too_small(više od 1 milijun kuna)amount_too_large) ili odbijen od strane Lightning novčanika (amount_out_of_range). |
429 | Više od 60 računa za ovaj nimm, ili 120 s ove adrese, u satu (rate_limit_exceeded, s Retry-After). |
502 | U ovom trenutku nije moguće izraditi račun (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);
Provjerite top-up
Pita je li račun plaćen i, kada ga ima, dodaje kredit. Provjera je ono što ga kreditira, pa nakon plaćanja, provjerite dok status nije creditedProvjeravanje ponovno 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 račun.
status je pending (Još uvijek nije plaćena) paid (plaćeno, ali još nije kreditirano; provjerite ponovno), credited (na vašoj ravnoteži) ili expired (ne plaća se na vrijeme). polja ravnoteže su za razinu na kojoj se računi popunjavaju.
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-znamenski id iz poziva za stvaranje. |
404 | Nema računa za taj id za vašim nimom (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 povijest
Jedan red po zahtjevu: što je to bilo, koji model, koliko žetona i što košta. Ne zadržavaju se upute ili odgovori, tako da se nitko ne vraća. Redovi se čuvaju 90 dana, najnovije prvo. Ključ koji je dosegao svoju granicu još uvijek može pročitati svoju povijest.
GET https://nymbot.ai/api/v1/queries/history - treba API ključ, koji vidi vlastite zahtjeve, ili Potpisani zahtjev od vašeg nimma, koji vidi svaki ključ.
| polje | Vrsta | Potrebno | Opis |
|---|---|---|---|
page | Sljedeći Članak Integer (query) | Ne | Podrazumijevanje 1, najviše 1000; viša stranica je 400 invalid_value. |
page_count | Sljedeći Članak Integer (query) | Ne | Redovi po stranici. podrazumijevanje 20, na najviše 100. |
start_dateend_date | String (zahtjev za upit) | Ne | ISO 8601 datum ili vrijeme. |
model | String (zahtjev za upit) | Ne | Samo ovaj model. |
type | String (zahtjev za upit) | Ne | chat, responses, messages, image, video, speech, transcription ili embedding. |
all_keys | Sljedeći Članak Boolean (query) | Ne | Uz jedan ključ: true uključuje svaki ključ istog nym. false. |
key_id | String (zahtjev za upit) | Ne | Uz potpisani zahtjev, ili s 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 zahtjeva za račun
Stvaranje, mijenjanje i opoziv ključeva, sažetak računa i automatski top-up ne uzimaju API ključ.
Aplikacija radi ovo za vas: sve u svom vatra Ovaj odjeljak je potreban samo za upravljanje ključima iz vlastitog koda.
Potpis je Nostr događaj vrste 27235 (NIP-98), koji se šalje baz64-kodiran u
Authorization Header s riječju Nostr Na prednjem mjestu:
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 cijeli URL zahtjeva, uključujući niz upita, točno onako kako je poslan.methodTo je HTTP metoda.payloadje SHA-256 sirovog tijela zahtjeva, 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 poslužitelja.- Svaki događaj djeluje jednom, a
GETuključena, tako da se zabranjena glava ne može ponovno igrati. Potpišite novu za svaki zahtjev.nonceoznačite slučajnom vrijednošću tako da se dva zahtjeva 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, metodu ili tijelo vraća
invalid_nostr_auth, s razlogom u poruci; ponovno korišten jedan vraća
nostr_auth_replayedPotpis se provjerava prije nego što se tijelo pročita, a svaka adresa može propustiti 30 puta u minuti (IPv6 adresa se računa kao cijela /64); nakon toga dobiva 429 s
Retry-After.
Browseri mogu nazvati ove krajnje točke samo s vlastitih web-mjesta Nymbota (https://nymbot.ai,
https://nymchat.app Stranica na bilo kojoj drugoj stranici ne dobiva povratne glave CORS-a, tako da ne može pročitati ono što vraćaju.
OriginNe utječu na njih.
Potpisivanje zahtijeva tajni ključ vašeg nyma (tzv. nsec), koji kontrolira sve: vaš identitet, vašu povijest i vašu bilancu. Samo ga stavite u skript na stroju kojem vjerujete, pročitajte ga iz okoline umjesto da ga napišete u datoteku, i preferirajte aplikaciju kada možete.
Ovi pomoćnici izrađuju glavu. Kasniji primjeri na ovoj stranici koriste ih. NOSTR_SECRET_HEX; cURL jedan koristi
Nak alat za zapovjedni red, koji uzima nsec ili hex ključ, i sha256sum na macOSu, 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
Što API list aplikacije prikazuje na vrhu: vaš javni ključ, oba balansira, koliko ključeva je aktivno (nije opozvano ili nije isteklo) i Automatski top-up postavke, ili
null kada ih poslužitelj ne pruža.
GET https://nymbot.ai/api/v1/account Potrebno je a Potpisani zahtjev.
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 točke iza popisa ključeva aplikacije. svi oni trebaju Potpisani zahtjevSvaki ključ se vraća u ovom obliku, s vremenima u ISO 8601 i iznosima u sats:
Ključni predmet
{
"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 Dovoljno je prepoznati ključ, ali ne i upotrijebiti ga.
Popis ključeva
GET https://nymbot.ai/api/v1/keys Potpisan je.
| polje | Vrsta | Potrebno | Opis |
|---|---|---|---|
include_revoked | Sljedeći Članak Boolean (query) | Ne | Uključuje poništene ključeve. 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);
Napraviti ključ
POST https://nymbot.ai/api/v1/keys Povratak – povratak 201.
| polje | Vrsta | Potrebno | Opis |
|---|---|---|---|
name | String | Da | 1 do 40 znakova, koji se razlikuju od ostalih aktivnih ključeva (ignoriranje slučaja). |
limit_sats | integer | Ne | Potrošni kap u sats, najmanje 1. ostavite ga bez kap. |
reset_period | String | Ne | daily, weekly ili monthlyPotrebe limit_satsOstavite ga za kapu koja se nikada ne ponavlja. |
expire_at | String ili integer | Ne | Kada ključ prestaje raditi: ISO 8601 vrijeme, ili milisekundi 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 uporabi (duplicate_name); kap koji nije cijeli broj od najmanje 1; razdoblje ponovnog postavljanja bez kapi; isteak 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 s ove adrese, u satu (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);
Čitanje jednog ključa
GET https://nymbot.ai/api/v1/keys/{id} Potpisan je.
Povratak {"data": {…}} s ključnim predmetom, ili 404
key_not_found ako nijedan od vaših ključa 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);
Promjena ključa
PATCH https://nymbot.ai/api/v1/keys/{id} Potpisan je.
Pošaljite bilo koju name, limit_sats, reset_period i
expire_atIsti postupak kao i kod postavljanja ključa. null Izbjegavajte promjenu polja: nema ograničenja, nema ponovnog postavljanja, nema isteka. Promjena razdoblja ponovnog postavljanja započinje novo razdoblje na nuli.400 key_revoked) Povratak
{"data": {…}} s ažuriranim ključnim predmetom.
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 popisu s revoked_at Sastavljen je i može se vidjeti 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());
Sljedeći članakNWC Auto-top-up
Povežite Lightning novčanik s Nostr Wallet Connect i Nymbot samostalno podiže ravnotežu kada je trošak API-ja nizak. Potpisani zahtjev.
Kako to funkcionira: nakon što se API zahtjev naplaćuje na saldo koji ste odabrali za gledanje, ako je taj saldo pao ispod vašeg praga, Nymbot izdaje račun 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 zahtjeva ne može isprazniti novčanik. Trošenje u aplikacijama ga ne pokreće. Vrijeme i veličina posljednjeg top-up i posljednje pogreške su u postavkama; ako je plaćanje prošlo nakon pogreške, provjerite svoj račun s Top-up status Krediti za to.
Nymbot ga pohranjuje šifrirano i samo ga koristi za plaćanje vlastitih računa, ali napravite vezu samo za to, s proračunom potrošnje 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 | Vrsta | Potrebno | Opis |
|---|---|---|---|
nwc_url | String | Da | Poveznica, počevši od nostr+walletconnect://Nymbot traži novčanik za get_info prije nego što ga sačuvate i pohranite ga šifrirano. |
threshold_sats | integer | Da | Top up kada ravnoteža padne ispod ovih mnogo sats. |
topup_sats | integer | Da | Koliko da dodam svaki put. 1000 do 1.000.000 sats. |
tier | String | Ne | pro (u slučaju neispunjenja obveze) 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 | ne smije biti povezan s mrežom (invalid_nwc_url); novčanik nije odgovorio na svoj prijenos (nwc_unreachable) ili odbio provjeru (nwc_rejected); poveznica ne može platiti račune (nwc_missing_permission3) ili iznos koji je izvan granica. |
501 | Automatski top-up nije uključen za ovaj poslužitelj (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, s connected: false i ostala polja
null kada nema povezanog novčanika. Sam lanac povezanosti nikada se 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 poveznica. Više se ne stvaraju top-ups. Da biste bili sigurni, također možete povući poveznicu 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 na zahtjev bez ključa
Krajnje točke fiksne cijene mogu se platiti za jedan zahtjev u jednom trenutku tijekom 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 uvijek trebaju ključ.Zahtjev koji nosi ključ obračunava se na saldo kao i obično; protok plaćanja počinje samo kada nije poslan ključ.
Nymbot govori dvije verzije iste ideje, iz jednog backend: Lightning Labs'
L402 (također prihvaćena pod svojim starim imenom, LSAT) i nacrt IETF-a
Plaćanje HTTP autentifikacijski sustav s lightning Metoda i
charge Koristite ono što vaš klijent razumije.
Plaćanje bez ključa je uključeno samo kada API_L402_SECRET sadrži najmanje 32 slučajna bajta, kao što su hex (64 znakova) ili base64 (44). openssl rand -hex 32Kratka ili nagađajuća vrijednost isključuje značajku i bilježi zašto. API_L402_SECRET_PREVIOUS za jedan dan: povjerljivosti, statusni URL-ovi i izazovi pod njim nastavljaju raditi dok ne isteknu.
Izazov
Pošaljite zahtjev s ne Authorization ako je valjana, ništa ne radi, a dobivate 402 Payment Required s računom za točno ono što traži troškove: istu cijenu 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 kreditni minimum). WWW-Authenticate Izazovi za isti račun:
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 povezan s krajnjom točkom, s Content-Type (njegov tip medija i, za više dijelova, njegova granica) i na SHA-256 točnih bajtova tijela koje ste poslali, i traje 15 minuta. identična Ponovno zahtjev: isto
Content-Type i iste JSON bajte, ili za višestruke krajnje točke (/images/edits, /audio/transcriptions, /audio/translationsVećina HTTP knjižnica 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, a postoji opći limit na izazove Nymbot problema u svim adresama; zahtjev odbijen prije izazova (na primjer s tijelom koje nije valjan JSON) ne računa prema njemu. 429 s Retry-AfterPlaćene krajnje točke poziva bez ključa ili povjerenja također se računaju prema općem ograničenju od 120 neovjerljivih zahtjeva po minuti po adresi. Content-Type Nije application/json ( ili
multipart/form-data za uvođenje) je odbijen s 415 Nikada ne dobivaju račun.
Ugradnje se cijene na temelju procjene žetona u ulazu, s marginom od 1,5 puta, budući da je stvarni broj poznat tek nakon toga. Povratak tokena.
Slanje plaćanja
Plaćanje računa s bilo kojim Lightning novčanik. novčanik vam daje predobrazbu, 64 hex znakova. Zatim pošaljite isti zahtjev s jednim od ovih:
| Sustav | Header |
|---|---|
| L402 | Authorization: L402 <macaroon>:<preimage> (LSAT također djeluje) |
| Plaćanje | Authorization: Payment <base64url JSON>Gdje je JSON {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}} |
Plaćeni zahtjev odgovara baš kao onaj koji je napravljen s ključem, osim da je nymbot
Objekt nema polja ravnoteže: {"payment": "l402", "tier": "pro", "paid_sats": 237,
"charged_sats": 237}I postoji ne X-Nymbot-Balance-Sats Zahtjev koji se plaća pomoću sheme plaćanja također dobiva Payment-Receipt glava (base64url JSON s idom izazova, hash plaćanja kao reference, status i
timestampPlaćeni zahtjevi nisu vezani za nijedan nim, tako da se ne pojavljuju u povijesti upita.
| Status | Kada |
|---|---|
402 payment_already_used | Svaki plaćanje plaća za jedan zahtjev. odgovor je novi izazov za ovaj zahtjev, tako da klijent koji cache svoje posljednje povjerljivosti (kao lnget Jednostavno, ponovno je zemlja. |
402 payment_mismatch | Vjerodostojnost je izdana za drugu krajnju točku, Content-Type ili tijelo, ili platiti manje nego što ovaj zahtjev sada košta. Novi izazov za ovaj zahtjev dolazi s njim; ako je plaćanje bilo premalo, ono što ste platili vraća se kao Povratak tokena (refund_token i refund_sats i u tijelu). |
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; vjerodostojnost se zatim iskoristi. |
401 invalid_preimage | Prethodna slika ne hash računa plaćanja hash. plaćanje se ne koristi. |
401 invalid_payment_credential | Povjerljivost je nepravilno oblikovana, promijenjena nakon što ju je Nymbot izdao, ili naziva plaćanje hash Nymbot nikada nije izdao račun za. |
429 rate_limit_exceeded | Više od 30 povjerljivosti ili ključeva koji nisu uspjeli provjeriti došli su s ove adrese u minuti, ili je jedan token za povrat 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 pomoću Metode munje sami rješavaju izazove plaćanja; uputite ih na krajnju točku i pustite ih da plaćaju.
Videozapisi
Plaćanje POST /videos odgovori 202 kao ključ jedan, plus a
status_url: GET To je potpisano 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..."
}
}
Držite ga refund_token Sljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći (GET /api/v1/l402/refunds odgovori "status": "pending"); ako render ne uspije ne računati, plaćanje slijetanje na njega.
refund_sats za povrat posla, ali nikada žetona, tako da dijeljenje URL-a statusa ne dijeli povrat.
Povrata
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, s charged_sats, baš kao i kod ključanog zahtjeva. Ako ne uspije bez obračuna, pogreška nosi Povratak tokena Vrijedno je š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šteni 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 onaj koji nedostaje; transkripcija čija se duljina ne može pročitati unaprijed je cijenjena za najduže što bi datoteka mogla biti (nikad više od 30 minuta), a razlika do stvarne duljine vraća se kao token za povrat novca; ako se ispostavi da je duža od 30 minuta, to se odbija s 413
Ugradnje vraćaju ono što je procijenjena vrijednost zadržana.Neuspješni video vraća token koji mu je vraćen.
Token za povrat novca je slučajni 256-bitni kod. Nymbot pohranjuje samo svoj haš, a istekne nakon 30 dana.
- Plaćajte s njim. Pošaljite
Authorization: Bearer REFUND-…Sljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći članakSljedeći (refund_token_satsU nanymbotŽetona vrijedna manje od zahtjeva odgovora402refund_insufficientNeuspjeh koji se ne obračunava stavlja sats natrag na isti žeton. - 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.
- Pokušajte ga premjestiti na nym. Stavite ga u Donirajte poklon u aplikaciji Nymbot, ili pozovite
POST /api/v1/l402/refunds/redeemS A Potpisani zahtjev i{"refund_token": "REFUND-...", "balance": "standard"}( ili"pro"Cijeli krediti idu na ravnotežu (10 stopa svaki na standard, 100 na Pro); stopa koja ne čini cijeli kredit ostaje na žetonu za API zahtjeve.
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 } }