Пређи на садржај
Nazad na Nymbot

База знања Развијачи

Баланс, врхови и кључеви

Проверите шта имате, надгледајте Бљесак, надгледајте аутоматски из сопственог новчаника, видите колико сваки захтев кошта и управљајте кључевима из кода.

Проверите равнотежу

Оба ваше равнотеже, и колико је коришћен поклопац овог кључа.

GET https://nymbot.ai/api/v1/credits/balance Potreban vam je API ključ. POST Такође ради, за клијенте који то очекују.

balance је два баланса заједно у доларима по тренутној цени Битцоин-а, за алате који очекују један број (null ако се цена не може прочитати). остатак је у кредитима и стопама, што је начин на који се салдо заправо чува. key описује кључ који је затражио. кључ који је достигао своју границу и даље може да провери равнотежу.

Odgovor

{
  "balance": 49.18,
  "balance_sats": 42037,
  "standard": { "credits": 120.4, "sats": 1204 },
  "pro": { "credits": 408.33, "sats": 40833 },
  "key": {
    "id": "4f0c9a1be27d3856",
    "name": "laptop scripts",
    "limit_sats": 20000,
    "period_used_sats": 3412,
    "total_used_sats": 18230,
    "reset_period": "monthly",
    "reset_at": "2026-10-01T00:00:00Z"
  }
}
статусКада
401Кључ је нестао, непознат, поништен или истекао.

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

Начини плаћања

Како можете да превазиђете, и границе. муња је једина метода.

GET https://nymbot.ai/api/v1/topup/payment-methods Nije potreban ključ.

Топ-уп је 10 до 1.000.000 стопа; Про топ-уп мора купити најмање један Про кредит, тако да почиње са 100 стопа. bulk_bonus наводи додатни кредит на већим врховима, исти као у апликацији: 10%, 15% или 20% више на стандардним врховима од 500, 1.000 или 5.000 стопа, и на Про врховима од 5.000, 10.000 или 50.000 стопа.

Odgovor

{
  "supported_methods": [
    {
      "method": "btc-lightning",
      "display_name": "Bitcoin Lightning",
      "supported_currencies": ["SATS", "USD", "BTC"],
      "limits": {
        "SATS": { "min": 10, "max": 1000000 },
        "USD": { "min": 0.02, "max": 1170 },
        "BTC": { "min": 1e-7, "max": 0.01 }
      },
      "tiers": ["standard", "pro"],
      "default_tier": "pro",
      "tier_min_sats": { "standard": 10, "pro": 100 },
      "sats_per_credit": { "standard": 10, "pro": 100 },
      "bulk_bonus": [
        { "bonus": 0.1, "standard_sats": 500, "pro_sats": 5000 },
        { "bonus": 0.15, "standard_sats": 1000, "pro_sats": 10000 },
        { "bonus": 0.2, "standard_sats": 5000, "pro_sats": 50000 }
      ]
    }
  ]
}

cURL

curl https://nymbot.ai/api/v1/topup/payment-methods

Python

import requests

methods = requests.get("https://nymbot.ai/api/v1/topup/payment-methods").json()
print(methods["supported_methods"][0]["limits"])

JavaScript

const methods = await (await fetch("https://nymbot.ai/api/v1/topup/payment-methods")).json();
console.log(methods.supported_methods[0].limits);

Подигните се изнад муње

Направља лампе рачун који додаје кредит на ним кључ припада. Платите га из било којег лампе новчаник, онда Проверите га Да бисте добили додатни кредит.

POST https://nymbot.ai/api/v1/topup/create/btc-lightning Potreban vam je API ključ.

ПољеТипПотребнаОпис
amountБројДаКолико је, у currencyЦео број за ставку.
currencyStringНеSATS (Одлука о дефолту USD или BTCДолари се конвертују по тренутној цени Битцоин-а.
tierStringНеpro (понекад је дефект) или standard: на који баланс иде кредит.

Стандардни кредит је 10 стопа и Про кредит 100 стопа, плус било који бонус; credits Каже шта ће овај рачун додати.

Odgovor

{
  "invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
  "payment_request": "lnbc100u1p5...",
  "amount_sats": 10000,
  "credits": 115,
  "tier": "pro",
  "expires_at": "2026-09-30T09:27:00Z",
  "status": "pending"
}
статусКада
400Друга метода на путу (unsupported_method), непозната валута (unsupported_currency) или ниво, недостајући износ, или износ испод минималног (amount_too_small) преко 1.000.000 стопа (amount_too_large) или одбијено од стране Лигхтнинг новчаника (amount_out_of_range).
429Више од 60 рачуна за овај ним, или 120 са ове адресе, у једном сату (rate_limit_exceeded, са Retry-After).
502Тренутно није могуће направити рачун (invoice_unavailable, са 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);

Проверите врхунац

Пита да ли је рачун плаћен и, када га има, додаје кредит. Провера је оно што га кредитира, тако да након плаћања, проверите док статус није creditedПоново проверавање касније је сигурно: кредит долази једном, без обзира на то колико пута питате.

GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - потребан вам је кључ из нима који је направио рачун.

status је pending (Još uvek nije isplaćeno) paid (плаћено, али још није кредитирано; проверите поново), credited (на вашем балансу) или expired (не плаћају на време). Поља биланса су за ниво на којем се врши рачун.

Odgovor

{
  "invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
  "status": "credited",
  "amount_sats": 10000,
  "credits": 115,
  "tier": "pro",
  "expires_at": null,
  "balance_credits": 523.33,
  "balance_sats": 52333
}
статусКада
400ИД није 64-карактерни ИД из позива за креирање.
404Нема фактуре по том ИД-у за ваш ним (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);

Желимо историју

Један ред по захтеву: шта је то било, који модел, колико токена и шта кошта. Не чувају се позиви или одговори, тако да се нико не враћа. Редови се чувају 90 дана, најновији први. кључ који је достигао своју границу и даље може прочитати своју историју.

GET https://nymbot.ai/api/v1/queries/history — потребан је АПИ кључ, који види своје захтеве, или Потписан захтев од твоје ниме, која види сваки кључ.

ПољеТипПотребнаОпис
pageИнтеграција (query)НеПодразумевано 1, највише 1000; већа страница је 400 invalid_value.
page_countИнтеграција (query)НеРедови по страници. Подразумевано 20, највише 100.
start_date
end_date
String (потражња)НеИСО 8601 датуми или времена.
modelString (потражња)НеSamo ovaj model.
typeString (потражња)Неchat, responses, messages, image, video, speech, transcription или embedding.
all_keysБоолеан (у питању)НеСа једним кључем: true укључује сваки кључ истог нима. Подразумевано false.
key_idString (потражња)НеСа потписаним захтевом, или са all_keys=trueSamo ovaj ključ.

Odgovor

{
  "data": [
    {
      "id": "q_71c4e9a0",
      "timestamp": "2026-09-30T08:12:00Z",
      "model": "anthropic/claude-sonnet-5",
      "type": "chat",
      "input_tokens": 1240,
      "output_tokens": 380,
      "cached_tokens": 0,
      "cost_sats": 16.2,
      "cost_usd": 0.01895,
      "balance": "pro",
      "key_id": "4f0c9a1be27d3856",
      "web_search": false,
      "status": "ok"
    }
  ],
  "pagination": { "page": 1, "page_count": 20, "total": 311, "total_pages": 16 }
}

cURL

curl "https://nymbot.ai/api/v1/queries/history?page_count=50&type=chat" \
  -H "Authorization: Bearer $NYMBOT_API_KEY"

Python

import os
import requests

res = requests.get(
    "https://nymbot.ai/api/v1/queries/history",
    headers={"Authorization": "Bearer " + os.environ["NYMBOT_API_KEY"]},
    params={"page_count": 50, "type": "chat"},
)
for row in res.json()["data"]:
    print(row["timestamp"], row["model"], row["cost_sats"])

JavaScript

const res = await fetch("https://nymbot.ai/api/v1/queries/history?page_count=50&type=chat", {
  headers: { "Authorization": "Bearer " + process.env.NYMBOT_API_KEY },
});
for (const row of (await res.json()).data) console.log(row.timestamp, row.model, row.cost_sats);

Потписивање захтева за рачун

Креирање, мењање и повлачење кључева, резиме налога и аутоматски топ-уп не узимају АПИ кључ. Они узимају потпис од вашег ним-а, тако да цурећи кључ може потрошити до своје капије, али никада не може направити још један кључ или подићи сопствени капију.

Апликација ради ово за вас: све у својој Огње листа користи ове крајње тачке. Потребан вам је само овај одељак за управљање кључевима из сопственог кода.

Potpis je Nostr događaj vrste 27235 (NIP-98), koji se šalje baz64 kodiran u Authorization header sa rečju Nostr На предњој страни:

догађај

{
  "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 je potpuni URL zahteva, uključujući niz upita, tačno onako kako je poslan.
  • method To je HTTP metoda.
  • payload је СХА-256 тела сировог захтева, у хексу. POST и PATCH, и тело које шаљете мора бити бајт за бајт оно што сте хасхед.
  • created_at мора бити у року од 60 секунди од сата сервера.
  • Сваки догађај ради једном, а GET укључен, тако да ухваћени наслов не може да се репродукује. Потпишите нови за сваки захтев. nonce означите са случајном вредношћу тако да се два захтева потписана у истој секунди и даље разликују.
  • Тело потписаног захтева може бити највише 64 КБ, а телу је потребно Content-Type: application/json.

Изгубљени догађај се враћа 401 missing_nostr_auth; један који је лоше формиран, лоше потписан, престари, или за другачији УРЛ, метод или тело враћа invalid_nostr_auth, са разлогом у поруци; поновно коришћена једна се враћа nostr_auth_replayedПотпис се проверава пре читања тела, а свака адреса може да га не успе 30 пута у минути (ИПв6 адреса се рачуна као цела /64); након тога добија 429 са Retry-After.

Претраживачи могу позвати ове крајње тачке само са сопствених сајтова Нимбот-а (https://nymbot.ai, https://nymchat.app Страница на било ком другом сајту не добија ЦОРС наслове назад, тако да не може прочитати оно што враћају. OriginNe, oni nisu pogođeni.

Vaš tajni ključ

Potpisanju je potreban tajni ključ vašeg nyma (na nsec), који контролише све: ваш идентитет, вашу историју и ваш баланс. Само га ставите у скрипту на машини којој верујете, прочитајте га из окружења уместо да га напишете у датотеку, и преферирајте апликацију када можете.

Ови помагачи граде наслов. Каснији примери на овој страници их користе. Они читају тајни кључ у хексу од NOSTR_SECRET_HEX; cURL један користи Наки алат командне линије, који узима нсец или хексни кључ, и sha256sum na 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");
}

Резиме рачуна

Оно што АПИ лист апликације показује на врху: ваш јавни кључ, оба баланса, колико кључева је активно (није поништено или истекло), и Automatski top-up подешавања, или null када их сервер не нуди.

GET https://nymbot.ai/api/v1/account Potreban je a Потписан захтев.

Odgovor

{
  "data": {
    "pubkey": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
    "balances": {
      "standard": { "credits": 120.4, "sats": 1204 },
      "pro": { "credits": 408.33, "sats": 40833 }
    },
    "keys_active": 3,
    "nwc_auto_topup": {
      "connected": true, "threshold_sats": 5000, "topup_sats": 20000, "tier": "pro",
      "last_topup_at": null, "last_topup_sats": null, "last_error": null
    }
  }
}

cURL

URL=https://nymbot.ai/api/v1/account
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/account"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json())

JavaScript

const url = "https://nymbot.ai/api/v1/account";
const res = await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } });
console.log(await res.json());

Управљање кључевима

Крајње тачке иза листе кључева апликације. Сви они требају Потписан захтевСваки кључ се враћа у овој форми, са временима у ИСО 8601 и износима у sats:

Кључни објекти

{
  "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 Довољно је препознати кључ, али не и користити га.Сам кључ се враћа само једном, када је направљен.

Листа кључева

GET https://nymbot.ai/api/v1/keys је потписао.

ПољеТипПотребнаОпис
include_revokedБоолеан (у питању)НеУкључује поништене кључеве. Подразумевано false.

Odgovor

{ "data": [ { "id": "4f0c9a1be27d3856", "name": "laptop scripts", "hint": "sk-nymbot-Qm7x…c2Lw", "...": "..." } ] }

cURL

URL=https://nymbot.ai/api/v1/keys
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/keys"
for key in requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json()["data"]:
    print(key["id"], key["name"], key["period_used_sats"], key["limit_sats"])

JavaScript

const url = "https://nymbot.ai/api/v1/keys";
const { data } = await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json();
for (const key of data) console.log(key.id, key.name, key.period_used_sats, key.limit_sats);

Направите кључ

POST https://nymbot.ai/api/v1/keys Повратак - Повратак 201.

ПољеТипПотребнаОпис
nameStringДа1 до 40 карактера, другачији од ваших других активних кључева (игнорисање случаја).
limit_satsинтегритетНеКапацитет трошкова у sats, најмање 1.
reset_periodStringНеdaily, weekly или monthlyPotrebe limit_satsОставите га за поклопац који се никада не ресетује.
expire_atstring или integerНеКада кључ престане да ради: ISO 8601 време, или милисекунди од 1970.

Одговор (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"
  }
}
статусКада
400Недостаје или превише дуго име; име већ у употреби (duplicate_name); капа који није цео број од најмање 1; период ресетовања без капа; истека у прошлости; непознато поље (unknown_parameter); или 25 активних кључева већ (too_many_keys).
429Више од 60 кључева направљених овим ним, или 120 са ове адресе, за сат времена (rate_limit_exceeded, са 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);

Читање једног кључа

GET https://nymbot.ai/api/v1/keys/{id} је потписао.

Повратак {"data": {…}} са кључним објектом, или 404 key_not_found ако ниједан од ваших кључева нема тај ИД.

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

Menjajte ključ

PATCH https://nymbot.ai/api/v1/keys/{id} је потписао.

Pošaljite bilo koju name, limit_sats, reset_period и expire_at, са истим правилима као када се прави кључ. null Чисти поље: нема капа, нема ресетовања, нема истека. Промена периода ресетовања почиње нови период од нуле.400 key_revoked) повратак {"data": {…}} са ажурираним кључним објектом.

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

Отказивање кључа

DELETE https://nymbot.ai/api/v1/keys/{id} је потписао.

Зауставља кључ одмах, за добро. Остаје на листи са revoked_at постављен, а може се видети са include_revoked=trueПовратак кључа који је већ повучен одговара на исти начин. Само се задржава најновијих 50 повучених кључева; старији се бришу када се повуче још један кључ.

Odgovor

{ "data": { "id": "4f0c9a1be27d3856", "revoked": true } }

cURL

URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
curl -X DELETE "$URL" -H "Authorization: $(nostr_auth DELETE "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
print(requests.delete(url, headers={"Authorization": nostr_auth("DELETE", url)}).json())

JavaScript

const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
const res = await fetch(url, { method: "DELETE", headers: { "Authorization": nostrAuth("DELETE", url) } });
console.log(await res.json());

НВЦ ауто-топ-уп

Povežite Lightning novčanik sa Nostr Wallet Connect i Nymbot će samostalno napraviti ravnotežu kada troškovi API-ja budu niski. API list aplikacije ima ista podešavanja; to su krajnje tačke iza njega. Потписан захтев.

Како то функционише: након што се захтев за АПИ наплаћује на биланс који сте изабрали да гледате, ако је тај биланс пао испод вашег прага, Нимбот прави рачун за ваш износ, тражи од вашег новчаника да га плати и додаје кредит. То се наплаћује највише једном сваких 5 минута за сваки ним и биланс, тако да експлозија захтјева не може испразнити новчаник. Трошење у апликацијама га не изазива. Време и величина последњег врхунца и последње грешке су у подешавањима; ако је плаћање прошло након грешке, проверите свој рачун са Статус топ-уп Кредити то

Пре него што повежете новчаник

Нимбот га чува шифровано и користи га само за плаћање сопствених рачуна, али направите везу само за ово, са трошачким буџетом у вашем новчанику, тако да је највише што је икада могао платити број који сте изабрали. pay_invoice.

Повезивање новчаника

POST https://nymbot.ai/api/v1/nwc-auto-topup/connect је потписао.

ПољеТипПотребнаОпис
nwc_urlStringДаПрикључак за везу, почетак nostr+walletconnect://Nymbot traži novčanik za get_info пре него што га сачувате, и чува га шифровано.
threshold_satsинтегритетДаВрх када биланс падне испод ове многе ставки. најмање 1000.
topup_satsинтегритетДаКолико да додате сваки пут. 1.000 до 1.000.000 ставки.
tierStringНеpro (понекад је дефект) или standard: баланс за гледање и врхунац.

Odgovor

{
  "data": {
    "connected": true,
    "threshold_sats": 5000,
    "topup_sats": 20000,
    "tier": "pro",
    "last_topup_at": null,
    "last_topup_sats": null,
    "last_error": null
  }
}
статусКада
400Не постоји веза за везу (invalid_nwc_url); новчаник није одговорио на његов релеј (nwc_unreachable) или је одбио проверу (nwc_rejected); веза не може платити рачуне (nwc_missing_permission); или износ изван граница.
501Аутоматски врхови се не укључују за овај сервер (nwc_unavailableИсто важи и за остале две крајње тачке.

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

Читање подешавања

GET https://nymbot.ai/api/v1/nwc-auto-topup је потписао.

Враћа исти објекат као што је повезивање, са connected: false i ostala polja null kada nema povezanog novčanika. Sam lanac veze se nikada ne vraća.

cURL

URL=https://nymbot.ai/api/v1/nwc-auto-topup
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/nwc-auto-topup"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json())

JavaScript

const url = "https://nymbot.ai/api/v1/nwc-auto-topup";
console.log(await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json());

Откључавање

DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection је потписао.

Избрише сачуван низ веза. Нема више врхова. Да бисте били сигурни, такође можете поништити везу у вашем новчанику.

Odgovor

{ "data": { "connected": false, "threshold_sats": null, "topup_sats": null, "tier": null, "last_topup_at": null, "last_topup_sats": null, "last_error": null } }

cURL

URL=https://nymbot.ai/api/v1/nwc-auto-topup/connection
curl -X DELETE "$URL" -H "Authorization: $(nostr_auth DELETE "$URL")"

Python

import requests

url = "https://nymbot.ai/api/v1/nwc-auto-topup/connection"
print(requests.delete(url, headers={"Authorization": nostr_auth("DELETE", url)}).json())

JavaScript

const url = "https://nymbot.ai/api/v1/nwc-auto-topup/connection";
const res = await fetch(url, { method: "DELETE", headers: { "Authorization": nostrAuth("DELETE", url) } });
console.log(await res.json());

Плаћање по захтеву без кључа

Фиксне ценовне крајње тачке могу се платити за један захтев у једном тренутку преко Ласхнинг-а, без кључа, без рачуна и без салда: POST /images/generations, POST /images/edits, POST /videos, POST /audio/speech, POST /audio/transcriptions, POST /audio/translations и POST /embeddingsРазговор, одговори и поруке увек треба кључ. Захтев који носи кључ се наплаћује на биланс као и обично; ток плаћања почиње само када није послат кључ.

Нимбот говори две верзије исте идеје, из једног бацкенда: Лаблинг Лабс' Л402 (такође прихваћен под својим старим именом, LSAT) и нацрт ИЕТФ Плаћање HTTP аутентификација са lightning Метода и charge Користите оно што ваш клијент разуме.

Покрените сопствени сервер

Плаћање без кључа је на само када API_L402_SECRET садржи најмање 32 случајних бајта, као хекса (64 карактера) или база64 (44). openssl rand -hex 32Kratka ili pogodljiva vrednost isključuje funkciju i beleži zašto. API_L402_SECRET_PREVIOUS za jedan dan: akreditacije, status URL-ovi i izazovi pod njim nastavljaju da rade dok ne isteknu.

izazov

Пошаљите захтев са не Authorization ако је валидна, ништа не ради, и добијате 402 Payment Required са факторима за управо оно што захтев кошта: исту цену кључ би платио, конвертован на 10 стопа стандардног кредита или 100 стопа Про кредита и заобљен до читавог сета (најмање 1 стопа, и најмање 0.05 кредитног минимума). WWW-Authenticate Проблеми са истим рачуном:

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

Плаћање request параметар је base64url JSON: {"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.

Izazov je vezan za kraj, za Content-Type (њихов тип медија и, за вишеделни, његова граница) и на СХА-256 тачних бајтова тела које сте послали, и траје 15 минута. Идентична Поново захтев: исто Content-Type и исти ЈСОН бајтови, или за вишедељне крајње тачке (/images/edits, /audio/transcriptions, /audio/translationsВећина ХТТП библиотека бира нову границу сваки пут када кодирају образац, тако да га кодирају једном и шаљу те бајтове два пута.

Свака адреса може тражити 30 изазова у минути (ИПв6 адреса се рачуна као његова цела /64). Захтеви чија адреса није позната деле строже 10 у минути, и постоји укупна граница на изазовима Нимбот проблемима преко свих адреса; захтев одбијен пре него што је изазов направљен (на пример, са телом које није валидно ЈСОН) не рачуна према њему. 429 са Retry-AfterPlaćene krajnje tačke poziva bez ključa ili poverenja takođe se računaju prema opštoj granici od 120 neoverenjenih zahteva po minuti po adresi. Content-Type nije application/json (или multipart/form-data за уплоад) је одбијен са 415 Nikada ne dobija račun.

Уграђивања се цене на основу процене токена у улазу, са маргином од 1,5 пута, пошто је прави број познат тек касније.Плаћате за токене који су заправо коришћени, а неупотребљени део плаћања се враћа као Повратак токена.

Пошаљи плаћање

Платите рачун са било којим Лигхтнинг новчаником. новчаник вам даје пре-слику, 64 хекс карактера. Затим пошаљите исти захтев са једним од ових:

Схемахејдер
Л402Authorization: L402 <macaroon>:<preimage> (LSAT takođe radi)
ПлаћањеAuthorization: Payment <base64url JSON>gde je JSON {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}}

Плаћени захтев одговара управо као онај направљен са кључем, осим што је nymbot objekat nema polja ravnoteže: {"payment": "l402", "tier": "pro", "paid_sats": 237, "charged_sats": 237}И постоји не X-Nymbot-Balance-Sats Захтев плаћен помоћу шеме плаћања такође добија Payment-Receipt заглавља (base64url JSON са изазовом id, хасх плаћања као reference, status и timestampPlaćeni zahtevi nisu vezani za nijm, tako da se ne pojavljuju u istoriji upita.

статусКада
402 payment_already_usedСваки плаћање плаћа за један захтев. Одговор је нови изазов за овај захтев, тако да клијент који кешира своју последњу верификацију (као lnget То јест, једноставно опет падне.
402 payment_mismatchКредитација је издата за другу крајњу тачку, Content-Type или тело, или плаћа мање него што овај захтев сада кошта. Нови изазов за овај захтев долази са њим; ако је плаћање било премало, оно што сте платили враћа се као Повратак токена (refund_token и refund_sats у свом телу).
402 payment_expiredВише од 15 минута је прошло од изазова. Нови изазов долази са њим. Ако прелиминарна слика показује да сте платили, оно што сте платили враћа се као Повратак токена (refund_token и refund_sats у телу), једном; онда се поверења користе.
401 invalid_preimagePreimage не хасх на фактуре плаћања хасх. плаћање није искоришћено.
401 invalid_payment_credentialПотврда је погрешно формирана, променила се након што га је Нимбот издао, или назива плаћање хасх Нимбот никада није издао рачун за. Макарон са упозорењем Нимбот не зна, или са сукобљивим упозорењима, одбија се.
429 rate_limit_exceededВише од 30 поверења или кључева који нису успели да се верификују дошли су са ове адресе у минути, или је један токен за повраћај послат више од 60 пута у минути. 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"));

Клијенти су изграђени на mppx са методом Муња сами управљају изазовом Плаћања; указујући их на крајњу тачку и пустите их да плате.

Видео

Плаћен је POST /videos Одговори 202 као кључ један, плус а status_url: GET То је потписано и ради 24 сата, све док се посао чува.

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

Држи се refund_token од овог одговора: то је приказано само овде. То је празно док видео рендерира (GET /api/v1/l402/refunds Одговори "status": "pending"); ако рендеринг није наплаћен, плаћање слети на њега. refund_sats за повраћен посао, али никада токен, тако да дељење URL статуса не дели повраћај.

Повратак

Ако плаћени захтев не успије и провајдер је наплатио Нимбот за покушај, плаћање се задржава и грешка каже тако, са charged_sats, баш као и за кључни захтев. Ако не успе без фактурисања, грешка носи Повратак токена Vredi ono što ste platili:

{
  "error": {
    "message": "The image generator failed. Nothing was charged. Please try again. The 237 sats you paid are on refund token REFUND-...",
    "type": "api_error",
    "code": "upstream_error",
    "refund_token": "REFUND-0C15DBED145D59131BA70298A413ADEB3D9B9AB082C476EA70A5BD38FCA5DE6D",
    "refund_sats": 237,
    "refund_expires_at": "2026-10-30T12:00:00.000Z"
  }
}

Неискоришћени делови се враћају на исти начин: ако сте затражили две слике, а једна није исплаћена, успех одговора nymbot објект носи токен за повраћај за недостајућу; транскрипција чија дужина није могла бити прочитана унапред је цијењена за најдужу датотеку која би могла бити (никада више од 30 минута), а разлика у стварној дужини се враћа као токен за повраћај; ако се испостави да је дуже од 30 минута, она се одбија са 413 и целокупно плаћање се враћа. Уграђивања враћају оно што је процена задржала. Неуспешан видео враћа токен који је његова подношење вратило.

Токен за повраћај је случајни 256-битни код. Нимбот чува само свој хасх, а истекује након 30 дана.

  • Плати са њом. Пошаљи Authorization: Bearer REFUND-… Постоје и друге опције које треба узети у обзир, као што је упутство за употребу (укључујући и упутства за употребу).refund_token_sats У о nymbot objekat). token vredan manje od odgovora na zahtev 402 refund_insufficient; неуспјех без рачуна ставља ставку назад на исти токен.
  • Провери то GET /api/v1/l402/refunds Са истим хеадер враћа {"sats": 237, "status": "open", "expires_at": "..."}.
  • Један токен се може користити највише 60 пута у минути.
  • Преместите га на ним. Ставите га у Набавите поклон у апликацији Нимбот, или позовите POST /api/v1/l402/refunds/redeem Са а Потписан захтев и {"refund_token": "REFUND-...", "balance": "standard"} (или "pro"Цели кредити иду у биланс (10 стопа сваки на стандарду, 100 на Про); стопе које не чине цео кредит остатак на токену за АПИ захтјеве.

cURL

URL=https://nymbot.ai/api/v1/l402/refunds/redeem
BODY='{"refund_token":"REFUND-...","balance":"standard"}'
curl "$URL" \
  -H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
  -H "Content-Type: application/json" \
  -d "$BODY"

Odgovor

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