Konesans baz Devlopè
Balanse, Top-ups ak kle
Tcheke sa ou gen, top up sou Lightning, top up otomatikman soti nan portefeuille pwòp ou, wè sa chak demann koute, ak jere kle soti nan kòd.
Paj sa a se machin-tradui pou konvenyans. Orijinal angle a se vèsyon ki aplike a.
Tcheke balans la
Tou de balans ou, ak ki jan anpil nan kap nan kle sa a se itilize.
GET https://nymbot.ai/api/v1/credits/balance - ou bezwen yon kle API. POST travay tou, pou kliyan ki espere li.
balance se de balans ansanm nan dola nan pri a kounye a Bitcoin, pou zouti ki espere yon sèl nimewo (null si pri a pa ka li). Rès la se nan kredi ak sats, ki se ki jan balans yo reyèlman kenbe. key Deskripsyon nan kle a ki te mande. Yon kle ki te rive nan cap li yo toujou ka tcheke balans la.
Reply
{
"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 nan | Kòm |
|---|---|
401 | Klavye a se manke, pa konnen, revoke oswa fini. |
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);
Metòd peman
Ki jan ou ka top up, ak limit yo. Lightning se metòd la sèlman.
GET https://nymbot.ai/api/v1/topup/payment-methods Pa gen okenn kle bezwen.
Yon top-up se 10 a 1.000.000 sats; yon Pro top-up gen yo achte omwen yon kredi Pro, se konsa li kòmanse nan 100 sats. Limi yo dola swiv pri a nan Bitcoin. bulk_bonus lis kredi a siplemantè sou top-ups pi gwo, menm jan ak nan app la: 10%, 15% oswa 20% plis sou top-ups estanda soti nan 500, 1,000 oswa 5,000 sats, ak sou Pro top-ups soti nan 5,000, 10,000 oswa 50,000 sats.
Reply
{
"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);
Kòmanse sou Lightning
Li kreye yon faktè Lightning ki ajoute kredi nan nym la kle a nan. Peye li soti nan nenpòt wallet Lightning, Lè sa a, Tcheke nan pou yo gen kredi a ajoute.
POST https://nymbot.ai/api/v1/topup/create/btc-lightning - ou bezwen yon kle API.
| Zòn | Ki jan | Rechèch | Deskripsyon |
|---|---|---|---|
amount | Nimewo | Wi | Ki jan anpil, nan currencyYon nimewo tout pou sats. |
currency | String nan | pa | SATS (pou yon defèt) USD ou BTCDollar yo konvèti nan pri a kounye a nan Bitcoin. |
tier | String nan | pa | pro (ki se default la) oswa standard: balans ki nan ki kredi a ale. |
Yon kredi estanda se 10 sats ak yon kredi Pro 100 sats, plis nenpòt bonis volim;
credits Li di sa ki sa a faktè pral ajoute.
Reply
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"payment_request": "lnbc100u1p5...",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": "2026-09-30T09:27:00Z",
"status": "pending"
}
| Status nan | Kòm |
|---|---|
400 | Yon lòt metòd nan wout la (unsupported_method), yon lajan sanble (unsupported_currency) oswa tier, yon kantite manke, oswa yon kantite anba minimòm la (amount_too_small), pi wo pase 1 000 000 sats (amount_too_large) oswa refize pa Lightning wallet la (amount_out_of_range). |
429 | Plis pase 60 faktè pou sa a nimm, oswa 120 soti nan adrès sa a, nan yon èdtan (rate_limit_exceededak Retry-After). |
502 | Pa gen okenn faktè ka fè kounye a (invoice_unavailableak 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);
Tcheke yon top-up
Li mande si faktè a te peye epi, yon fwa li te gen, ajoute kredi a. Tcheke se sa kredi li, se konsa apre peye, tcheke jiska estati a se creditedTcheke ankò apre sa se san danje: kredi a fini yon fwa, pa gen pwoblèm ki jan anpil fwa ou mande.
GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - bezwen yon kle soti nan nym la ki te fè faktè a.
status se pending (pa gen peye ankò) paid (Paye, men pa toujou kredi; tcheke ankò), credited (sou balans ou) oswa expired (pa peye nan tan). Zòn balans yo se pou nivo a ki fè faktè a tèt.
Reply
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"status": "credited",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": null,
"balance_credits": 523.33,
"balance_sats": 52333
}
| Status nan | Kòm |
|---|---|
400 | ID a se pa id a 64-karakter soti nan kreye apèl la. |
404 | Pa gen okenn faktè pa id sa a pou 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);
Eseye istwa
Yon ranje pou chak demann: ki sa li te, ki modèl, ki kantite token yo ak sa ki koute li. Pa gen okenn prompts oswa repons kenbe, se konsa pa gen okenn retounen. Ranje yo kenbe pou 90 jou, dènye premye. Yon kle ki te rive nan limit li yo toujou ka li istwa li yo.
GET https://nymbot.ai/api/v1/queries/history — bezwen yon kle API, ki wè pwòp demand li yo, oswa yon Rechèch nan soti nan nim ou, ki wè chak kle a.
| Zòn | Ki jan | Rechèch | Deskripsyon |
|---|---|---|---|
page | pa gen okenn pwoblèm. | pa | default 1, maksimòm 1000; yon paj ki pi wo se 400 invalid_value. |
page_count | pa gen okenn pwoblèm. | pa | Rwa pou chak paj. Default 20, nan maksimòm 100. |
start_dateend_date | Règleman nan (Query) | pa | ISO 8601 dat oswa tan. |
model | Règleman nan (Query) | pa | Se sèlman modèl sa a. |
type | Règleman nan (Query) | pa | chat, responses, messages, image, video, speech, transcription ou embedding. |
all_keys | Pwodwi pou Telefòn (query) | pa | ak yon kle: true gen ladan chak kle nan menm nym. Default false. |
key_id | Règleman nan (Query) | pa | avèk yon demann sigare, oswa ak all_keys=true: Se sèlman kle sa a. |
Reply
{
"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);
Signature kont demann
Kreye, chanje ak revoke kle, konvèti kont ak otomatik top-ups pa pran yon kle API. Yo pran yon signature soti nan nym ou, se konsa yon kle lekòl ka pase jiska cap li yo, men pa janm ka fè yon lòt kle oswa ogmante cap li yo.
App a fè sa a pou ou: tout nan li Fwa sheet sèvi ak pwen fini sa yo. Ou sèlman bezwen seksyon sa a pou jesyon kle soti nan kòd pwòp ou.
Signature se yon evènman Nostr nan kalite a 27235 (NIP-98), voye base64-encode nan
Authorization Header ak Pawòl la Nostr nan devan:
Evènman an
{
"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": "..."
}
use URL a konplè nan demann an, string nan demann ki gen ladan, egzakman kòm te voye.methodse metòd la HTTP.payloadse SHA-256 nan kò a demann brik, nan hex. Li se mande souPOSTepiPATCH, ak kò a ou voye ta dwe byte pou byte ki ou hashed.created_atdwe nan 60 segonn nan orè a nan sèvè a.- Tout evènman ap travay yon fwa, a
GETki gen ladan, se konsa yon header captured pa ka replay. Sign yon nouvo pou chak demann. Ajoute yonnoncetag ak yon valè alektè, se konsa de mande sigare nan menm segonn toujou diferan. - Kòn nan yon demann sigare ka maksimòm 64 KB, ak yon kò bezwen
Content-Type: application/json.
Yon evènman manke retire 401 missing_nostr_auth; yon sèl ki se mal fòme, mal sigare, te granmoun, oswa pou yon URL diferan, metòd oswa kò retire
invalid_nostr_auth, ak rezon nan mesaj la; yon re-brake yon sèl retire
nostr_auth_replayedYon kle API voye nan pwen sa yo se refize. Signature a se tcheke anvan kò a se li, ak chak adrès ka default li 30 fwa pou yon minit (yon adrès IPv6 konsidere kòm tout /64); Lè sa a, li jwenn 429 ak
Retry-After.
Navigatè ka rele poutèt sa yo sèlman soti nan sit yo pwòp nan Nymbot (https://nymbot.ai,
https://nymchat.app Yon paj sou nenpòt lòt sit jwenn pa gen okenn tèt CORS tounen, se konsa li pa ka li sa yo retounen. Skript ak apps natif, ki voye pa gen okenn
Originyo pa afekte.
Signing bezwen kle a sekrè nan nim ou a (la nsec), ki kontwole tout: idantite ou, istwa ou ak balans ou. Jis mete li nan yon script sou yon machin ou konfyans, li soti nan anviwònman anvan ekri li nan dosye a, ak prefere app a lè ou ka.
Sèvis sa yo bati header la. Egzanp ki pi ta sou paj sa a sèvi ak yo. Yo li kle a sekrè nan hex soti nan NOSTR_SECRET_HEX; cURL yon itilize nan
NAN Zouti liy lòd, ki pran yon nsec oswa hex kle, ak sha256sum Pou 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");
}
Konte rezime
Ki sa ki fèy la API nan aplikasyon an montre nan tèt la: kle piblik ou a, tou de balans, ki kantite kle yo aktif (pa revoke oswa te pase), ak Otomatik Top-up nan Konfigirasyon, oswa
null lè sèvè a pa ofri yo.
GET https://nymbot.ai/api/v1/account Li bezwen yon Rechèch nan.
Reply
{
"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());
Manadjè kle
Endpoints ki anba lis la kle nan aplikasyon an. Tout nan yo bezwen yon Rechèch nanTout kle se retounen nan fòm sa a, ak tan nan ISO 8601 ak kantite lajan nan sats:
Objè kle
{
"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 se ase yo rekonèt yon kle, men pa sèvi ak li. Klav la nan tèt li se retire sèlman yon fwa, lè li se kreye.
Listifikasyon kle
GET https://nymbot.ai/api/v1/keys nan sigarèt.
| Zòn | Ki jan | Rechèch | Deskripsyon |
|---|---|---|---|
include_revoked | Pwodwi pou Telefòn (query) | pa | Gen ladan revoke kle. Default false. |
Reply
{ "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);
Kreye yon kle
POST https://nymbot.ai/api/v1/keys Retounen. Retounen 201.
| Zòn | Ki jan | Rechèch | Deskripsyon |
|---|---|---|---|
name | String nan | Wi | 1 a 40 karaktè, diferan de lòt kle aktif ou (ignore ka). |
limit_sats | Entegre | pa | Kap chèz nan sats, minimòm 1. Pèmèt li soti pou pa gen cap. |
reset_period | String nan | pa | daily, weekly ou monthlyPotansyèl limit_sats. Lè sa a, kite li pou yon kouvèti ki pa janm resèt. |
expire_at | String oswa enteryè | pa | Lè kle a pa travay: yon tan ISO 8601, oswa milisekond soti nan 1970. |
Repons nan (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 nan | Kòm |
|---|---|
400 | Yon non manke oswa trè long; yon non deja nan itilize (duplicate_name); yon cap ki se pa yon nimewo enteryè nan mwens pase 1; yon peryòd reset san yo pa yon cap; yon expiration nan tan kap vini an; yon jaden enkonnen (unknown_parameter); oswa 25 kle deja aktif (too_many_keys). |
429 | Plis pase 60 kle te fè pa sa a nim, oswa 120 soti nan adrès sa a, nan yon èdtan (rate_limit_exceededak 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);
Li yon sèl kle
GET https://nymbot.ai/api/v1/keys/{id} nan sigarèt.
Retounen {"data": {…}} ak objektif la kle, oswa 404
key_not_found Si pa gen okenn kle nan ou gen id sa a.
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);
Chanje yon kle
PATCH https://nymbot.ai/api/v1/keys/{id} nan sigarèt.
voye nenpòt nan name, limit_sats, reset_period epi
expire_at, ak regleman yo menm jan ak lè fè yon kle. null netwaye yon jaden: pa gen okenn kouvèti, pa gen reset, pa gen okenn expiration. Chanje peryòd reset kòmanse yon nouvo peryòd nan 0. Yon kle revoke pa ka chanje (400 key_revoked) Retounen
{"data": {…}} ak objektif la kle mete ajou.
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);
Revoke yon kle
DELETE https://nymbot.ai/api/v1/keys/{id} nan sigarèt.
Kòmanse kle a nan yon moman, pou bon. Li rete nan lis la ak revoked_at mete, epi yo ka wè ak include_revoked=trueRevoke yon kle ki deja revoke reponn menm jan an. Se sèlman dènye a 50 revoke kle yo kenbe; pi ansyen yo retire lè yon lòt kle revoke.
Reply
{ "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 nan peyi a
Konekte yon Lightning portefeuille ak Nostr Wallet Connect ak Nymbot monte yon balans nan tèt li lè API spending kouri li ki ba. Sheet la API nan app a gen anviwònman yo menm; sa yo se endpoints ki gen ladan li. Tout moun nan yo bezwen yon Rechèch nan.
Ki jan li travay: apre yon demann API se chaje nan balans la ou chwazi yo gade, si balans sa a te ba anba limit ou, Nymbot fè yon faktè pou kantite lajan an tèt ou, mande pou lajan an tèt ou peye li, epi ajoute kredi a. Li monte pi wo a yon fwa chak 5 minit pou chak nime ak balans, se konsa yon brok nan demann pa ka drenaj lajan an. Pandan nan app yo pa trigger li. Tan ak gwosè nan dènye top-up la, ak erè a dènye, yo nan anviwònman yo; si yon peman te pase apre yon erè, tcheke faktè li ak Status nan Top-up kredi nan li.
Yon seri koneksyon pèmèt nenpòt ki moun ki kenbe li mande wallet ou peye. Nymbot magazen li enkripsyon ak sèlman lè l sèvi avèk li peye faktè tèt li yo, men fè yon koneksyon jis pou sa a, ak yon budgèt gasp nan wallet ou, se konsa pi plis li ta ka janm peye se yon nimewo chwazi ou. pay_invoice.
Konekte yon wallet
POST https://nymbot.ai/api/v1/nwc-auto-topup/connect nan sigarèt.
| Zòn | Ki jan | Rechèch | Deskripsyon |
|---|---|---|---|
nwc_url | String nan | Wi | koneksyon string, kòmanse nan nostr+walletconnect://. Nymbot mande pou lajan an pou get_info anvan yo sove li, ak magazen li enkripte. |
threshold_sats | Entegre | Wi | Top up lè balans la desann anba sa a anpil sats. Menm 1000. |
topup_sats | Entegre | Wi | Ki jan anpil yo ajoute chak fwa. 1000 a 1,000,000 sats. |
tier | String nan | pa | pro (ki se default la) oswa standard: balans la yo gade ak top up. |
Reply
{
"data": {
"connected": true,
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
"last_topup_at": null,
"last_topup_sats": null,
"last_error": null
}
}
| Status nan | Kòm |
|---|---|
400 | Pa gen okenn koneksyon ranje (invalid_nwc_url); lajan an pa te reponn sou relay li (nwc_unreachable) oswa refuse tcheke (nwc_rejected); koneksyon pa ka peye faktè (nwc_missing_permission); oswa yon kantite lajan deyò limit yo. |
501 | Otomatik top-ups se pa aktive pou sèvè sa a (nwc_unavailable). Yo menm jan an se pou de lòt endpoints. |
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());
Li nan opsyon yo
GET https://nymbot.ai/api/v1/nwc-auto-topup nan sigarèt.
Retire objè a menm jan an kòm konekte, ak connected: false Epi lòt jaden yo
null lè pa gen okenn wallet ki konekte. Se seri a koneksyon nan tèt li pa janm retire.
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());
Deskripsyon
DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection nan sigarèt.
Retire koneksyon an ki anbake. Pa gen plis top-ups. Pou asire w ke, ou ka tou revoke koneksyon an nan wallet ou.
Reply
{ "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());
Peye sou demann san yon kle
Endpoints pri fixe ka peye pou yon sèl demann nan yon fwa sou Lightning, san yo pa kle, san yo pa kont ak san yo pa balans: POST /images/generations, POST /images/edits,
POST /videos, POST /audio/speech, POST /audio/transcriptions,
POST /audio/translations epi POST /embeddingsChat, Repons ak Mesaj toujou bezwen yon kle. Yon demann ki pote yon kle se chaje nan balans la kòm nòmalman; flux la peman kòmanse sèlman lè pa gen okenn kle te voye.
Nymbot pale de vèsyon nan menm lide a, soti nan yon sèl backend: Lightning Labs '
Pwensipal (Epitou aksepte anba non anvan li, LSAT) ak pwojè a IETF
Paye Sistèm HTTP otantifikasyon ak lightning Metòd ak
charge Tèmèt. Sèvi ak sa kliyan ou konprann.
Paye san yon kle se sou sèlman lè API_L402_SECRET kenbe yon minimòm de 32 byte alegan, tankou hex (64 karaktè) oswa base64 (44). openssl rand -hex 32Yon valè pi kout oswa enkyetid apye karakteristik la epi li anrejistre poukisa. Pou rote li, deplase valè a ansyen nan API_L402_SECRET_PREVIOUS pou yon jou: credentials, estati URLs ak retounen ki te fè anba li kontinye travay jiskaske yo fini.
Devlopman an
Envoye demann la ak pa Authorization header. Si li valab, pa gen anyen kouri, epi ou jwenn 402 Payment Required ak yon faktè pou eksactman sa ki ke demann koute: menm pri a yon kle ta dwe peye, konvèti nan 10 sats yon kredi estanda oswa 100 sats yon kredi Pro ak aranjman jiska yon sat tout antye (minimum 1 sat, ak minimòm 0.05 kredi). WWW-Authenticate repitasyon pou menm faktè:
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 }
}
Paye request paramèt la se base64url JSON:
{"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.
Yon repitasyon ki gen rapò ak fini a, nan Content-Type (tipi medya li yo ak, pou plizyè pati, limit li yo) ak nan SHA-256 nan kò a eksakteman byte ou voye, ak kenbe 15 minit. Apre peye, voye Identifye Demande ankò: menm bagay
Content-Type ak menm byte JSON, oswa pou multipart endpoints (/images/edits, /audio/transcriptions, /audio/translationsPifò bibliyotèk HTTP chwazi yon limit nouvo chak fwa yo enkode yon fòm, se konsa enkode li yon fwa ak voye byèt sa yo de fwa.
Chaj adrès ka mande pou 30 rechèch pou yon minit (yon adrès IPv6 konsidere kòm tout /64 li yo). Rechèch ki adrès la se pa konnen pataje yon pi strik 10 pou yon minit, ak gen yon limit jeneral sou rechèch Nymbot pwoblèm nan tout adrès; yon rechèch refize anvan yon rechèch se fè (pou egzanp ak yon kò ki pa valab JSON) pa konsidere pou li. Anplis de sa, repons la se 429 ak Retry-After, voye anvan kò a li se li. Paye endpoints rele san yon kle oswa credential tou konekte nan limit jeneral la nan 120 non-autantifikasyon demann pou chak minit pou chak adrès. Yon credential se tcheke anvan kò a se li, ak yon demann ki Content-Type se pa application/json (Ou nan
multipart/form-data pou uploads) se refize ak 415 Epi pa janm jwenn yon faktè.
Embeddings se pri soti nan yon estime nan token yo nan antrepriz la, ak yon 1.5× marje, depi kont la reyèl se sèlman konnen apre sa. Ou peye pou token yo reyèlman itilize, ak pati ki pa itilize nan peman vin tounen kòm yon Retounen nan token.
Envoye peman
Peye faktè a ak nenpòt ki Lightning wallet. Wallet la bay ou preimage, 64 karaktè hex. Lè sa a, voye menm demann la ak youn nan sa yo:
| Sistèm | Header nan |
|---|---|
| Pwensipal | Authorization: L402 <macaroon>:<preimage> (LSAT travay tou) |
| Paye | Authorization: Payment <base64url JSON>, kote se JSON la {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}} |
Yon demann peye reponn menm jan yo te fè ak yon kle, san yo pa ke nymbot
Objè pa gen okenn jaden balans: {"payment": "l402", "tier": "pro", "paid_sats": 237,
"charged_sats": 237}Epi pa gen okenn X-Nymbot-Balance-Sats header. Yon demann peye ak sistèm peman tou resevwa yon Payment-Receipt header (base64url JSON ak id repitasyon, pwa hash kòm reference, status epi
timestampPaye demann yo pa lye ak nenpòt nim, se konsa yo pa parèt nan istorik la nan demann.
| Status nan | Kòm |
|---|---|
402 payment_already_used | Tout peman peye pou yon demann. Repons la se yon retounen nouvo pou demann sa a, se konsa yon kliyan ki cache dènye credential li yo (as lnget se) jis yon fwa ankò. |
402 payment_mismatch | kredential te emèt pou yon lòt fen-pwen, Content-Type oswa kò, oswa peye mwens pase sa a demann kounye a koute. Yon nouvo repitasyon pou demann sa a vini ak li; si peman an te ti, sa ou te peye vin tounen kòm yon Retounen nan token (refund_token epi refund_sats nan kò a). |
402 payment_expired | Plis pase 15 minit depi repitasyon an. Yon nouvo repitasyon vini ak li. Si preimaj la montre ke ou te peye, sa ou te peye vin tounen kòm yon Retounen nan token (refund_token epi refund_sats nan kò a), yon fwa; kredential la Lè sa a, yo te itilize. |
401 invalid_preimage | Preimaj la pa hache sou hache a peman nan faktè a. Paye a se pa itilize. |
401 invalid_payment_credential | Credential la se malformed, te chanje apre Nymbot te emèt li, oswa non yon peman hash Nymbot pa janm te emèt yon faktè pou. Yon macaroon ak yon avèz Nymbot pa konnen, oswa ak avèz konparab, se refize. |
429 rate_limit_exceeded | Plis pase 30 credentials oswa kle ki pa t 'konvèti te vini soti nan adrès sa a nan yon minit, oswa yon token retounen te voye plis pase 60 fwa nan yon minit. 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"));
Kliyan yo bati sou mppx ak yon metòd Lightning sove Paye repitasyon yo tèt yo; montre yo nan fen pwen ak kite yo peye.
Videyo
Yon peye POST /videos Reply 202 tankou yon sèl kle, plis a
status_url: GET li san yo pa gen okenn kle pou swiv travay la. Li sigare ak travay pou 24 èdtan, si travay la se kenbe.
{
"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..."
}
}
kenbe nan refund_token soti nan repons sa a: li se sèlman montre isit la. Li se vid pandan y ap videyo a retrè (GET /api/v1/l402/refunds Reply "status": "pending"); si rendu a manke sanble, peman an ateris sou li. URL a estati montre
refund_sats pou yon travay ranbousman, men pa janm token la, se konsa pataje URL a estati pa pataje ranbousman an. Tcheke token la tou rezoud yon travay ki pa te fè sondaj.
Repons
Si yon demann peye manke ak founisè a chaje Nymbot pou eseye a, peman an se kenbe ak erè a di sa, ak charged_sats, menm jan ak pou yon demann klavye. Si li échoue san yo pa fè fakturasyon, erè a pote yon Retounen nan token Valè sa ou te peye:
{
"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"
}
}
Yon pati ki pa itilize vin tounen nan menm fason an: si ou te mande pou de foto ak youn pa t 'fwa, repons la siksè nymbot objè pote yon token refwadisman pou sa ki manke; yon transkripsyon ki longè yo pa te kapab li nan devan se pri pou pi long ki ka dosye a dwe (pa janm plis pase 30 minit), ak diferans la nan longè reyèl la vin tounen kòm yon token refwadisman; si li rezilta yo pi long pase 30 minit, li se refize ak 413
e tout peman ap retounen. Embeddings retire sa ki estime a te retire. Yon videyo ki pa t 'retire nan token la soumisyon li te retire.
Yon token refwadisman se yon kòd random 256-bit. Nymbot sove sèlman hash li yo, epi li fini apre 30 jou. Li kenbe yon salè sat, epi ou ka:
- Pa peye ak li. Tcheke
Authorization: Bearer REFUND-…nan nenpòt nan pwen fen pi wo a (yon SDK OpenAI pran li kòm kle API l 'yo). Pri a soti nan token an ak sa ki rete sou li (refund_token_satsnannymbotObjè). Yon token ki valè mwens pase repons la nan demann an402refund_insufficient; yon erè sanble mete sats la tounen sou menm token an. - Tcheke nan.
GET /api/v1/l402/refundsak menm header retounen{"sats": 237, "status": "open", "expires_at": "..."}. - Yon token ka itilize maksimòm 60 fwa pou chak minit.
- Move li nan yon nym. Pase li nan Rechèch yon Cadeau nan aplikasyon an Nymbot, oswa rele
POST /api/v1/l402/refunds/redeemak yon Rechèch nan epi{"refund_token": "REFUND-...", "balance": "standard"}(Ou nan"pro"Total kredi ale nan balans la (10 sats chak sou estanda, 100 sou Pro); sats ki pa fè yon kredi tout antye rete sou token la pou demand 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"
Reply
{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }