Мазмунга өтүү
Nymbot'ко кайтуу

Билим базасы Розработчикдер

Баланс, толуктоолор жана ачкычтар

Эмне бар экенин текшериңиз, Lightning аркылуу балансты толуктаңыз, өз кошелектериңизден автоматтык түрдө толуктаңыз, ар бир сурамдын баасын көрүңүз жана ачкычтарды код аркылуу башкарыңыз.

Балансты текшерүү

Эки тең балансыңыз жана бул ачкычтын чегинин канчасы колдонулгандыгы.

GET https://nymbot.ai/api/v1/credits/balance — API ачкычы керек. POST ошондой эле, муну күткөн кардарлар үчүн да иштейт.

balance азыркы Биткоин баасы боюнча эки баланс доллар менен кошо, бир гана санды күткөн куралдар үчүн (null эгерде баасын окууга мүмкүн болбосо). Калган бөлүгү кредиттерде жана саттарда, тең салмактуулуктар иш жүзүндө ушундай сакталат. 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);

Төлөм ыкмалары

Кантип толуктаса болот жана чектөөлөр кандай. Lightning — жалгыз ыкма.

GET https://nymbot.ai/api/v1/topup/payment-methods — ачкыч керек эмес.

Төлөм 10дөн 1 000 000 сатшиге чейин; Pro төлөмдүн алкагында кеминде бир Pro кредитин сатып алуу керек, ошондуктан ал 100 сатшиден башталат. Доллардык чектөөлөр Биткоиндын баасына жараша өзгөрөт. bulk_bonus чоңураак толуктоолор үчүн кошумча бонусту тизмелейт, тиркемедегидей эле: 500, 1,000 же 5,000 саттон баштаган стандарттык толуктоолорго 10%, 15% же 20% кошумча, ал эми Pro толуктоолорго 5,000, 10,000 же 50,000 саттан баштап кошумча бонустар берилет.

Жооп

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

cURL

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

Python

import requests

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

JavaScript

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

Lightning аркылуу пополдоо

Lightning инвойсун түзөт, ал ага таандык ачкычтын nym-дарына кредит кошөт. Аны каалаган Lightning капчыгынан төлөңүз, андан кийин текшерүү кредитти кошутуу үчүн.

POST https://nymbot.ai/api/v1/topup/create/btc-lightning — API ачкычы керек.

АйланатТүрүКеректелүүчүСүрөттөмө
amountсанОобаКанча, ... ичинде currencysats үчүн бүтүн сан.
currencyсапЖокSATS (демейки), USD же BTCДолларлар учурдагы Биткоин баасы боюнча конвертацияланат.
tierсапЖокpro (демейлүү) же standard: кредит кайсы баланс менен эсептелет.

Стандарттык кредит 10 сат, ал эми Pro кредит 100 сат, плюс кандайдыр бир топтук бонус; 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,000,000 саттен жогору (amount_too_large) же Lightning кошени тарабынан четке кагылды (amount_out_of_range).
429Бул nym үчүн 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} — инвойскону түзүүчү nym'дан ачкыч керек.

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
}
СтатусКачан
400ID түзүү чакырышындагы 64 мүнөздүү ID эмес.
404Бул ID боюнча сиздин 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);

Суроо тарыхы

Ар бир суроо үчүн бир сап: эмне болду, кайсы модель, канча токен жана кандай баага туура келди. Prompt же жооптор сакталбайт, ошондуктан алар кайтарылбайт. Саптар 90 күн бою сакталат, эң жаңысы биринчи. Лимити жеткен ачкыч өз тарыхын дагы деле окуй алат.

GET https://nymbot.ai/api/v1/queries/history — API ачкычы керек, ал өзүнүн сурамдарын көрөт, же кол коюлган суроо-талап Ар бир ачкычты көргөн сенин атыңдан.

АйланатТүрүКеректелүүчүСүрөттөмө
pageбүтүн сан (суроо)ЖокДемейлүү 1, эң көп дегенде 1 000; жогорку бет: 400 invalid_value.
page_countбүтүн сан (суроо)ЖокБаракчадагы саптардын саны. Дефолттуу 20, эң көп дегенде 100.
start_date
end_date
сап (суроо)ЖокISO 8601 даталары же убактысы.
modelсап (суроо)ЖокТек гана бул модель.
typeсап (суроо)Жокchat, responses, messages, image, video, speech, transcription же embedding.
all_keysboolean (суроо)ЖокАчкыч менен: true ошол эле атташтылуунун ар бир ачкычын камтыйт. Default false.
key_idсап (суроо)ЖокКол коюлган суроо-талап менен же 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 ачкычы керек эмес. Алар сиздин nym'ден келген кол тамганы талап кылат, ошондуктан купуяланган ачкыч өзүнүн чегине чейин акча корото алат, бирок эч качан башка ачкыч түзө албайт же өзүнүн чегин көтөрө албайт.

Тиркеме муну сиз үчүн аткарат: баары өз ордунда API кесте бул чекиттерди колдонот. Сизге өз кодуңуздон ачкычтарды башкаруу үчүн ушул бөлүм гана керек.

Кол тамга — бул 27235 түрүндөгү (NIP-98) Nostr окуясы, ал base64 форматында жөнөтүлөт Authorization сөз менен шелтеме 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 бул сырткы суроо-талаптын (raw request body) hex форматындагы SHA-256 хеши. Ал талап кылынат POST жана PATCH, жана сиз жөнөткөн телоо байт боюнча байт чейин сиз хэш жасаган телоо менен дал келиши керек.
  • created_at сервердин саатынан 60 секунддун ичинде болушу керек.
  • Ар бир окуя бир жолу иштейт, а GET кошулган, ошондуктан кармап алынган заголовокту кайра колдонууга мүмкүн эмес. Ар бир суроо үчүн жаңысын кол коюңуз. Кошуңуз nonce кокустук маани менен белгилөө ошондуктан бир секунддун ичинде кол коюлган эки сурам деле айырмаланат.
  • Кол коюлган сурамдын денеси эң көп дегенде 64 КБ болушу мүмкүн жана дене керек Content-Type: application/json.

Жоголуп кеткен окуя кайтып келет 401 missing_nostr_auth; туура эмес түзүлгөн, туура эмес кол коюлган, өтө эски же башка URL, ыкма же телоо үчүн болгон кайтарымдар döndүрүлөт invalid_nostr_auth, билдирүүдөгү себеби менен; кайра колдонулганы кайтып келет nostr_auth_replayedБул uçuşтук чекиттерге жөнөтүлгөн API ачкычы четке кагылат. Сигнатура дене окулардан мурун текшерилет жана ар бир дарек мүнөтүнө 30 жолу ката кетирүүгө укуктуу (IPv6 дареги өзүнүн бүтүндөй /64 дареги катары эсептелет); андан кийин ал 429 менен Retry-After.

Браузерлер бул эндпоинттерди Nymbot'тун өзүнүн сайттарынан гана чакыра алышат (https://nymbot.ai, https://nymchat.app жана алардын поддомендери). Башка каалаган сайттагы бет CORS хедерлерин албайт, ошондуктан ал алардын кайтарып берген маалыматтарын окуй албайт. Эч нерсе жибербеген скрипттер жана нативдүү тиркемелер, Origin, таасир этпейт.

Сиздин секреттик ачкычыңыз

Кол коюу үчүн сиздин nym'дин секреттик ачкычыңыз керек (the nsec), ал баарын башкарат: сиздин идентификацияңызды, тарыхыңызды жана балансыңызды. Аны ишенимдүү машинадагы скрипттин ичине гана коюңуз, файлга жазуунун ордуна аны чөйрөдөн (environment) окуңуз жана мүмкүн болгон учурда тиркемени колдонууну артык көрүңүз.

Бул жардамчылар хедерди түзөт. Бул баракчадагы кийинки мисалдар аларды колдонушат. Алар секреттик ачкычты hex форматында окушат NOSTR_SECRET_HEX; cURL варианты ... колдонот nak nsec же hex ачкычын алган командалык сап куралы жана sha256sum (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");
}

Аккаунттун маалыматтары

Тиркеменин 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_revokedboolean (суроо)ЖокТекшерүүдөн өтпөгөн ачкычтарды кошуңуз. Адаттагы режим 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бүтүн санЖокСатындагы чыгаша чеги, кеминде 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Бул nym тарабынан 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 эгерде сиздин эч бир ачкычыңызда ал ID жок болсо.

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 менен байланыштырыңыз жана API чыгымдары төмөндөп калганда Nymbot балансты өзү толтурат. Колдонмонун API баракчасында ушундай эле жөндөөлөр бар; бул анын артындагы endpoint'тер. Алардын баарына... кол коюлган суроо-талап.

Кантип иштейт: API суроосу сиз көзөмөлдөө үчүн тандаган баланстан алынгандан кийин, эгерде ал баланс сиздин чегиңизден төмөн түшсө, Nymbot толуктоо суммасы үчүн эсеп-фактура түзөт, капчыңыздан аны төлөөнү суранат жана кредитти кошот. Ал ар бир nym жана баланс үчүн 5 мүнөттө бир жолдон эң көп толтурат, ошондуктан суроолордун кескин көбөйүшү капчыкты бошотуп жибербейт. Тиркемелердеги чыгымдар муну ишке ашырбайт. Акыркы толуктоонун убактысы жана өлчөмү, ошондой эле акыркы ката жөндөөлөрдө көрсөтүлгөн; эгерде катадан кийин төлөм ишке ашса, анын эсеп-фактурасын... толуктоо статусу кредиттер.

Капчыкты туташтыруудан мурун

Байланыш сап (connection string) аны ким кармаса, ошол адам сиздин капчыңыздан төлөм сураганга мүмкүндүк берет. Nymbot аны шифрленген түрдө сактайт жана аны өзүнүн балансын толуктоо эсеп-фактураларын төлөө үчүн гана колдонот, бирок мунун үчүн гана капчыңыздагы чыгаша бюджети менен өзүнчө байланыш түзүңүз, ошондо ал эң көп дегенде сиз тандаган сумманы гана төлөй алат. Капчык колдоо көрсөтүшү керек. pay_invoice.

Кошумча капчык туташтыруу

POST https://nymbot.ai/api/v1/nwc-auto-topup/connect — кол коюлду.

АйланатТүрүКеректелүүчүСүрөттөмө
nwc_urlсапОобаБайланыш саптары, башталуучу nostr+walletconnect://. Nymbot капчыктан сурайт get_info аны сактаардан мурун, жана аны шифрленген абалда сактайт.
threshold_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 — кол коюлду.

connecting менен бирдей объектти кайтарат, менен 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());

Ачкычсыз ар бир суроо үчүн төлөө

Белгиленген баадагы endpoint-тер үчүн Lightning аркылуу бир убакта бир суроо-талап үчүн, ачкычсыз, аккаунтсуз жана баланссыз төлөөгө болот: POST /images/generations, POST /images/edits, POST /videos, POST /audio/speech, POST /audio/transcriptions, POST /audio/translations жана POST /embeddings. Chat, Жооптор жана Билдирүүлөр дайыма ачкычты талап кылат. Ачкычты камтыган суроо-талап кадимкидей эле баланстын эсебинен кармалат; төлөм процесси ачкыч жөнөтүлбөгөн учурда гана башталат.

Nymbot бир эле бэкэндден бир эле идеянын эки версиясын айтат: Lightning Labs' L402 (ошондой эле мурунку аталышы менен да кабыл алынган, LSAT) жана IETF чертеги Төлөм HTTP аутентификация схемасы менен lightning метод жана charge максат. Кардарыңыз кайсынысын түшүнсө, ошону колдонуңуз.

Өз сервериңизди иштетүү

Ачкычсыз төлөө болгону төмөнкү учурда гана иштейт: API_L402_SECRET кеминде 32 рандомдуу байтты камтыйт, hex (64 символ) же base64 (44) түрүндө. Бирөөсүн жасаңыз: openssl rand -hex 32Кыскараак же алдын ала айтууга мүмкүн болгон маани функцияны өчүрөт жана эмне үчүн экенин жазып коёт. Аны ротациялоо үчүн, эски маанини которуңуз API_L402_SECRET_PREVIOUS бир күнгө: идентификациялоо маалыматтары, статус URL-дарын жана алардын негизинде түзүлгөн тапшырмалар мөөнөтү бүткөнгө чейин иштеп турат.

Сыноо

Сурамды эч нерсесиз жөнөт Authorization header. Эгер ал жарактуу болсо, эч нерсе иштебейт жана сиз аласыз 402 Payment Required ал суроо так канча турганы жөнүндө эсеп-фактура менен: бир эле ачкыч төлөй турган баа, стандарттык кредит үчүн 10 sats же Pro кредит үчүн 100 sats курсу менен айландырылып: жана бүтүн satка чейин тегеректелет (кеминде 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 (анын медиа түрүн жана, multipart болсо, анын чекударын (boundary)) жана сиз жөнөткөн так дене байттарынын (body bytes) SHA-256 кодуна, жана 15 мүнөт созулат. Төлөмдөн кийин, төмөнкүнү жөнөтүңүз окшош кайра сураныч: ошол эле Content-Type жана ошол эле JSON байттары, же multipart чекиттери үчүн (/images/edits, /audio/transcriptions, /audio/translations) бирдей чектөө (boundary) менен бирдей көп бөлүктүү денени (multipart body) колдонуу. Көптөгөн HTTP китепканалары форманы коддогон сайын жаңы чектөө тандашат, ошондуктан аны бир жолу коддоп, ал байттарды эки жолу жөнөтүңүз.

Ар бир дарек мүнөтүнө 30 челлендж сурай алат (IPv6 дареги өзүнүн бүткүл /64 дареги катары эсептелет). Дареги белгисиз болгон суроо-талаптар үчүн мүнөтүнө 10 челлендж деген кыйла катаал чектөө коюлган жана Nymbot бардык даректер боюнча чыгарган челлендждерге жалпы чектөө бар; челлендж бериле электе баш тартылган суроо-талап (мисалы, туура эмес JSON форматындагы мазмун менен) ага кирбейт. Андан ары жообу... 429 менен Retry-After(), негизги маалымат окулгуча жөнөтүлөт. Төлөмдүү endpoint'тер ачкычсыз же идентификациялоо каражатысыз чакырылганда да, ар бир дареске мүнөтүнө 120 аутентификацияланбаган сурам чегине кирүүдө. Идентификациялоо каражаты негизги маалымат окулгуча текшерилет жана сурамдын... Content-Type эмес application/json (же multipart/form-data жүктөөнү үчүн) менен баш тартылды 415 жана эч качан инвойс албайт.

Эмбеддингдердин баасы киргизилген токендердин болжолдуу санына карап, 1.5× кошумча маржа менен эсептелет, себеби чыныгы санын болгону кийин гана билүүгө болот. Сиз иш жүзүндө колдонулган токендер үчүн төлөйсүз, ал эми төлөмдүн колдонулбаган бөлүгү кайра кайтарылат Кайтаруу токени.

Төлөмдү жөнөтүү

Каалаган Lightning кошелек менен инвойско төлөм жүргүзүңүз. Кошелек сизге 64 hex символдон турган preimage берет. Андан кийин төмөнкүлөрдүн бири менен ошол эле сурамды жөнөтүңүз:

СхемаБашкы бөлүм
L402Authorization: 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 challenge id менен төлөм hash'и катары reference, status жана timestamp). Төлөнүүчү сурамдар эч кандай nym менен байланышпайт, ошондуктан алар сурамлардын тарыхында көрүнбөйт.

СтатусКачан
402 payment_already_usedАр бир төлөм бир суроо-талап үчүн төлөнөт. Жооп бул суроо-талап үчүн жаңы чакырык болуп саналат, ошондуктан акыркы маалыматтарын кэштеген кардар (as lnget жай гана кайра төлөйт.
402 payment_mismatchКүбөлүк башка чекит үчүн берилген, Content-Type же дене, же бул сурамдан азыраак төлөө азыр чыгым болуп жатат. Бул сурам үчүн жаңы чакырык келип түшөт; эгерде төлөм өтө аз болсо, сиз төлөгөн сумма кайра кайтып келет Кайтаруу токени (refund_token жана refund_sats денеде).
402 payment_expiredСыноодон 15 мүнөттөн ашык убакыт өттү. Жаңы сыноо келет. Эгерде preimage сиз төлөгөнүңүздү көрсөтсө, сиз төлөгөн нерсе ... катары кайтып келет. Кайтаруу токени (refund_token жана refund_sats денектин ичинде), бир жолу; андан кийин credential колдонулуп бүтөт.
401 invalid_preimageАлдын ала сүрөт инвойстун төлөм хешине туура келбейт. Төлөм колдонулган жок.
401 invalid_payment_credentialСертификат туура эмес түзүлгөн, Nymbot аны бергенден кийин өзгөртүлгөн же Nymbot эч качан инвойс берген төлөм хешинин атын көрсөтөт. Nymbot билбеген шарттын (caveat) бар болгон же карама-каршы шарттары бар macaroon четке кагылат.
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 Lightning ыкмасы менен төлөм боюнча тапшырманы өз алдынча ишке ашырышат; аларды чекитүүгө (endpoint) багыттап, төлөп коюусуна жол бериңиз.

Видеолор

Төлөнгөн 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"); эгерде рендеринг төлөнбөгөн абалда ката кетсе, төлөм ага түшөт. Статус URL дареги көрсөтөт 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-… жогорудагы түрдүү чекиттердин биринде (OpenAI SDK аны API ачкычы катары кабыл алат). Баа токенден алынат жана калган бөлүгү анда калат (refund_token_sats ичинде nymbot объект). Суроого жооп берген суроодон аз убакыт созулган токен. 402 refund_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, Proдо 100 sats); бүтүн кредитти түзбөгөн sats-тар 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 } }