Ezagutza oinarria Garapitzaileak
Saldoa, kargak eta giltzak
Ikusi zer duzun, kargatu Lightning bidez, kargatu automatikoki zure portafoiotik, ikusi eskaera bakoitzak zer kostatu zion, eta kudeatu moduluetatik gakoak.
Orrialde hau automatikoki itzuli da erosotasunerako. Ingelesezko jatorrizkoa da aplikatzen den bertsioa.
Saldoa egiaztatzen ari naiz
Zure bi saldoak, eta gako hauren gehikorra zenbat erabilita dagoen.
GET https://nymbot.ai/api/v1/credits/balance — API gako bat behar du. POST fungitzen ere egiten du, hori espero duten bezeroentzat.
balance zenbalti bi hauek elkarrekin dolarretan daudela Bitcoinren prezio egokian,
zenbaki bakarra espero duten tresnarako (null (zenbakia irakurri ezin bada). Geria guztia
kredituetan eta satsetan dago, eta horrela mantentzen dira saldoak benetan. key eskatu zuen gakoa deskribatzen du. Bere limitua iritsi duen gakoak hala ere saldoa egiaztatu dezake.
Erantzuna
{
"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"
}
}
| Estatusa | Noiz |
|---|---|
401 | Gakoa falta da, ezaguna ez da, anulatua da edo arrailatu da. |
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);
Ordainketa metodoak
Nola gehitu saldoa eta mugak. Lightning izango da metodo bakarra.
GET https://nymbot.ai/api/v1/topup/payment-methods — ez du urrari beharrik.
Sare-kargak 10 eta 1.000.000 satzen artean da; Pro sare-karga batek Pro kreditu bat gutxienez erosi behar du, beraz 100 satzetatik hasten da. Dolar limitak Bitcoinren prezioari jarraitzen diote. bulk_bonus entzusia gehigarria azaltzen du
haserriak handiagoetan, aplikazioan bezalaxe: %10, %15 edo %20 gehiago haserri arrunteetan
500, 1.000 edo 5.000 sats-etik aurrera, eta Pro haserrietan 5.000, 10.000 edo 50.000 sats-etik aurrera.
Erantzuna
{
"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);
Lightning bidezren kargatzea
Lightning faktura bat egiten du nym-ari kidea dagozkion kredituak gehitzeko. Itxi Lightning portafoi edozein erabiltuz, ondoren egiaztatu kreditu hori gehitu izateko.
POST https://nymbot.ai/api/v1/topup/create/btc-lightning — API gako bat behar du.
| Kalea | Idatzi | Beharrezkoa | Deskribapena |
|---|---|---|---|
amount | zenbakia | Bai | Zer kantitate, currencyZenbakizur oso bat satsentzat. |
currency | saria | Ez | SATS (berezgaia), USD edo BTCDolarrak Bitcoinren prezio egokian bihurtzen dira. |
tier | saria | Ez | pro (egoargarria) edo standard: zein saldo biltzen duen kreditu hori. |
Kreditu standard bat 10 sats da eta Pro kreditu bat 100 sats, lote bulkiko edozein bonusa gehitu eta;
credits faktura honek zer gehituko du dio dio.
Erantzuna
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"payment_request": "lnbc100u1p5...",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": "2026-09-30T09:27:00Z",
"status": "pending"
}
| Estatusa | Noiz |
|---|---|
400 | Metodo beste bat bidean (unsupported_method), moneta ezaguna bat (unsupported_currency) edo maila, falta falta falta kopurua, edo minimuma azalerako kopurua (amount_too_small), 1,000,000 sats baino gehiago (amount_too_large) edo Lightning wallet-ek uko egin dien (amount_out_of_range). |
429 | Inozte batetik igaro, faktura 60 baino gehiago antzinako izen honekin, edo 120 antzinako onesibide honekin (rate_limit_exceeded, ,rekin Retry-After). |
502 | Ez da faktura egin ahal orain mascato (invoice_unavailable, ,rekin 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);
Sare-betetzea egiaztatzen ari naiz
Faktura ordaindu den jakin nahi du eta, ordaindu denean, kredituari gehitzen dio. Egiaztapenak dira kredituak ematen dituenak, beraz, ordaindu ondoren, egoera den arte egiaztatu. credited. Berriro egiaztatzea segurua da gero: kredituak behin bakarrik iristen da, zenbat aldiz eskatu ez baduzu.
GET https://nymbot.ai/api/v1/topup/status/{invoice_id} — faktura egin zuen nym-etik giltza bat behar du.
status da pending (oraindik ez pagatu), paid (ordaindu, baina oraindik
kreditatuta ez; begiratu berriro), credited (zure saldoan) edo expired (ez da ordaindu
garaiz). Saldo-aldia faktura kargatzen den mailarako da.
Erantzuna
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"status": "credited",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": null,
"balance_credits": 523.33,
"balance_sats": 52333
}
| Estatusa | Noiz |
|---|---|
400 | ID ez da sortze deiaren 64 karaktereko IDa. |
404 | Ez dago faktura horretako ID horretarako zure nym-erako (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);
Bilaketa historia
Eskaera bakoitzeko fila bat: zer zen, zein modelo, zenbat token eta zenbat kostatu zen. Ez da promptik edo erantzunetik ez da gordetzen, beraz ez da ezta innone itzuliz. Filak 90 egunetara arte gordetzen dira, berriena lehenik. Bere limitea iritsi duen gako batek bere historia oraindik irakurri dezake.
GET https://nymbot.ai/api/v1/queries/history — API gako bat behar du, bere eskaerak ikusten dituena, edo eskari sinratua zu zure izen sekretuaren bidez, bakoitzaren gakoa ikusten duena.
| Kalea | Idatzi | Beharrezkoa | Deskribapena |
|---|---|---|---|
page | entegeroa (bilaketa) | Ez | Berezkoratua 1, gehien 1.000; orri altuago bat da 400 invalid_value. |
page_count | entegeroa (bilaketa) | Ez | Orrialdeko lerroak. Oinarrizkoa 20, gehienez 100. |
start_dateend_date | testuinguru (bilaketa) | Ez | ISO 8601 datak edo orduak. |
model | testuinguru (bilaketa) | Ez | Modela hau bakarrik. |
type | testuinguru (bilaketa) | Ez | chat, responses, messages, image, video, speech, transcription edo embedding. |
all_keys | boolean (entzibila) | Ez | Txertarekin: true hamaika izenberdiko izen bakoitzaren gako guztia barne hartzen ditu. Bifazkoa false. |
key_id | testuinguru (bilaketa) | Ez | Eskaera sinatutako batekin, edo... all_keys=true: gako hau bakarrik. |
Erantzuna
{
"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);
Kontu eskaerak sinatzea
Gakoak egitea, aldatzea eta ezabatzeko prozesuak, kontu laburpena eta automatikoki eskuetzea ez dute API gako bat behar. Zure nym-etik iristen den sinadura bat behar dute, beraz, filtratutako gako batek bere limitura arte gastatu dezake, baina ez du inoiz beste gako bat egin dezakeen edo bere limitua igota dezakeen.
Aplikazioak hau egiten dizu: dena bere... API orrialdeak endpoint hauek erabiltzen ditu. Zure propioko kodean daudela gakoak kudeatzeko atal hau bakarrik behar duzu.
Sinadura 27235 motako Nostr ekizado bat da (NIP-98), base64 kodatuta bidaltzen dena...
Authorization titulua hitza dagoena Nostr aurrean:
Txapelkidea
{
"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": "..."
}
ueskaeraren URL osoa da, eskatzailearen stringa barne, bidali bezala zehaztasun osoan.methodHTTP metodoa da.payloadeskaera-gorrizkoaren SHA-256a da, hex formatuan. Honetan beharrezkoa daPOSTetaPATCH, eta bidaltzen duzun korpua byte bakoitzeko bera izan behar du hash egin duzuna.created_atzerbitlaritzaren orduarekin 60 segunduko ezinbesteko margoan egon behar du.- Gertakari bakoitza behin egiten da, a
GETbarne hartua, beraz, hartutako burulegidi bat ez da berrerikatu daitekeena. Sinatu berri bat eskaera bakoitzerako. Gehitu...noncebalio alokatu baten arau ditzake taga berri alokatuarekin, beraz, segundu berean zigunltuak ere desberdinak izan daitezela. - Eskakizun sinatutako baten oihala gehieneko 64 KB izan daiteke, eta ohi bati behar dio
Content-Type: application/json.
Gertakari galditu bat itzultzen da 401 missing_nostr_auth; formatu txarriakoa, sinadura txarra duena, oso zaharra dena, edo URL, metodo edo kide ezberdin batentzat dagoena, hau itzultzen du
invalid_nostr_auth, mezuan arrazoia dagoen ariarekin; berriz erabiltutakoa bueltatzen da
nostr_auth_replayed. Honeetako endpointetara bidalitako API gako bat baztertzen da. Azpixatura
testugatzen da oihala irakurri baino lehen, eta helbide bakoitzak minutako 30 txan
entzun dezake (IPv6 helbide bat bere /64 osoa kontatzen da); horren ostean 429 rekin
Retry-After.
Browserek endgameinak hauek Nymbot-en propioko webguneetatik soilik dei ditzakete (https://nymbot.ai,
https://nymchat.app eta haien subdomeinetan). Beste edozein webgunean dagoen orrialdeak ez ditu CORS
txertakaririk jasotzen, beraz, ezin ditu itzultzen dituenak irakurri. Scriptek eta aplikazio natiboek, ez dituztenek
Origin, ez dira afetatu.
Sinadura honek zure nym-aren gako sekretua behar du (the nsec), dena kontrolatzen duena: zure identitatea, zure historia eta zure saldoa. Ez duzu script batean jarri beharzu zuretzain fidatzen zaren makina batean, ingurunearen bidez irakurri eta ez filean idatzi, eta aplikazioa aukeratu preferentzialki ahal izaten duzun guztian.
Laguntzaile hauek esteka eraikitzen dute. Orrialde honetako ondorengo adibideek haiek erabiltzen dituzte. Hex formatuan dagoen sekretu-gakoa irakurtzen dute NOSTR_SECRET_HEX; cURL-enak erabiltzen du
nak komando-lerroko tresna, nsec edo hex
gako bat hartzen duena, eta sha256sum (macOS-en, 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");
}
Kontuaren laburpena
Apparen API orrialdeak goialdean erakusten duena: zure sarbide publikoa, saldo bi guztiak, zein gako diren
aktiboak (ez benjaminatuak edo irauberritutakoak), eta igoera automatikoa ajurgeriak, edo
null zerbitzarrak ez dituen eskaintzen duenean.
GET https://nymbot.ai/api/v1/account — bat behar du eskari sinratua.
Erantzuna
{
"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());
Gakoak kudeatzea
App-aren gako zerrendaren atzean dauden puntendiburuak. Guztiak behar dute a sinadu duen eskaria. Gako bakoitza forma honetan itzuliko da, denborak ISO 8601 formatuan eta zenbakierak satsetan:
Objetu gakoa
{
"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 nahikoa da giltza ezagutzeko, baina ez erabiltzeko. Giltza berera behin bakarrik itzul daiteke, egiten denean.
Teketei zerrendak egitea
GET https://nymbot.ai/api/v1/keys — sinadua.
| Kalea | Idatzi | Beharrezkoa | Deskribapena |
|---|---|---|---|
include_revoked | boolean (entzibila) | Ez | Sartu kendetu ziren gakoak. Lehentzietarako. false. |
Erantzuna
{ "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);
Gako bat egiten ari naiz
POST https://nymbot.ai/api/v1/keys — sinadua. Itzulitakoak 201.
| Kalea | Idatzi | Beharrezkoa | Deskribapena |
|---|---|---|---|
name | saria | Bai | 1 eta 40 karakter arteko, zure beste giltza aktiboetatik ezberdina (kasua ez jurtuz). |
limit_sats | entegeroa | Ez | Gastu geharketa batas limitazioa, gutxienez 1. Utzi alkat limitazioa ez badu. |
reset_period | saria | Ez | daily, weekly edo monthly. Beharrak limit_satsEz behezu inoiz resetatzen ez den tope batentzat. |
expire_at | testuingurua ala integerra | Ez | Gakoa funtzionatzen uzten duenean: ISO 8601 denbora bat, edo milisegundoak 1970tik bertara. |
Erantzuna (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"
}
}
| Estatusa | Noiz |
|---|---|
400 | Izena falta da edo urすぎる luzea da; izen bat erabiltzen dagoela ere (duplicate_name); gutxienez 1 osagarri osoa ez den tope bat; tope gabeako reset aldia; iraganeko berakhiratzea; talde ezagun bat (unknown_parameter); edo 25 gako aktibo jada (too_many_keys). |
429 | Nym honek egindako 60 giltza baino gehiago, edo helbide honetatik 120, ordu batean (rate_limit_exceeded, ,rekin 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);
Gako bat irakurtzea
GET https://nymbot.ai/api/v1/keys/{id} — sinadua.
Iturriak {"data": {…}} objetdu klaretekin, edo 404
key_not_found ez bada zureren klagatik ez du ID hori.
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);
Gako bat aldatzea
PATCH https://nymbot.ai/api/v1/keys/{id} — sinadua.
Bidali edozein name, limit_sats, reset_period eta
expire_at, giltza egiten dueneko bezalako arau berdinekin. null txanpa bat garbitzen du
eremua: ez dago limitaziorik, ez resetarik, ez expiraziorik. Reset garaiari aldaketa egiteak zeroan bermea berri bat hasten du.
Gatziotako gako bat ez da aldatu daitekeela (400 key_revoked). Itzulera
{"data": {…}} txertatutako giltza objektuarekin.
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);
Gako baten kanporatzea
DELETE https://nymbot.ai/api/v1/keys/{id} — sinadua.
Gakoa berehala gelditzen du, betiko. Zerrendan geratzen da honekin revoked_at hornitu, eta ikus daiteke
...rekin include_revoked=true. Jada anulatua dagoen gako bat anulatzeak modu berean erantzuten du. Anulatutako gako berrienetako 50 soilik gordetzen dira; beste bat anulatzen denean, zaharragoak ezabatzen dira.
Erantzuna
{ "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
Konektatu Lightning portafoi batea Nostr Wallet Connect erekin eta Nymbotek saldoa berez betetzen du API gastuak txikiena iristen denean. Apparen API orrietan doako konfigurazio hauek daude; hauek etaude horren atzean kokatutako endpoint-ak. Guztiak behar dute eskari sinratua.
Modu e maneraetan funtzionatzen du: API eskaera bat zure monitorizazioan saldoa aukeratu duzun eskaeraren kostean kargatzen denean, balansua zure limitagarria baino txikiagoa bada, Nymbot-ek zureren kargapen kopuruaren faktura bat egiten du, zure portafoiari ordain dezala eskatzen dio, eta kreditu hori gehitzen du. 5 minututan behin gehiago kargatzen du nym eta saldo bakoitzarengatik, beraz, eskaera bat-batean egitenak ez du portafoiari ezerna egin dezakeen. Aplikazioetan gastatzeak ez du prozesu hori aktibatzen. Azken kargapenaren unea eta tamaina, eta azken errorea, konfigurazioan daude; errore baten ondoren ordainketa bat egin bada, bere faktura egiaztatzea... egarritzearen egoera Kreditu ematen dio.
Lotura-sormenek nor berek du, zure portafoiak ordaindu dezan eskatzeko aukera ematen dio. Nymbot
ordezkatuta gordetzen du eta bere kargak pagatzeko soilik erabiltzen du, baina
justo hauentzat lotura bat sortu, zure portafoiako gastu-aurrekontu batekin,
beraz, gehien ordain dezakeen zenbakia zureak hautuatutakoa izango da. Portafoiak
laguntzea beharrezkoa da pay_invoice.
Portafolio bat konektatzea
POST https://nymbot.ai/api/v1/nwc-auto-topup/connect — sinadua.
| Kalea | Idatzi | Beharrezkoa | Deskribapena |
|---|---|---|---|
nwc_url | saria | Bai | Lotura-saria, hasten da nostr+walletconnect://. Nymbot-ek portafoiari eskatzen dio get_info gorde aurretik, eta enkriptatuta gordetzen du. |
threshold_sats | entegeroa | Bai | Egoera hau sartzen denean sartu saldoa honako satts hau errutik beherago dagoenean. Gutxienez 1,000. |
topup_sats | entegeroa | Bai | Zer kantitate gehitu behar da bakoitzean. 1,000 ate 1,000,000 sats. |
tier | saria | Ez | pro (egoargarria) edo standard: saldoa zaindu eta kargatu beharrekoa. |
Erantzuna
{
"data": {
"connected": true,
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
"last_topup_at": null,
"last_topup_sats": null,
"last_error": null
}
}
| Estatusa | Noiz |
|---|---|
400 | Ez da konexio-aktibategia (invalid_nwc_url); portafølioak ez zuen erantzun bere errelea bidez (nwc_unreachable) edo egiaztapena uko egin zuen (nwc_rejected); konexioak fakturak ezin ditu ordaindu (nwc_missing_permission); edo muguen kanpoko kantitate bat. |
501 | Sarrerako top-up automatikoak ez daude켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜켜nwc_unavailable). Bera egiten da beste bi puntuko bidezko terminoz ere. |
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());
Konfigurazioak irakurtzen ari naiz
GET https://nymbot.ai/api/v1/nwc-auto-topup — sinadua.
Konektatzeak ematen duen objektu bera itzultzen du, ...-rekin. connected: false eta beste eremuak
null portafolio baten konexioa ez dagoenean. Konexio-saria ez da inoiz
entzermaten.
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());
Konektatuta uzten ari da
DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection — sinadua.
Konexio-testua gordtzen den stringa ezabatzen du. Ez da gehiago lehentasuna/igoera (top-up) egingo. Ziurtatzeko, zure portafolioan konexioa kendu ere dezakezu.
Erantzuna
{ "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());
Eskaera bakoitzeko ordainketa giltzarik gabe
Prezio fikoko terminak Lightning bidez eskaera bat txarretan ordaindu daitezke, giltzarik gabe,
konturik gabe eta saldoik gabe: POST /images/generations, POST /images/edits,
POST /videos, POST /audio/speech, POST /audio/transcriptions,
POST /audio/translations eta POST /embeddings. Txatak, Erantzunak eta
Mezuak beti behar dute gako bat. Gako bat daramatzan eskaera ohiko bezala saldu egiten da salduko saldoan;
ordainketa fluxoak gako bat bidali ez denean hasi egiten da bakarrik.
Nymbot-ek ideia beraren bertsio bi hitz egiten ditu, backend batetik: Lightning Labs'
L402 (hainero ere bere izen zaharrean onartzen dena, LSAT) eta IETF drafta
Ordainketa HTTP autentikazio esquema honekin lightning metodoa eta
charge asmoa. Erabili zure bezeroak ulertzen duen edozein.
Ordainketa giltzarik gabe bakarrik ondu dagoenean API_L402_SECRET gutxienez 32 byte aleatorio du, hex bezala (64 karakter) edo base64 bezala (44). Egiteko bat egin mezuarekin openssl rand -hex 32.
Balio labunagoa edo asmatzeko erraza batak eziztu egiten du ezaugarria eta zergatia erregistratzen du. Aldatzeko, balio zaharra mugitu eginzu API_L402_SECRET_PREVIOUS egun batez: izendapenak, egoeraren URLak eta horren bidez egindako erronkak ira egiten duten arte funtzionatzen jarraitzen dute.
Erronka
Bidali eskaera ez dagoen bezala Authorization titulua. Baliozkoa bada, ez da ezer funtzionatzen eta
zerbait jasotzen duzu 402 Payment Required eskaera horrek eskatzen duen zenbatekoa zehatz eginez faktura batekin:
gako batek ordainduko lukeen irabazi berdinak, 10 sats standard kreditugatik edo 100 sats Pro kreditugatik bihurtuta
eta sat oso bateraino goraondoztatua (gutxienez 1 sat, eta gutxienez 0.05 kredituko minimoa).
erantzunak hiru darama WWW-Authenticate faktura bera uchun errongak:
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 }
}
Ordainketa request parametroa base64url JSON da:
{"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.
Zaila dago erronka amaieragatik lotuta, Content-Type (bere media mota eta,
multipartentzat, bere muga) eta bidali ditzuen korpuzko byte zehatzen SHA-256-ra, eta 15
minutuko iraupena du. Ordaindu<|image><tool|> identiko berriro eskatu: bera bera
Content-Type eta JSON byte berdinak, edo multipart endpoint-entzat
(/images/edits, /audio/transcriptions, /audio/translations)
hainbat parteko gorputz bera muga bera erabiliz. HTTP liburutegi gehienek muga berri bat hautatzen dute formulario bat kodatzen duten bakoitzean, beraz, kodeatu ezazu behin eta bidali byte horiek bi aldiz.
Helbide bakoitzak minutaren batean 30 erronka eskat ditzake (IPv6 helbide bat bere /64 osoa bezala kontatzen da).
Helbidea ez ezaguna den eskaerak minutaren batean 10 eskatzen dituzte, eta Nymbot-ak helbide guztietan erronkak emateko gehieneko muga bat dago; erronka egin baino lehen uko egiten den eskaera bat (adibidez, JSON baliozkoa ez den body baten ondorioz) ez da muga horretan kontatzen. Horretaz haratago erantzuna da 429 rekin Retry-After, ukoez sentia oharrak irakurri baino lehen.
Gako edo kredentzia gabe deifikatzen diren puntuak ere kontatzen dira helburu orokorraren barruan:
minutako 120 eskaera autentikatu gabeko bidaia zelada bakoitzeko. Kredentzia bat egiaztatzen da oharrak irakurri baino lehen, eta
eskaera baten... Content-Type ez da application/json (edo
multipart/form-data (ibilgaitzetarako) uko egiten zaio _________________ bidez 415 eta inoiz ez du
faktura bat jasotzen.
Embeddings-en prezioa inputeko tokenen estimatetik kalkulatzen da, 1.5× margenarekin, kontatu benetarraa geroago soilik ezagutzen baitzaio, eta token benetan erabiltzen direnengatik ordaintzen duzu, eta ordainketaren parte erabili ez dena itzuliko da... gelduruko tokena.
Ordainketa bidaltzen ari naiz
Ordaindu faktura Lightning wallet edozeinarekin. Walletak preimagea emango dizu, 64 hex karakteretakoa. Ondoren, bide hauetako bat erabiliz eskatza bera bidali:
| Plana | Titulua |
|---|---|
| L402 | Authorization: L402 <macaroon>:<preimage> (LSAT fungitzen ere egiten du) |
| Ordainketa | Authorization: Payment <base64url JSON>, non dago JSONa {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}} |
Ordainduko eskaera baten erantzuna txertatutako giltzaren batekin egindakoaren beretikakoa da, ez arraia hau izan salbu nymbot
objektuak ez ditu saldo-aldareak: {"payment": "l402", "tier": "pro", "paid_sats": 237,
"charged_sats": 237}, eta ez dago X-Nymbot-Balance-Sats titulua. A
Ordainketa mota horretarekin ordaindu den eskaera batek ere % Payment-Receipt header (base64url
JSON erronkiaren IDarekin, ordainketa hasharekin bezala reference, status eta
timestamp). Erakarketa ordainduak ez dira izenใดekin lotuta, beraz ez dira agertzen
bilaketa historikoan.
| Estatusa | Noiz |
|---|---|
402 payment_already_used | Ordainketa bakoitzak eskaera bat ordaintzen du. Erantzuna eskaera honen erronka berri bat da, beraz, azken kredentzia gordetzen duen bezero bat (bezala lnget berriro ordaintzen du soilik. |
402 payment_mismatch | Izendapena beste puntendiko batenentzat ematu zen, Content-Type edo gorputza, edo orain eskaera honen kostua honetan baino gutxiago ordaindu du. Eskaera honentzat erronka berri bat dator; ordainketa txikiegia izan bada, ordaindu duena itzultzen da gelduruko tokena (refund_token eta refund_sats gorputzean. |
402 payment_expired | Erronketik 15 minutu baino gehiago igaro dira. Erronka berri bat datorronik. Preimageak ordaindu duela erakusten badu, ordaindu duzuna itzuli egingo da... bezala gelduruko tokena (refund_token eta refund_sats lainan), behin; orduan kredentiala erabiltuta geratzen da. |
401 invalid_preimage | Aurrez-irudia ez da fakturaren ordainketaren hashera konpondutzen. Ordainketa ez dago erabiltuta. |
401 invalid_payment_credential | Kredentzialak oker doa, Nymbot-ek emandakoan aldatu da, edo Nymbot-ek faktura inoiz eman ez duen ordainketa-hash bat izendatzen du. Nymbot ez dakien ohar bat duen macaroon bat, edo ohar konfrontatzaileak dituena, baztertuta dago. |
429 rate_limit_exceeded | Berrikuntza edo gako 30 baino gehiagok berifikatzeko ez zuten funtzionatu bertan minuteko tartean, edo pistu baten itzultzeko tokena 60 baino gehiagotan bidali zen minuteko tartean. Itxaron 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"));
Klienteak eraikiak ⇩ mppx Lightning metodo batekin ordainketa erronka kudeatuko dute; puntatuko dituzte amaieragura eta ordaindu erasiko dute.
Bideoak
Ordaindu duena POST /videos erantzunak 202 gakoa duen bezala, eta agindutakoa
status_url: GET lanari jarraipen egiteko giltzarik gabe. Sinaturata dago
eta 24 ordu funtzionatzen du, lana mantentzen den bitartean.
{
"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..."
}
}
Gorde... refund_token hain honekotik irampen honekin: hemen bakarrik erakusten da. Bideoa prozesatzen den bitartean hutsik dago (GET /api/v1/l402/refunds erantzunak "status": "pending");
rendertzeak fakturagabe huts egiten badu, ordainketa horretan amaitzen da. Egoeraren URLak erakusten du
refund_sats lan errefundatu batentzat, baina inoiz ez tokena, beraz egoera URLa partekatzeak ez du errefunda partekatzen. Tokena egiaztatzeak, inork poltsatu ez zuen falla egindako lana ere konpontzen du.
Diru-etorakitzak
Eskaera ordainduak huts egiten badu eta hornitzaileak Nymbot bilgarri hartzen badu saialdiaren trantzean, ordainketa gordetzen da eta
erroreak horrela dio, honekin charged_sats, gakoarekin eskatutako baten bera bezala zehazki. Erregistroa ordaindu gabe huts egiten bada, erroreak zerbait darama gelduruko tokena ordaindu duzun balioa:
{
"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"
}
}
Erabiltzatik gabe gordetako piezak modu berean itzultzen dira: bi irudi eskatu badituzu eta bat fakturatu gabe huts egin badu,
arrakasta erantzunaren nymbot objektuak falta denaren erstatetik diru-etorera berpentseko token bat darama;
hasieran irakurri ezin izan zen transkripzioaren irauera fitxategiaren irauera gehienaren arabera kobratzen da (30 minututik gehiago ez, inoiz), eta benetako iraurerako aldea diru-etorera berpentseko token gisa itzultzen da; 30 minututik luzagoa dela ikusten badu, errefusatzen da 413
eta ordainketa osoa bueltatzen da. Embedding-ek estimatuek atzera bakoizkoak itzultzen dituzte. Bideo huts batek bere bidalketak itzultzen zuen tokenera eutsi egiten du.
Itzultzeko token bat 256-bitko kode alokatu bat da. Nymbot-ek bere hash-a soilik gordetzen du, eta 30 egun pasatzean prezkatzen da. Sat saldoa du, eta honela egin dezakezu:
- Itzali horrekin ordaindu. Bidali
Authorization: Bearer REFUND-…gozoki horietako edozeinetan (OpenAI SDK batek API gako gisa hartzen du). Prezioa tokenetatik ateratzen da eta geratzen dena horretan geratzen da (refund_token_sats...ennymbotobjektua). Eskaeratik gutxiago balio du tokenak erantzunak402refund_insufficient; kobratu gabeako akats batek sat-ak token berean eraiktzen ditu. - Begiratu.
GET /api/v1/l402/refundsburu berdinarekin itzultzen du{"sats": 237, "status": "open", "expires_at": "..."}. - Token bat minuteko 60 aldiz gehien erabili daiteke.
- Mugitu nym batera. Iontu bertara Egiaztatu regalo bat Nymbot aplikazioan,
edo deitu
POST /api/v1/l402/refunds/redeema baten</h4> eskari sinratua eta{"refund_token": "REFUND-...", "balance": "standard"}(edo"pro"). Kreditu osoak saldoan doaz (10 sats bakoitza standard-ean, 100 Pro-n); kreditu oso bat ez egiten duten satsak tokenean geratzen dira API eskaeraentzat.
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"
Erantzuna
{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }