Ugrás a tartalomhoz
Vissza a Nymbothoz

Tudásbázis Fejlesztők

Egyensúly, top-up és kulcsok

Ellenőrizze, hogy mi van, felsorolja a Lightning-t, automatikusan felsorolja a saját pénztárcáját, nézze meg, mennyi minden egyes kérés költsége, és kezelje a kulcsokat a kódból.

Ellenőrizze az egyensúlyt

Mindkét egyensúlyt, és hogy mennyi a kulcs fedelét használják.

GET https://nymbot.ai/api/v1/credits/balance Szüksége van egy API kulcsra. POST Az ügyfelek számára is, akik ezt várják.

balance a két egyenleg együtt dollárban a jelenlegi Bitcoin áron, olyan eszközök esetében, amelyek egyetlen számot várnak (null Ha az ár nem olvasható). a többi a hitelekben és az árakban van, így a mérlegek ténylegesen megmaradnak. key Az a kulcs, amely elérte a határértéket, még mindig ellenőrizheti a mérleget.

Válasz

{
  "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"
  }
}
státuszMikor
401A kulcs hiányzik, ismeretlen, visszavont vagy lejárt.

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);

Fizetési módok

Hogyan lehet felszínre, és a határok. villám az egyetlen módszer.

GET https://nymbot.ai/api/v1/topup/payment-methods Nincs szükség kulcsra.

A top-up 10 000-1 000 000 sats; a Pro top-upnak legalább egy Pro-hitelet kell vásárolnia, így 100 sats-on kezdődik. bulk_bonus felsorolja az extra kredit nagyobb top-up, ugyanaz, mint az alkalmazásban: 10%, 15% vagy 20% -kal több a standard top-up 500, 1000 vagy 5000 sats, és a Pro top-up 5000, 10,000 vagy 50,000 sats.

Válasz

{
  "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);

Felemelkedés a villám felett

Készít egy Lightning számlát, amely hozzáadja a hitelt a nymhez, amelyhez a kulcs tartozik. Fizessen bármilyen Lightning pénztárcából, majd Ellenőrizze A hitel hozzáadása.

POST https://nymbot.ai/api/v1/topup/create/btc-lightning Szüksége van egy API kulcsra.

mezőtípusSzükségleírás
amountszámIgenMekkora mértékben, a currencyEgy egész szám a téthez.
currencyStringnemSATS (A meghibásodás USD vagy BTCA dollár az aktuális Bitcoin áron kerül átváltásra.
tierStringnempro (a lejárati idő) vagy standard: melyik egyensúlyba kerül a hitel.

A standard hitel 10 sats és egy Pro hitel 100 sats, plusz bármilyen ömlesztett bónusz; credits mondja meg, hogy ez a számla hozzáteszi.

Válasz

{
  "invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
  "payment_request": "lnbc100u1p5...",
  "amount_sats": 10000,
  "credits": 115,
  "tier": "pro",
  "expires_at": "2026-09-30T09:27:00Z",
  "status": "pending"
}
státuszMikor
400Egy másik módszer az úton (unsupported_method) ismeretlen pénznem (unsupported_currencya) a hiányzó összeg, vagy a minimális érték alatti összeg (amount_too_small1 millió forint felett (amount_too_large) vagy elutasították a Lightning pénztárca (amount_out_of_range).
429Több mint 60 számla erre a nymra, vagy 120 ezen a címen, egy óra alatt (rate_limit_exceededAzokkal a Retry-After).
502Jelen pillanatban nem lehet számlát adni (invoice_unavailableAzokkal a 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);

Ellenőrizze a top-up

Megkérdezi, hogy a számlát kifizették-e, és ha van, hozzáadja a hitelt. Ellenőrizze, hogy mit hitelez, így a kifizetés után ellenőrizze, amíg az állapot creditedA későbbiekben ismét ellenőrzés biztonságos: a hitel egyszer leszáll, függetlenül attól, hogy hányszor kér.

GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - szüksége van egy kulcsra a nym-től, amely a számlát készítette.

status az pending (még nem fizetett ki) paid (fizetett, de még nem hitelesített; ellenőrizze újra), credited (az Ön mérlegénél) vagy expired (Nem fizetve időben) A mérleg mezők a számla felső szintjei.

Válasz

{
  "invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
  "status": "credited",
  "amount_sats": 10000,
  "credits": 115,
  "tier": "pro",
  "expires_at": null,
  "balance_credits": 523.33,
  "balance_sats": 52333
}
státuszMikor
400Az id nem a létrehozott hívás 64 karakteres azonosítója.
404Nincs számla az ID-vel a nym (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);

Történelem akar

Kérésenként egy sor: mi volt, milyen modell, hány token és mennyibe kerül. Nincs meghívó vagy válasz, így senki sem tér vissza. A sorokat 90 napig őrizzük meg, először a legfrissebb.

GET https://nymbot.ai/api/v1/queries/history - szüksége van egy API kulcsra, amely saját kéréseit látja, vagy egy Aláírt kérelem A nyomaidból, amely minden kulcsodat látja.

mezőtípusSzükségleírás
pageA kérés (query)nemAlapértelmezett 1, legfeljebb 1000; egy magasabb oldal 400 invalid_value.
page_countA kérés (query)nemOldalonkénti sorok. Alapértelmezett 20, legfeljebb 100.
start_date
end_date
A kérés (query)nemISO 8601 dátumok és időpontok.
modelA kérés (query)nemCsak ezt a modellt.
typeA kérés (query)nemchat, responses, messages, image, video, speech, transcription vagy embedding.
all_keysA kérés (query)nemAz egyik kulcs: true tartalmazza ugyanazon nym. alapértelmezett kulcsát false.
key_idA kérés (query)nemAz aláírt kérelemmel, vagy all_keys=trueCsak ezt a kulcsot.

Válasz

{
  "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);

Elszámolási kérelmek aláírása

A kulcsok létrehozása, megváltoztatása és visszavonása, a fiók összefoglalása és az automatikus felülvizsgálatok nem veszik fel az API kulcsot. Az aláírást a nym-től veszik fel, így a szivárgott kulcs a határt meghaladhatja, de soha nem hozhat létre egy másik kulcsot, vagy nem emelheti meg saját határt.

Az alkalmazás ezt teszi az Ön számára: mindent a saját tűz A sheet ezeket a végpontokat használja. Csak a saját kódodból származó kulcsok kezeléséhez szükséges ez a szakasz.

Az aláírás egy 27235 (NIP-98) típusú Nostr esemény, amelyet a Authorization Header a szóval Nostr Az előtérben:

Az esemény

{
  "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 a lekérdezés teljes URL-címét tartalmazza, beleértve a lekérdezéssorozatot is, pontosan úgy, ahogyan azt elküldték.
  • method A HTTP módszer.
  • payload az SHA-256 a nyers kérelem test, hex. POST és PATCH, és az a test, amelyet elküldesz, bajtnak kell lennie a bajtnak, amelyet hasheltél.
  • created_at 60 másodpercen belül kell lennie a szerver órájának.
  • Minden esemény egyszer működik, a GET beleértve, így a rögzített fejlécet nem lehet újra lejátszani. Jelentkezzen be egy új fejlécbe minden egyes kéréshez. nonce véletlenszerű értékkel jelölje meg, hogy ugyanazon a másodpercben aláírt két kérés még mindig eltérjen.
  • Az aláírt kérés teste legfeljebb 64 KB lehet, és a szervezetnek szüksége van Content-Type: application/json.

A hiányzó esemény visszatér 401 missing_nostr_authrosszul kialakult, rosszul aláírt, túl régi, vagy más URL-t, módszert vagy testet ad vissza invalid_nostr_auth, az üzenetben szereplő okkal; egy újrafelhasznált visszatér nostr_auth_replayedAz aláírást a test elolvasása előtt ellenőrizzük, és minden cím percenként 30 alkalommal meghibásodhat (egy IPv6 cím egészként számít /64); ezután kap 429 Azokkal Retry-After.

A böngészők csak a Nymbot saját webhelyeiről hívhatják ezeket a végpontokat (https://nymbot.ai, https://nymchat.app Egy oldal bármely más webhelyen nem kap vissza CORS fejléceket, így nem tudja elolvasni, amit visszaküldenek. Originnem érintik őket.

A titkos kulcs

Az aláírásnak szüksége van a nym titkos kulcsára (a nsec), amely mindent irányít: a személyazonosságot, a történelmet és az egyensúlyt. Csak helyezze el a forgatókönyvben egy számítógépen, amelyben bízik, olvassa el a környezetet, ahelyett, hogy leírná a fájlba, és előnyben részesítse az alkalmazást, ha lehetséges.

Ezek a segédeszközök építik a fejléceket. Az ezen az oldalon található későbbi példák használják őket. A titkos kulcsot hexben olvassák el NOSTR_SECRET_HEXA cURL az egyiket használja Édesanyám parancsfájl, amely egy nsec vagy hex kulcsot vesz igénybe, és sha256sum A macOS esetében, 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");
}

A számla összefoglalója

Amit az alkalmazás API-lapja a tetején mutat: a nyilvános kulcs, mindkét egyenleg, hány kulcs aktív (nem visszavont vagy lejárt), és a Automatikus top-up beállításait, vagy null Ha a szerver nem adja meg.

GET https://nymbot.ai/api/v1/account Szükség van a Aláírt kérelem.

Válasz

{
  "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());

Kulcsok kezelése

A végpontok mögött az alkalmazás kulcslista. mindegyiküknek szüksége van egy Aláírt kérelemMinden kulcs a következő formában kerül visszaküldésre, az ISO 8601 szabványban szereplő időkkel és összegekkel:

Kulcsobjektum

{
  "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 A kulcsot csak egyszer lehet visszaküldeni, ha elkészül, de nem használni.

Kulcsszavak listázása

GET https://nymbot.ai/api/v1/keys Az aláírt.

mezőtípusSzükségleírás
include_revokedA kérés (query)nemEltávolított kulcsok. alapértelmezett false.

Válasz

{ "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);

Hozzon létre kulcsot

POST https://nymbot.ai/api/v1/keys Visszatérés - Visszatérés 201.

mezőtípusSzükségleírás
nameStringIgen1–40 karakter, amely különbözik a többi aktív kulcsodtól (az eset figyelmen kívül hagyása).
limit_satsIntegrálnemA kiadási kapszula a sats-ban, legalább 1. Hagyja ki a kapszulát.
reset_periodStringnemdaily, weekly vagy monthlyszükségletei limit_satsHagyja ki egy olyan sapkát, amely soha nem áll vissza.
expire_atstring vagy integernemAmikor a kulcs leáll: ISO 8601 idő, vagy milliszekundum 1970 óta.

Válasz erre (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"
  }
}
státuszMikor
400Hiányzó vagy túl hosszú név; már használt név (duplicate_name); egy kap, amely nem egy egész szám legalább 1; egy visszaállítási időszak nélkül kap; egy lejárati idő a múltban; egy ismeretlen mező (unknown_parameter); vagy 25 aktív kulcs már (too_many_keys).
429Több mint 60 kulcsot készített ez a nym, vagy 120 ebből a címből, egy óra alatt (rate_limit_exceededAzokkal a 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);

Egy kulcs olvasása

GET https://nymbot.ai/api/v1/keys/{id} Az aláírt.

Visszatérés {"data": {…}} a kulcsfontosságú objektummal, vagy 404 key_not_found ha a kulcsa nem rendelkezik ezzel az azonosítóval.

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);

A kulcs megváltoztatása

PATCH https://nymbot.ai/api/v1/keys/{id} Az aláírt.

Küldje el bármelyik name, limit_sats, reset_period és expire_atugyanazokkal a szabályokkal, mint amikor kulcsot készít. null a mező eltávolítása: nincs korlát, nincs visszaállítás, nincs lejárat. A visszaállítási időszak megváltoztatása új időszakot indít nulláról. A visszavont kulcsot nem lehet módosítani (400 key_revoked) visszatér {"data": {…}} a frissített kulcsszó objektummal.

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);

A kulcs visszavonása

DELETE https://nymbot.ai/api/v1/keys/{id} Az aláírt.

Megállítja a kulcsot azonnal, jó. továbbra is a listán marad revoked_at beállítva, és láthatók a include_revoked=trueA már visszavont kulcs visszavonása ugyanúgy válaszol. Csak a legújabb 50 visszavont kulcsot tartjuk meg; a régebbi kulcsokat töröljük, ha egy másik kulcsot visszavonunk.

Válasz

{ "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());

Az NWC Auto-top-up

Csatlakoztassa a Lightning-pénztárcát a Nostr Wallet Connect alkalmazással, és a Nymbot önmagában kiegyenlíti az egyensúlyt, amikor az API-kiadások alacsonyak. Aláírt kérelem.

Hogyan működik: miután az API-kérelmet a megtekintésre választott egyenlegre terhelik, ha az egyenleg a küszöb alatt esett, a Nymbot számlát készít a felső összegért, megkéri a pénztárcáját, hogy fizesse meg, és hozzáadja a hitelt. Minden 5 percben legfeljebb egyszer felemelkedik minden nym és egyensúlyért, így a kérelmek kitörése nem tudja kiüríteni a pénztárcát. Az alkalmazásokban való kiadások nem indítják el. Az utolsó felső összeg és az utolsó hiba ideje és mérete a beállításokban van; ha a kifizetés hiba után történt, ellenőrizze a számlát A top-up állapot Ezt hitelesíti.

Mielőtt csatlakoztatná a pénztárcát

A Nymbot titkosítva tárolja, és csak a saját felső számláinak kifizetésére használja, de csak erre a célra hozzon létre kapcsolatot, egy kiadási költségvetéssel a pénztárcájában, így a legtöbbet valaha is fizethet egy szám választott téged. pay_invoice.

Csatlakoztassa a pénztárcát

POST https://nymbot.ai/api/v1/nwc-auto-topup/connect Az aláírt.

mezőtípusSzükségleírás
nwc_urlStringIgenA kapcsolódási lánc, kezdve nostr+walletconnect://Nymbot kéri a pénztárcát get_info mentése előtt, és tárolja titkosítva.
threshold_satsIntegrálIgenAkkor is, ha ez az összeg alacsonyabb, mint ez az összeg, legalább 1000 Ft.
topup_satsIntegrálIgenMennyit kell adni minden alkalommal. 1000-1000 000 sats.
tierStringnempro (a lejárati idő) vagy standard: az egyensúly, hogy figyelemmel kíséri és felső.

Válasz

{
  "data": {
    "connected": true,
    "threshold_sats": 5000,
    "topup_sats": 20000,
    "tier": "pro",
    "last_topup_at": null,
    "last_topup_sats": null,
    "last_error": null
  }
}
státuszMikor
400Nincs kapcsolódási lánc (invalid_nwc_url); a pénztárca nem válaszolt a reléjére (nwc_unreachable) vagy elutasította az ellenőrzést (nwc_rejected); a kapcsolat nem fizet számlákat (nwc_missing_permissionc) a határértékeken kívüli összeget.
501Az automatikus felső felületek nem kapcsolódnak be erre a szerverre (nwc_unavailableUgyanez vonatkozik a másik két végpontra is.

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());

A beállítások olvasása

GET https://nymbot.ai/api/v1/nwc-auto-topup Az aláírt.

ugyanazt az objektumot adja vissza, mint a csatlakoztatás, a connected: false A többi mező null Ha nincs pénztárca csatlakoztatva, a csatlakozási lánc soha nem kerül visszaadásra.

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());

Eltávolítás

DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection Az aláírt.

Eltávolítja a tárolt kapcsolatláncot. Nincs több felsőbbrendűség. Biztos lehet benne, hogy a pénztárcájában is visszavonhatja a kapcsolatot.

Válasz

{ "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());

Fizetés kérésre kulcs nélkül

A fix árú végpontok egyszerre egy kérésre fizethetők a Lightning alatt, kulcs nélkül, számla nélkül és egyenleg nélkül: POST /images/generations, POST /images/edits, POST /videos, POST /audio/speech, POST /audio/transcriptions, POST /audio/translations és POST /embeddingsA Csevegés, a Válaszok és az Üzenetek mindig kulcsot igényelnek. A kulcsot hordozó kérelmet a szokásos módon számlázzák a egyenlegre; a fizetési folyamat csak akkor kezdődik, ha a kulcsot nem küldik.

Nymbot beszél két változatát ugyanazt az ötletet, egy backend: Lightning Labs Lásd 402 (más néven is elismert, LSAT) és az IETF tervezet kifizetés HTTP-hitelesítési rendszer a lightning módszer és charge Használja azt, amit az ügyfél megért.

Saját szerver futtatása

A kulcs nélkül történő fizetés csak akkor lehetséges, ha API_L402_SECRET legalább 32 véletlenszerű bájtot tartalmaz, például hex (64 karakter) vagy base64 (44). openssl rand -hex 32Egy rövidebb vagy kiszámítható érték kikapcsolja a funkciót, és naplózza, hogy miért. API_L402_SECRET_PREVIOUS Egy napig: a hitelesítő adatok, az állapot URL-ek és a kihívások a lejáratukig továbbra is működnek.

A kihívás

Küldje el a kérést nem Authorization ha érvényes, semmi sem fut, és megkapja a 402 Payment Required számlával pontosan azt, amit a kérés költségei: ugyanazt az árat fizetné a kulcs, átalakítva 10 sats egy standard hitel vagy 100 sats egy Pro hitel és lekerekített egy egész sat (legalább 1 sat, és legalább a 0.05 hitel minimum). WWW-Authenticate Kihívások ugyanazon számla esetén:

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 }
}

A kifizetés request A következő paraméter a base64url JSON: {"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.

A kihívás a végponthoz kötődik, a Content-Type (a média típusa és a multipart esetében a határ) és az SHA-256 pontosan a küldött test bajtjait tartalmazza, és 15 percig tart. azonos Ismét kérés: ugyanaz Content-Type és ugyanazokat a JSON bájtokat, vagy a többrészes végpontok esetében (/images/edits, /audio/transcriptions, /audio/translationsA legtöbb HTTP-könyvtár minden alkalommal kiválaszt egy új határt, amikor egy űrlapot kódol, ezért kódolja egyszer, és kétszer küldje el ezeket a bajtokat.

Minden cím 30 kihívást kérhet percenként (egy IPv6-cím az egész /64-nek számít). Azok a kérések, amelyek címét nem ismerik, percenként szigorúbb 10-et osztanak meg, és az összes címre kiterjedő kihívásokra általános korlát van; a kihívás előtt elutasított kérelem (például olyan testtel, amely nem érvényes JSON) nem számít rá. 429 Azokkal Retry-AfterA kulcs vagy hitelesítő nélkül hívott fizetett végpontok szintén a címenként percenként 120 hitelesítetlen kérés általános határáig számítanak. Content-Type Nem az application/json (vagy multipart/form-data A felvételt elutasítják 415 Soha nem kap számlát.

A beágyazásokat a bemenetben lévő tokenek becsléséből állapítják meg, 1,5 alkalommal, mivel a tényleges szám csak később ismert. Visszatérítő token.

A fizetés elküldése

Fizesse ki a számlát bármilyen Lightning pénztárcával. A pénztárca megadja az előnézetet, 64 hex karaktert. Ezután küldje el ugyanazt a kérést az alábbiak egyikével:

rendszerFőoldal
Lásd 402Authorization: L402 <macaroon>:<preimage> (LSAT Ez is működik)
kifizetésAuthorization: Payment <base64url JSON>Ahol a JSON {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}}

A fizetett kérés pontosan úgy válaszol, mint egy kulcs, kivéve, hogy a nymbot Az objektumnak nincs egyensúlyi mezője: {"payment": "l402", "tier": "pro", "paid_sats": 237, "charged_sats": 237}És nincs semmilyen X-Nymbot-Balance-Sats A fizetési rendszerrel fizetett kérés szintén kap egy Payment-Receipt header (base64url JSON a kihívás azonosítóval, a fizetési hash mint reference, status és timestampA fizetett lekérdezések nem kötődnek semmilyen nymhez, így nem jelennek meg a lekérdezések történetében.

státuszMikor
402 payment_already_usedMinden kifizetés egy kérésért fizet.A válasz új kihívást jelent ennek a kérésnek, így egy ügyfél, aki az utolsó hitelesítő adatait (mint lnget Egyszerűen csak újra földet.
402 payment_mismatchA hitelesítő egy másik végpontra került kiadásra, Content-Type vagy a test, vagy kevesebbet fizet, mint ez a kérés most költsége. Egy új kihívás erre a kérésre jön vele; ha a kifizetés túl kicsi volt, amit fizetett, visszatér, mint egy Visszatérítő token (refund_token és refund_sats és a testben).
402 payment_expiredTöbb mint 15 perc telt el a kihívás óta. Új kihívás jön hozzá. Ha az előnézet azt mutatja, hogy fizetett, amit fizetett, visszatér, mint egy Visszatérítő token (refund_token és refund_sats a testben), egyszer; a hitelesítő ezután kihasználva.
401 invalid_preimageA preimage nem hash a számla fizetési hash.
401 invalid_payment_credentialA hitelesítő hibás, a Nymbot kiadása után megváltozott, vagy a fizetési hash nevét a Nymbot soha nem bocsátott ki számlát.
429 rate_limit_exceededTöbb mint 30 hitelesítő vagy kulcs, amely nem sikerült ellenőrizni jött ebből a címből egy perc alatt, vagy egy visszatérítési token küldött több mint 60 alkalommal egy perc alatt. 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"));

Az ügyfelek épülnek mppx A Lightning módszerrel maguk kezelik a fizetési kihívást; mutassák meg őket a végpontban, és hagyják, hogy fizessenek.

Videók

A fizetett POST /videos Válaszok 202 mint egy kulcsszó, plusz a status_url: GET Ez aláírt és működik 24 órán át, mindaddig, amíg a munkát megtartják.

{
  "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..."
  }
}

Tartsa meg a refund_token a válaszból: csak itt látható. Ez üres, míg a videó (GET /api/v1/l402/refunds Válaszok "status": "pending"); ha a renderelés nem kerül elszámolásra, a kifizetés rajta leszáll. refund_sats visszafizetett munkára, de soha nem a tokenre, így az állapot URL megosztása nem osztja meg a visszatérítést.

visszafizetés

Ha a fizetett kérés sikertelen, és a szolgáltató számlázta a Nymbot-ot a kísérletért, a kifizetés megmarad, és a hiba ezt mondja. charged_sats, pontosan úgy, mint egy kulcsszóval ellátott kérés esetében. Ha nem számlázott, akkor a hiba egy Visszatérítő token Megéri amit fizetett:

{
  "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"
  }
}

A fel nem használt alkatrészek ugyanúgy jönnek vissza: ha két képet kértél, és az egyik nem került kifizetésre, a sikeres válasz nymbot az objektum a hiányzóhoz visszatérítést tartalmaz; egy olyan átiratot, amelynek hosszát nem lehetett előre elolvasni, a fájl leghosszabb idejére becsülik (soha ne haladja meg a 30 percet), és a tényleges hosszúság közötti különbség visszatérítést jelent; ha 30 percnél hosszabbnak bizonyul, akkor visszautasítják 413 A beágyazások visszakapják azt, amit a becslés visszatartott.A sikertelen videó visszakapja a visszaküldött benyújtott tokent.

A visszatérítési token egy véletlenszerű 256-bites kód. A Nymbot csak a hashjét tárolja, és 30 nap elteltével lejár.

  • Fizessen vele együtt. Küldje el Authorization: Bearer REFUND-… A fenti végpontok bármelyikén (az OpenAI SDK-t API kulcsként veszi igénybe).refund_token_sats Ebben a nymbot Egy token értéke kevesebb, mint a kérés válaszai 402 refund_insufficientEgy nem számlázott hiba visszaállítja a tétet ugyanarra a tokenre.
  • Ellenőrizze azt! GET /api/v1/l402/refunds Ugyanaz a header visszatér {"sats": 237, "status": "open", "expires_at": "..."}.
  • Egy token percenként legfeljebb 60 alkalommal használható.
  • Helyezze el egy nym. Tegye be a Ajándékozzon ajándékot a Nymbot alkalmazásban, vagy hívjon POST /api/v1/l402/refunds/redeem Az A Aláírt kérelem és {"refund_token": "REFUND-...", "balance": "standard"} (vagy "pro"A teljes kreditek a egyenlegbe kerülnek (10 sats mindegyik standard, 100 pro); az API-kérelmek esetében a tokenben nem maradnak teljes hitelek.

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"

Válasz

{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }