База на знаење Развивачи
Баланс, врвови и клучеви
Проверете што имате, надминете Lightning, надминете автоматски од сопствениот паричник, видете што чини секое барање и управувајте со клучевите од кодот.
Оваа страница е машински преведена за погодност. Англискиот оригинал е верзијата што се применува.
Проверка на балансот
И вашите баланси, и колку од капа на овој клуч се користи.
GET https://nymbot.ai/api/v1/credits/balance Потребен ви е API клуч. POST Работи и за клиентите кои го очекуваат тоа.
balance е двата салда заедно во долари на тековната цена на Bitcoin, за алатки кои очекуваат еден број (null Останатото е во кредити и sats, што е како салдо всушност се чуваат. key Опис на клучот кој го побарал.Кључ кој го достигнал својот капак сè уште може да го провери балансот.
Одговор
{
"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 Нема потреба од клуч.
Топ-уп е од 10 до 1.000.000 ставки; Про топ-уп мора да купи најмалку еден Про кредит, па тоа започнува со 100 ставки. bulk_bonus Листа на дополнителни кредити на поголеми врвови, исто како и во апликацијата: 10%, 15% или 20% повеќе на стандардни врвови од 500, 1.000 или 5.000 sats, и на Про врвови од 5.000, 10.000 или 50.000 sats.
Одговор
{
"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 Потребен ви е API клуч.
| Полето | Тип | Потребни | Опис на |
|---|---|---|---|
amount | Број | Да | Колку, во currencyЦелиот број за ставка. |
currency | Стринг | не | SATS на дефектот, USD или BTCДоларите се конвертираат по тековната цена на Bitcoin. |
tier | Стринг | не | pro (недостапни услови) или standard: во која рамнотежа оди кредитот. |
Стандарден кредит е 10 sats и Про кредит 100 sats, плус било кој бонус во големина;
credits кажува што ќе додаде оваа фактура.
Одговор
{
"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 милион долари)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 (се уште не е платен) paid (платен, но сè уште не е кредитиран; проверете повторно), credited (во вашата рамнотежа) или expired (не се плаќа на време). Полето на балансот е за нивото на кое врви фактурата.
Одговор
{
"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 потребен е API клуч, кој ги гледа сопствените барања, или Потпишано барање од вашиот ним, кој ги гледа сите клучеви.
| Полето | Тип | Потребни | Опис на |
|---|---|---|---|
page | целосно прашање (query) | не | Подрачливост 1, најмногу 1.000; повисока страница е 400 invalid_value. |
page_count | целосно прашање (query) | не | Родови по страница. Подрачливо 20, најмногу 100. |
start_dateend_date | Структура на прашање (query) | не | ISO 8601 датуми и времиња. |
model | Структура на прашање (query) | не | Само овој модел. |
type | Структура на прашање (query) | не | chat, responses, messages, image, video, speech, transcription или embedding. |
all_keys | Булевар (во прашање) | не | Со еден клуч: true вклучува секој клуч од ист ним. false. |
key_id | Структура на прашање (query) | не | со потпишано барање, или со all_keys=trueСамо овој клуч. |
Одговор
{
"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);
Потпишување на барања за сметка
Креирање, менување и повлекување на клучеви, резиме на сметката и автоматски врвови не земаат API клуч. Тие земаат потпис од вашиот ним, така што пропуштениот клуч може да потроши до својот капак, но никогаш не може да направи друг клуч или да го зголеми сопствениот капак.
Апликацијата го прави ова за вас: сè во својата Огнот Овој дел ви е потребен само за да управувате со клучевите од вашиот сопствен код.
Потписот е Nostr настан од типот 27235 (NIP-98), испратен base64-кодиран во
Authorization Header со зборот 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е целосниот URL на барањето, вклучувајќи го и низата за барање, токму како што е испратено.methodТоа е HTTP методот.payloadе SHA-256 на телото на суровото барање, во хекс.POSTиPATCH, и телото што го испраќате мора да биде бајт за бајт оној што сте го хаширале.created_atмора да биде во рок од 60 секунди од часовникот на серверот.- Секој настан работи еднаш, а
GETвклучени, така што зафатениот наслов не може да се репродуцира. Потпишете нов за секое барање.nonceозначете со случајна вредност, така што две барања потпишани во иста секунда се уште се разликуваат. - Телото на потпишаното барање може да биде најмногу 64 KB, а телото треба
Content-Type: application/json.
Исчезнатиот настан се враќа 401 missing_nostr_auth; една која е лошо формирана, лошо потпишана, престара, или за различен URL, метод или тело враќа
invalid_nostr_auth, со причината во пораката; повторно користен еден се враќа
nostr_auth_replayedПотписот се проверува пред да се прочита телото, а секоја адреса може да го пропушти 30 пати во минута (IPv6 адреса се брои како нејзина целина /64); потоа добива 429 со
Retry-After.
Прелистувачите можат да ги повикуваат овие крајни точки само од сопствените сајтови на Nymbot (https://nymbot.ai,
https://nymchat.app Страница на која било друга веб-страница нема да добие CORS наслови назад, така што не може да го прочита она што го враќаат.
OriginТие не се погодени.
За да го потпишете, потребен ви е тајниот клуч на вашиот Nim (The Secret Key) nsec), која контролира сè: вашиот идентитет, вашата историја и вашата рамнотежа. Само ставете го во скрипт на машина во која верувате, прочитајте го од околината наместо да го напишете во датотеката, и претпочитајте ја апликацијата кога можете.
Овие помагачи го градат насловот. Подоцнежните примери на оваа страница ги користат. Тие го читаат тајниот клуч во хекс од NOSTR_SECRET_HEX; cURL еден го користи
Наки команда линија алатка, која зема nsec или хекс клуч, и sha256sum на макотрпни, 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");
}
Резиме на сметката
Она што API листот на апликацијата го покажува на врвот: вашиот јавен клуч, двата баланси, колку клучеви се активни (не се повлечени или истекувани) и Автоматски врв подесувањата, или
null кога серверот не ги нуди.
GET https://nymbot.ai/api/v1/account Потребна е а Потпишано барање.
Одговор
{
"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());
Управување со клучеви
Крајните точки зад листата со клучеви на апликацијата. Сите тие имаат потреба од Потпишано барањеСекој клуч се враќа во оваа форма, со времиња во ISO 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. |
Одговор
{ "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.
| Полето | Тип | Потребни | Опис на |
|---|---|---|---|
name | Стринг | Да | 1 до 40 знаци, различни од вашите други активни клучеви (игнорирање на случај). |
limit_sats | интегритет | не | Капацитетот на трошоците во sats, најмалку 1. |
reset_period | Стринг | не | daily, weekly или monthlyПотреби limit_satsОставете го надвор за капа што никогаш не се ресетира. |
expire_at | Структура или интеграл | не | Кога клучот престанува да работи: 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);
Промена на клучот
PATCH https://nymbot.ai/api/v1/keys/{id} Потпишан е
Испратете некој од 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 отповикани клучеви се чуваат; постарите се бришат кога друг клуч е отповикан.
Одговор
{ "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 авто-топ-уп
Поврзете го Lightning паричникот со Nostr Wallet Connect и Nymbot самиот ќе го надмине балансот кога трошоците за API го користат ниско. Потпишано барање.
Како функционира: откако барањето за API е наплатено на салдото што сте го одбрале да го гледате, ако тој салдо падна под вашиот праг, Nymbot прави фактура за вашиот износ, бара од вашиот паричник да го плати, и го додава кредитот. Тоа се зголемува најмногу еднаш на секои 5 минути за секој ним и салдо, така што експлозијата на барања не може да го исцеди паричникот. Трошењето во апликациите не го активира. Времето и големината на последниот врв, и последната грешка, се во поставките; ако плаќањето помина по грешка, проверете ја неговата фактура со Статус на врвот Кредит за тоа.
Нимбот го чува шифрирано и само некогаш го користи за да ги плати сопствените фактури, но направи врска само за ова, со буџет за трошење во вашиот паричник, така што најмногу што некогаш може да плати е број избрани од вас. pay_invoice.
Поврзување на паричник
POST https://nymbot.ai/api/v1/nwc-auto-topup/connect Потпишан е
| Полето | Тип | Потребни | Опис на |
|---|---|---|---|
nwc_url | Стринг | Да | Приклучокот на лентата, почнувајќи од nostr+walletconnect://Nymbot бара паричник за get_info пред да го зачувате, и да го зачувате шифрирано. |
threshold_sats | интегритет | Да | Нагоре кога салдото паѓа под овие многу sats. најмалку 1.000. |
topup_sats | интегритет | Да | Колку да се додаде секој пат. 1.000 до 1.000.000 ставки. |
tier | Стринг | не | pro (недостапни услови) или standard: рамнотежата да се види и да се зголеми. |
Одговор
{
"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 И другите полиња
null кога нема поврзани паричници, самиот синџир за поврзување никогаш не се враќа.
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 Потпишан е
Избришете ја зачуваната низа на врски. Не се прават повеќе врски. За да бидете сигурни, исто така можете да ја повлечете врската во вашиот паричник.
Одговор
{ "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());
Плаќање по барање без клуч
Крајните точки со фиксна цена може да се плаќаат за едно барање во исто време преку Lightning, без клуч, без сметка и без салдо: POST /images/generations, POST /images/edits,
POST /videos, POST /audio/speech, POST /audio/transcriptions,
POST /audio/translations и POST /embeddingsРазговор, Одговори и Пораки секогаш треба клуч. За барање кое носи клуч се наплаќа на салдото како и обично; протокот на плаќање започнува само кога нема клуч испратен.
Nymbot зборува за две верзии на истата идеја, од еден крај: Lightning Labs
Држи 402 (исто така прифатено под неговото старо име, LSAT) и на IETF нацрт
Плаќање Систем за HTTP аутентификација со lightning Методот и
charge Користете го она што вашиот клиент го разбира.
Плаќањето без клуч е вклучено само кога API_L402_SECRET има најмалку 32 случајни бајтови, како хекс (64 знаци) или base64 (44). openssl rand -hex 32Кратка или претпоставена вредност ја исклучува функцијата и го запишува зошто. API_L402_SECRET_PREVIOUS за еден ден: акредитивите, URL-то за статус и предизвиците направени под него продолжуваат да работат додека не истечат.
предизвикот
Испратете го барањето со не Authorization ако е валидна, ништо не работи, и ќе добиете 402 Payment Required со фактура за токму она што барањето чини: истата цена што клучот ќе плати, конвертирана на 10 sats стандарден кредит или 100 sats Про кредит и заоблени до цела сет (најмалку 1 sat, и најмалку 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":"..."}}.
Еден предизвик е врзан за крајната точка, за Content-Type (типот на медиумите и, за повеќе делови, неговата граница) и на SHA-256 на точниот бајтови на телото што сте го испратиле, и трае 15 минути. Идентични Повторно барање: истото
Content-Type и истата JSON бајтови, или за повеќепартиски крајни точки (/images/edits, /audio/transcriptions, /audio/translationsПовеќето HTTP библиотеки избираат нова граница секој пат кога кодираат форма, па кодирајте ја еднаш и испратете ги тие бајтови два пати.
Секоја адреса може да побара 30 предизвици во минута (IPv6 адреса брои како цела /64). Барања чија адреса не е позната делат построги 10 во минута, и постои општа граница за предизвиците Nymbot проблеми низ сите адреси; барање одбиено пред предизвикот е направен (на пример, со тело кое не е валидно JSON) не брои кон него. 429 со Retry-AfterПлатени крајни точки повикани без клуч или верификација, исто така, се бројат кон општата граница од 120 непроверени барања по минута по адреса. Content-Type Не е application/json (или на
multipart/form-data за надворешни работи) се одбива со 415 Никогаш нема да добиете фактура.
Вградувањата се ценат врз основа на проценка на токените во влезот, со маргина од 1,5 пати, бидејќи вистинскиот број е познат само подоцна. враќање токен.
Испраќање на плаќање
Платете ја сметката со било кој паричник Lightning. Портфелот ви дава пред-изображение, 64 шестоцифрени знаци. Потоа испратете го истото барање со еден од овие:
| Схема | Хејдер |
|---|---|
| Држи 402 | Authorization: L402 <macaroon>:<preimage> (LSAT Работи исто така) |
| Плаќање | Authorization: Payment <base64url JSON>каде што JSON е {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}} |
Платеното барање одговара исто како оној направен со клуч, освен тоа што nymbot
Објектот нема рамнотежа: {"payment": "l402", "tier": "pro", "paid_sats": 237,
"charged_sats": 237}И постои не X-Nymbot-Balance-Sats Барање платени со плаќање шема, исто така, добива Payment-Receipt header (base64url JSON со ID за предизвик, хаширањето на плаќањето како reference, status и
timestampПлатени барања не се поврзани со ништо, така што тие не се појавуваат во историјата на прашањата.
| Статус | Кога |
|---|---|
402 payment_already_used | Секое плаќање плаќа за едно барање. Одговорот е нов предизвик за ова барање, така што клиентот кој ја кешира својата последна верификација (како lnget Едноставно пак паѓаат. |
402 payment_mismatch | Кредитирањето беше издадено за друга крајна точка, Content-Type или тело, или плаќаат помалку од ова барање сега чини. Новиот предизвик за ова барање доаѓа со него; ако плаќањето беше премногу мал, она што го плативте се враќа како враќање токен (refund_token и refund_sats во рамките на телото). |
402 payment_expired | Повеќе од 15 минути поминаа од предизвикот. Новиот предизвик доаѓа со него. Ако префиксот покажува дека сте платени, она што сте го платиле се враќа како предизвик. враќање токен (refund_token и refund_sats во телото), еднаш; тогаш верификацијата е искористена. |
401 invalid_preimage | Пред-изобразот не хашира на плаќањето хаширање на фактурата. плаќањето не се користи. |
401 invalid_payment_credential | Потврдата е погрешно формирана, е изменета откако Nymbot ја издаде, или имиња на плаќање хаш Nymbot никогаш не издаде фактура за. |
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-токот за статус не го дели враќањето.
Враќање
Ако платеното барање не успее и провајдерот го наплати Nymbot за обидот, плаќањето се задржува и грешката вели така, со charged_sats, исто како и за барање со клуч. Ако не успее без да се наплати, грешката носи враќање токен Вредно е тоа што го плаќате:
{
"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-битен код. Nymbot го чува само својот хаш, и истекува по 30 дена.
- Платете со тоа. Пратете
Authorization: Bearer REFUND-…Покрај тоа, за да се постигне тоа, потребно е да се преземат сите потребни мерки, вклучувајќи ги и мерките за заштита на животната средина (refund_token_satsВо наnymbotТокен вреден помалку од одговорот на барањето402refund_insufficient; неуспехот на неуспехот го враќа стапката на истиот токен. - Проверете го тоа.
GET /api/v1/l402/refundsСо истиот хејдер се враќа{"sats": 237, "status": "open", "expires_at": "..."}. - Еден токен може да се користи најмногу 60 пати во минута.
- Преместете го во нијанса. Ставете го во Направете подарок во апликацијата Nymbot, или повик
POST /api/v1/l402/refunds/redeemсо а Потпишано барање и{"refund_token": "REFUND-...", "balance": "standard"}(или на"pro"Цели кредити одат на салдо (10 sats секој на стандард, 100 на Про); стапки кои не прават цела кредит останува на токенот за API барања.
cURL
URL=https://nymbot.ai/api/v1/l402/refunds/redeem
BODY='{"refund_token":"REFUND-...","balance":"standard"}'
curl "$URL" \
-H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
-H "Content-Type: application/json" \
-d "$BODY"
Одговор
{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }