Baza e njohurive Zhvilluesit
Balanc, top-ups dhe çelësat
Kontrolloni atë që keni, mbuloni Lightning, mbuloni automatikisht nga portofoli juaj, shihni se çfarë kushton çdo kërkesë dhe menaxhoni çelësat nga kodi.
Kjo faqe është përkthyer me makinë për lehtësi. Origjinali në anglisht është versioni që zbatohet.
Kontrolloni balancën
Të dy balancat tuaja, dhe sa nga kapaku i këtij çelësi është përdorur.
GET https://nymbot.ai/api/v1/credits/balance Ju duhet një çelës API. POST Punon gjithashtu, për klientët që e presin atë.
balance është dy bilancet së bashku në dollarë në çmimin aktual të Bitcoin, për mjetet që presin një numër të vetëm (null Pjesa tjetër është në kredi dhe sats, që është se si balancat janë mbajtur në të vërtetë. key Një çelës që ka arritur kapakun e tij ende mund të kontrollojë bilancin.
Përgjigje
{
"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"
}
}
| Statusit | Kur |
|---|---|
401 | Çelësi është i munguar, i panjohur, i revokuar ose i skaduar. |
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);
Metodat e pagesës
Si mund të top up, dhe kufijtë. rrufeja është e vetmja metodë.
GET https://nymbot.ai/api/v1/topup/payment-methods Nuk ka çelës të nevojshëm
Një top-up është 10 deri në 1.000.000 sats; një top-up Pro duhet të blejë të paktën një kredi Pro, kështu që fillon në 100 sats. bulk_bonus liston kredinë shtesë në top-ups më të mëdha, të njëjta si në app: 10%, 15% ose 20% më shumë në top-ups standarde nga 500, 1,000 ose 5,000 sats, dhe në top-ups Pro nga 5,000, 10,000 ose 50,000 sats.
Përgjigje
{
"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);
Ngrihet mbi rrufe
Krijon një faturë Lightning që shton kredi në nym çelësi i takon. paguani atë nga çdo portofol Lightning, pastaj Kontrolloni atë për të marrë kredinë e shtuar.
POST https://nymbot.ai/api/v1/topup/create/btc-lightning Ju duhet një çelës API.
| fushë | Lloji | Të nevojshme | Përshkrimi |
|---|---|---|---|
amount | Numër | po | Sa shumë, në currencyNjë numër i tërë për bast. |
currency | Stringë | jo | SATS (Për shkak të defektit) USD ose BTCDollarët konvertohen në çmimin aktual të Bitcoin. |
tier | Stringë | jo | pro (Për shkak të defektit) ose standard> në të cilën balanca e kredisë shkon. |
Një kredi standarde është 10 sats dhe një kredi Pro 100 sats, plus çdo bonus në masë;
credits Kjo tregon se çfarë do të shtojë kjo faturë.
Përgjigje
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"payment_request": "lnbc100u1p5...",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": "2026-09-30T09:27:00Z",
"status": "pending"
}
| Statusit | Kur |
|---|---|
400 | Një tjetër metodë në rrugën (unsupported_method, një monedhë e panjohur (unsupported_currency(Për shembull, numri më i ulët ose më i ulët se numri më i lartë)amount_too_small(Për më shumë se 1 milion lekë)amount_too_large) ose refuzuar nga portofoli Lightning (amount_out_of_range). |
429 | Më shumë se 60 faturat për këtë nym, ose 120 nga kjo adresë, në një orë (rate_limit_exceededMe të Retry-After). |
502 | Nuk mund të bëhet faturë për momentin (invoice_unavailableMe të 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);
Kontrolloni një top-up
Pyet nëse fatura është paguar dhe, sapo të ketë, shton kredinë. kontrolli është ajo që kreditet atë, kështu që pas pagesës, kontrolloni derisa statusi është creditedKontrollimi përsëri më vonë është i sigurt: kredia mbërrin një herë, pa marrë parasysh se sa herë kërkoni.
GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - ka nevojë për një çelës nga nym që bëri faturën.
status është pending (Nuk është paguar ende) paid (Paguaj, por nuk kreditohet akoma; kontrolloni përsëri), credited (në bilancin tuaj) ose expired (Nuk paguhet në kohë). fushat e bilancit janë për nivelin në të cilin rritet fatura.
Përgjigje
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"status": "credited",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": null,
"balance_credits": 523.33,
"balance_sats": 52333
}
| Statusit | Kur |
|---|---|
400 | ID nuk është ID 64-karaktere nga thirrja e krijuar. |
404 | Asnjë faturë nga ajo id për nym tuaj (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);
Dëshira për histori
Një rresht për kërkesë: çfarë ishte, çfarë modeli, sa tokenë dhe çfarë kushton. Asnjë thirrje ose përgjigje nuk ruhet, kështu që asnjë nuk kthehet. Rreshtat ruhen për 90 ditë, më të reja së pari. Një çelës që ka arritur kapakun e tij ende mund të lexojë historinë e tij.
GET https://nymbot.ai/api/v1/queries/history - ka nevojë për një çelës API, i cili sheh kërkesat e veta, ose një Kërkesa e nënshkruar nga nyma jote, që sheh çdo çelës.
| fushë | Lloji | Të nevojshme | Përshkrimi |
|---|---|---|---|
page | Kërkesë ( Query ) | jo | Default 1, më shumë se 1,000; një faqe më e lartë është 400 invalid_value. |
page_count | Kërkesë ( Query ) | jo | Rreshta për faqe. Default 20, më shumë se 100. |
start_dateend_date | Kërkesë (Query) | jo | ISO 8601 datat ose orët. |
model | Kërkesë (Query) | jo | Vetëm këtë model. |
type | Kërkesë (Query) | jo | chat, responses, messages, image, video, speech, transcription ose embedding. |
all_keys | Kërkesë Boolean | jo | Me një çelës: true përfshin të gjitha çelësat e së njëjtës nym. false. |
key_id | Kërkesë (Query) | jo | me një kërkesë të nënshkruar, ose me all_keys=trueVetëm ky çelës |
Përgjigje
{
"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);
Kërkesat e nënshkrimit të llogarisë
Krijimi, ndryshimi dhe revokimi i çelësave, përmbledhja e llogarisë dhe top-ups automatike nuk marrin një çelës API. Ata marrin një nënshkrim nga nym juaj, kështu që një çelës i rrjedhur mund të shpenzojë deri në kapakun e tij, por kurrë nuk mund të bëjë një çelës tjetër ose të ngrejë kapakun e vet.
Aplikacioni e bën këtë për ju: gjithçka në zjarri sheet përdor këto pika përfundimtare. Ju vetëm keni nevojë për këtë seksion për të menaxhuar çelësat nga kodi juaj.
Nënshkrimi është një ngjarje Nostr e llojit 27235 (NIP-98), e dërguar baz64-koduar në
Authorization Header me fjalën Nostr Në front:
Ngjarja
{
"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është URL e plotë e kërkesës, zinxhiri i pyetjes përfshirë, pikërisht siç është dërguar.methodKjo është metoda HTTP.payloadështë SHA-256 e trupit të kërkesës së papërpunuar, në hex.POSTdhePATCHdhe trupi që ju dërgoni duhet të jetë byte për byte ajo që ju hashed.created_atduhet të jetë brenda 60 sekondave të orës së serverit.- Çdo ngjarje funksionon një herë, a
GETtë përfshira, kështu që një header i kapur nuk mund të riprodhohet. nënshkruani një të ri për çdo kërkesë. shtoni njënonceshënoni me një vlerë të rastësishme në mënyrë që dy kërkesa të nënshkruara në të njëjtën sekondë të jenë ende të ndryshme. - Trupi i një kërkese të nënshkruar mund të jetë deri në 64 KB, dhe një trup ka nevojë për
Content-Type: application/json.
Një ngjarje e humbur rikthehet 401 missing_nostr_authnjë që është keq i formuar, keq i nënshkruar, shumë i vjetër, ose për një URL të ndryshme, metodë ose trupi kthen
invalid_nostr_authme arsyen në mesazhin; një i ri-përdorur kthehet
nostr_auth_replayedNjë çelës API i dërguar në këto pika përfundimtare refuzohet. nënshkrimi kontrollohet para se trupi të lexohet, dhe çdo adresë mund ta dështojë atë 30 herë në minutë (një adresë IPv6 llogaritet si e tërë /64); pas kësaj ajo merr 429 me
Retry-After.
Shfletuesit mund të thërrasin këto pika përfundimtare vetëm nga faqet e veta të Nymbot (https://nymbot.ai,
https://nymchat.app Një faqe në çdo vend tjetër nuk merr asnjë tituj CORS prapa, kështu që nuk mund të lexojë atë që ata kthejnë.
OriginNuk janë të prekur.
Nënshkrimi ka nevojë për çelësin e fshehtë të nym tuaj (e nsecVetëm vendoseni në një skenar në një makinë që ju besoni, lexoni atë nga mjedisi në vend që ta shkruani atë në skedar, dhe preferoni aplikacionin kur mundeni.
Këto ndihmës ndërtojnë krye. shembujt e mëvonshëm në këtë faqe i përdorin ato. Ata lexojnë çelësin sekret në hex NOSTR_SECRET_HEX; cURL një përdor
Lakuriq mjetin e linjës së komandës, i cili merr një çelës nsec ose hex, dhe sha256sum në 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");
}
Përmbledhja e llogarisë
Çfarë tregon fletë API e aplikacionit në krye: çelësi juaj publik, të dy balancat, sa çelësat janë aktive (jo të revokuara ose të skaduara), dhe Top-up automatik përshtatje, ose
null kur serveri nuk i ofron ato.
GET https://nymbot.ai/api/v1/account Nevojë për a Kërkesa e nënshkruar.
Përgjigje
{
"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());
Menaxhimi i çelësave
Pikat e fundit prapa listës së çelësave të aplikacionit. të gjithë ata kanë nevojë për një Kërkesa e nënshkruarÇdo çelës kthehet në këtë formë, me herë në ISO 8601 dhe shuma në sats:
Objekti kryesor
{
"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 është e mjaftueshme për të njohur një çelës por jo për ta përdorur atë. çelësi vetë kthehet vetëm një herë, kur është bërë.
Lista e çelësave
GET https://nymbot.ai/api/v1/keys të nënshkruar.
| fushë | Lloji | Të nevojshme | Përshkrimi |
|---|---|---|---|
include_revoked | Kërkesë Boolean | jo | Përfshin çelësat e revokuara. false. |
Përgjigje
{ "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);
Bëni një çelës
POST https://nymbot.ai/api/v1/keys të nënshkruar, të kthyer 201.
| fushë | Lloji | Të nevojshme | Përshkrimi |
|---|---|---|---|
name | Stringë | po | 1 deri në 40 karaktere, të ndryshme nga çelësat tuaja të tjera aktive (duke injoruar rastin). |
limit_sats | Integrale | jo | Kapaku i shpenzimeve në sats, të paktën 1.Lëre atë jashtë për asnjë kapak. |
reset_period | Stringë | jo | daily, weekly ose monthlyNevojat limit_satsLëreni atë jashtë për një kapak që kurrë nuk rivendoset. |
expire_at | String ose integer | jo | Kur çelësi ndalon së punuari: një herë ISO 8601, ose milisekonda që nga viti 1970. |
Përgjigje (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"
}
}
| Statusit | Kur |
|---|---|
400 | Një emër i munguar ose shumë i gjatë; një emër tashmë në përdorim (duplicate_name(Përdorimi i një numri të plotë të një numri jo më pak se 1; një periudhë e rivendosur pa një kufi; një skadim në të kaluarën; një fushë e panjohur)unknown_parameter); ose 25 çelësat aktive tashmë (too_many_keys). |
429 | Më shumë se 60 çelësat e bëra nga ky nym, ose 120 nga kjo adresë, në një orë (rate_limit_exceededMe të 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);
Lexoni një çelës
GET https://nymbot.ai/api/v1/keys/{id} të nënshkruar.
Kthim {"data": {…}} me objektin kryesor, ose 404
key_not_found nëse asnjë nga çelësat tuaja nuk e ka këtë 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);
Ndryshimi i çelësave
PATCH https://nymbot.ai/api/v1/keys/{id} të nënshkruar.
Dërgo ndonjë name, limit_sats, reset_period dhe
expire_at, me të njëjtat rregulla si kur duke bërë një çelës. null Ndryshimi i periudhës së rivendosjes fillon një periudhë të re nga zero.400 key_revoked) Rikthehet
{"data": {…}} me objektin kyç të përditësuar.
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);
Kthimi i një çelësi
DELETE https://nymbot.ai/api/v1/keys/{id} të nënshkruar.
Ndalon çelësin menjëherë, për mirë. Ajo qëndron në listën me revoked_at të caktuar, dhe mund të shihet me include_revoked=trueRevokimi i një çelësi që tashmë është revokuar përgjigjet në të njëjtën mënyrë.Vetëm 50 çelësat më të reja të revokuara ruhen; ato më të vjetra fshihen kur një çelës tjetër revokohet.
Përgjigje
{ "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());
Fjalë kyçe NWC Auto-top-up
Lidhni një portofol Lightning me Nostr Wallet Connect dhe Nymbot mbulon një bilanc në vetvete kur shpenzimet API e drejtojnë atë të ulët. Kërkesa e nënshkruar.
Si funksionon: pasi një kërkesë API ngarkohet në bilancin që keni zgjedhur për të shikuar, nëse ky bilanc ka rënë nën pragun tuaj, Nymbot bën një faturë për shumën tuaj të lartë, kërkon që portofoli juaj ta paguajë atë, dhe shton kredinë. Ajo rritet në maksimum një herë çdo 5 minuta për çdo nym dhe bilanc, kështu që një shpërthim i kërkesave nuk mund të zbrazë portofolin. Shpenzimi në aplikacionet nuk e shkakton atë. Koha dhe madhësia e fundit të lartë, dhe gabimi i fundit, janë në cilësimet; nëse një pagesë kaloi pas një gabimi, kontrolloni faturën e saj me Statusi i Top-Up kredisë së saj.
Nymbot ruan atë të koduar dhe vetëm ndonjëherë e përdor atë për të paguar faturat e veta të lartë, por bëni një lidhje vetëm për këtë, me një buxhet shpenzimi në portofolin tuaj, kështu që më shumë që mund të paguajë është një numër që ju zgjodhi. pay_invoice.
Lidhja e një portofol
POST https://nymbot.ai/api/v1/nwc-auto-topup/connect të nënshkruar.
| fushë | Lloji | Të nevojshme | Përshkrimi |
|---|---|---|---|
nwc_url | Stringë | po | Rrjeti i lidhjes, duke filluar nga nostr+walletconnect://Nymbot kërkon portofolin për get_info para se ta ruajë atë, dhe e ruaj atë të koduar. |
threshold_sats | Integrale | po | Top up kur bilanci bie nën këto shumë sats. të paktën 1,000. |
topup_sats | Integrale | po | Sa për të shtuar çdo herë. 1,000 deri në 1,000,000 sats. |
tier | Stringë | jo | pro (Për shkak të defektit) ose standard: ekuilibri për të shikuar dhe top up. |
Përgjigje
{
"data": {
"connected": true,
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
"last_topup_at": null,
"last_topup_sats": null,
"last_error": null
}
}
| Statusit | Kur |
|---|---|
400 | Nuk është një linjë lidhëse (invalid_nwc_urlPërgjigjja nuk u përgjigj në lidhje me transmetimin (nwc_unreachable) ose refuzoi kontrollin (nwc_rejected(Nuk mund të paguajë faturat e lidhjes)nwc_missing_permissionose një sasi jashtë kufijve. |
501 | Shërbimi nuk mund të përdoret në mënyrë automatike (nwc_unavailableE njëjta gjë vlen edhe për dy përfundimet e tjera. |
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());
Leximi i cilësimeve
GET https://nymbot.ai/api/v1/nwc-auto-topup të nënshkruar.
kthen të njëjtin objekt si lidhja, me connected: false dhe fushat e tjera
null kur asnjë portofol nuk është i lidhur. rreshti i lidhjes nuk kthehet kurrë.
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());
Disconnecting
DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection të nënshkruar.
Fshin zinxhirin e lidhjes së ruajtur.Nuk bëhen më top-ups.Për të qenë i sigurt, mund të revokoni edhe lidhjen në portofolin tuaj.
Përgjigje
{ "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());
Pagesa me kërkesë pa çelës
Çmimet fikse mund të paguhen për një kërkesë në një kohë gjatë Lightning, pa çelës, pa llogari dhe pa bilanc: POST /images/generations, POST /images/edits,
POST /videos, POST /audio/speech, POST /audio/transcriptions,
POST /audio/translations dhe POST /embeddingsChat, Përgjigjet dhe Mesazhet gjithmonë kanë nevojë për një çelës. Një kërkesë që mban një çelës faturohet në bilanc si zakonisht; rrjedha e pagesës fillon vetëm kur nuk dërgohet asnjë çelës.
Nymbot flet dy versione të së njëjtës ide, nga një backend: Lightning Labs'
L402 të (E pranuar edhe nën emrin e tij të vjetër, LSATProjekti i IETF-së
Pagesa Skema e vërtetimit HTTP me lightning Metoda dhe
charge Përdorni atë që klienti juaj e kupton.
Pagesa pa një çelës është në vetëm kur API_L402_SECRET mbajnë të paktën 32 byte të rastësishme, si hex (64 karaktere) ose base64 (44). openssl rand -hex 32Një vlerë më e shkurtër ose e parashikueshme e fik funksionin dhe logon pse. API_L402_SECRET_PREVIOUS për një ditë: kredencialet, URL-të e statusit dhe sfidat e bëra nën të vazhdojnë të punojnë derisa të përfundojnë.
Sfidat
Dërgo kërkesën me jo Authorization header. nëse është e vlefshme, asgjë nuk funksionon, dhe ju merrni 402 Payment Required me një faturë për saktësisht se çfarë kushton kërkesa: e njëjta çmim një çelës do të paguante, të konvertuar në 10 sats një kredi standarde ose 100 sats një kredi Pro dhe të rrumbullakosur deri në një të tërë sat (të paktën 1 sat, dhe të paktën 0.05 minimum krediti). WWW-Authenticate Sfidat për të njëjtën faturë:
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 }
}
pagesës request Parametra është base64url JSON:
{"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.
Një sfidë është e lidhur me pikën përfundimtare, me Content-Type (tipi i mediave dhe, për shumë pjesë, kufiri i saj) dhe në SHA-256 të bytes saktë të trupit që keni dërguar, dhe zgjat 15 minuta. identike Kërkesa përsëri: e njëjta
Content-Type dhe të njëjtat bytes JSON, ose për pikët përfundimtare të shumë pjesëve (/images/edits, /audio/transcriptions, /audio/translationsShumica e bibliotekave HTTP zgjedhin një kufi të ri çdo herë që kodojnë një formular, kështu që kodoni atë një herë dhe dërgoni ato bajta dy herë.
Çdo adresë mund të kërkojë për 30 sfida në minutë (një adresë IPv6 llogaritet si e tërë /64). Kërkesat e të cilave adresa nuk është e njohur ndajnë një 10 më të rreptë në minutë, dhe ka një kufi të përgjithshëm për problemet e sfidave Nymbot në të gjitha adresat; një kërkesë e refuzuar para se të bëhet një sfidë (p.sh. me një trup që nuk është i vlefshëm JSON) nuk llogaritet ndaj saj. 429 me Retry-AfterPikat e fundit të paguara të thirrura pa një çelës ose kredencial gjithashtu llogariten në kufirin e përgjithshëm të 120 kërkesave të paautentifikuara në minutë për adresë. Content-Type Nuk është application/json ose
multipart/form-data për ngarkesat) është refuzuar me 415 Asnjëherë nuk merr faturë.
Embeddings janë vlerësuar nga një vlerësim i tokenëve në hyrje, me një 1.5× margjinë, pasi numri real është i njohur vetëm më vonë. Kthim token.
Dërgimi i pagesës
Paguani faturën me çdo portofol Lightning. portofoli ju jep para-imagjinën, 64 karaktere hexagonalë. Pastaj dërgoni të njëjtën kërkesë me një nga këto:
| skemë | Headerë |
|---|---|
| L402 të | Authorization: L402 <macaroon>:<preimage> (LSAT punojnë gjithashtu) |
| Pagesa | Authorization: Payment <base64url JSON>, ku JSON është {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}} |
Një kërkesë e paguar përgjigjet pikërisht si një e bërë me një çelës, përveç se nymbot
Objekti nuk ka fushë ekuilibri: {"payment": "l402", "tier": "pro", "paid_sats": 237,
"charged_sats": 237}Dhe nuk ka asnjë X-Nymbot-Balance-Sats Një kërkesë e paguar me skemën e pagesës gjithashtu merr një Payment-Receipt header (base64url JSON me id sfidë, hash pagesa si reference, status dhe
timestampKërkesat e paguara nuk janë të lidhura me asnjë nym, kështu që ato nuk shfaqen në historinë e pyetjeve.
| Statusit | Kur |
|---|---|
402 payment_already_used | Çdo pagesë paguan për një kërkesë. Përgjigja është një sfidë e re për këtë kërkesë, kështu që një klient që cache kredencialin e tij të fundit (si lnget Dhe sërish thjesht vijnë. |
402 payment_mismatch | Kërkesa u dërgua në një tjetër vend, Content-Type ose trup, ose paguani më pak se sa kjo kërkesë tani kushton. Një sfidë e re për këtë kërkesë vjen me të; nëse pagesa ishte shumë e vogël, ajo që keni paguar kthehet si një Kthim token (refund_token dhe refund_sats në trupin e tij). |
402 payment_expired | Më shumë se 15 minuta kanë kaluar që nga sfida. Një sfidë e re vjen me të. Nëse parafigura tregon se keni paguar, ajo që keni paguar kthehet si një Kthim token (refund_token dhe refund_sats në trup), një herë; kredencial pastaj është përdorur. |
401 invalid_preimage | Preimage nuk hash në hash pagesa e faturës. pagesa nuk është përdorur. |
401 invalid_payment_credential | Credentiali është i keqformuar, është ndryshuar pasi Nymbot e ka lëshuar atë, ose emrat e një hash pagese Nymbot kurrë nuk ka lëshuar një faturë për. |
429 rate_limit_exceeded | Më shumë se 30 kredencialet ose çelësat që dështuan të verifikoheshin erdhën nga kjo adresë në një minutë, ose një token e rimbursimit u dërgua më shumë se 60 herë në një minutë. 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"));
Klientët e ndërtuar në mppx me një metodë Rrufeja trajtojnë vetë sfidën e pagesës; i drejtojnë ata në pikën përfundimtare dhe i lënë ata të paguajnë.
Video të
Paguajë POST /videos Përgjigjet 202 si një çelës, plus a
status_url: GET Ajo është e nënshkruar dhe punon për 24 orë, për aq kohë sa puna është mbajtur.
{
"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..."
}
}
Mbajeni atë refund_token Përgjigje: Kjo është një përgjigje e thjeshtë që mund të shfaqet vetëm në këtë video (GET /api/v1/l402/refunds Përgjigjet "status": "pending"); në qoftë se renditja dështon pa faturim, pagesa ulet në të.
refund_sats për një punë të rimbursuar, por kurrë token, kështu që ndarja e statusit URL nuk ndan rimbursimin.
Rimbursimet
Nëse një kërkesë e paguar dështon dhe ofruesi faturoi Nymbot për përpjekjen, pagesa mbahet dhe gabimi thotë kështu, me charged_sats, pikërisht si për një kërkesë me çelës. Nëse dështon pa u faturuar, gabimi mbart një Kthim token Çfarë ia vlen të paguash:
{
"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"
}
}
Pjesët e papërdorura kthehen në të njëjtën mënyrë: nëse kërkuat dy foto dhe njëra dështoi pa faturim, përgjigja e suksesit nymbot objekti mban një token rimbursimi për atë që mungon; një transkriptim gjatësia e të cilit nuk mund të lexohet më parë çmimi për më të gjatë dosjen mund të jetë (kurrë më shumë se 30 minuta), dhe ndryshimi në gjatësinë e vërtetë kthehet si një token rimbursimi; në qoftë se ajo rezulton të jetë më e gjatë se 30 minuta, ajo është refuzuar me 413
dhe e gjithë pagesa kthehet. Embeddings kthejnë atë që vlerësimi mbajti mbrapa. Një video e dështuar kthehet në token paraqitjen e saj të kthyer.
Një token e rimbursimit është një kod i rastësishëm 256-bit. Nymbot ruan vetëm hash-in e tij, dhe ai skadon pas 30 ditësh.
- Paguani me të. Dërgo
Authorization: Bearer REFUND-…Çmimi i shpenzimeve është i barabartë me çmimin e shpenzimeve të shpenzimeve të shpenzimeve të shpenzimeve (refund_token_satsNë tënymbotNjë token me vlerë më pak se përgjigjet e kërkesës402refund_insufficientNjë dështim i panjohur vendos satsin përsëri në të njëjtin token. - Kontrolloni atë
GET /api/v1/l402/refundsme të njëjtin header kthehet{"sats": 237, "status": "open", "expires_at": "..."}. - Një token mund të përdoret deri në 60 herë në minutë.
- Vendoseni atë në një nym. Vendoseni atë në Merrni një dhuratë në aplikacionin Nymbot, ose telefononi
POST /api/v1/l402/refunds/redeemMe një Kërkesa e nënshkruar dhe{"refund_token": "REFUND-...", "balance": "standard"}ose"pro"Të gjitha kreditet shkojnë në bilancin (10 sats secili në standard, 100 në Pro); sats që nuk e bëjnë një kredi të tërë të qëndrojë në token për kërkesat 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"
Përgjigje
{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }