コンテンツにスキップ
Nymbot に戻る

知識ベース 開発者

バランス、トップアップとキー

持っているものをチェックし、ライトニングをアップし、自分の財布から自動的にアップし、各リクエストのコストを確認し、コードからキーを管理します。

バランスをチェック

あなたのバランスの両方、そしてこのキーのキャップがどれだけ使われているか。

GET https://nymbot.ai/api/v1/credits/balance APIキーが必要です。 POST それを期待する顧客にとっても、

balance 現行のBitcoin価格で2つのバランスを合計すると、単一の数字を期待するツール(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);

支払方法

あなたはどのようにトップアップすることができますか、そして限界です. ライトニングは唯一の方法です。

GET https://nymbot.ai/api/v1/topup/payment-methods 鍵は必要ありません。

トップアップは10〜1万枚;プロトップアップは少なくとも1枚のプロクレジットを購入する必要がありますので、100枚から始まります。 bulk_bonus 大型トップアップの追加クレジットは、アプリと同じで、標準トップアップの10%、15%または20%を500、1000、5000のセットから、プロトップアップの5000、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);

「Topping Up Over Lightning」

ライトニングの請求書を作成し、キーが所属するナイムにクレジットを追加します。 チェックする クレジットを追加するには

POST https://nymbot.ai/api/v1/topup/create/btc-lightning APIキーが必要です。

フィールドタイプ必要描写
amount番号はいどれだけ、中 currency全体の数を賭けます。
currencyStringノーSATS (デフォルトは、 USD または BTCドルは現在のBitcoin価格で変換されます。
tierStringノーpro (デフォルト)または standard● クレジットがどこへ向かうのか

標準クレジットは10セット、プロクレジットは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_small1億円を超える( )amount_too_large)または光の財布によって拒否された(amount_out_of_range).
429平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度rate_limit_exceeded, with Retry-After).
502現時点で請求書は提出されない)。invoice_unavailable, with 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
}
ステータスいつ
400id は、Create Call の 64 文字 ID ではありません。
404あなたのアイデンティティ(NIMM)に該当しない。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);

歴史を求める

リクエストごとに一行:それが何だったか、どのモデルだったか、いくつトークンがあったか、そのコストは何だったか。 リクエストごとに1行は返されないため、リクエストごとに1行は返されません。 リクエストは90日間、最初に最新です。 キャップに達したキーは、その歴史を読み取ることができます。

GET https://nymbot.ai/api/v1/queries/history 自分のリクエストを見るAPIキーが必要、または 申請署名 すべての鍵を見るあなたのニムから。

フィールドタイプ必要描写
pageクエリー(query)ノーデフォルト 1, 最大 1,000; より高いページは 400 invalid_value.
page_countクエリー(query)ノーデフォルトは20、最大100。
start_date
end_date
String(クエリー)ノーISO 8601 日付や時刻
modelString(クエリー)ノーこのモデルだけ。
typeString(クエリー)ノーchat, responses, messages, image, video, speech, transcription または embedding.
all_keysブレイク(query)ノーひとつの鍵: true includes every key of the same nym. デフォルト false.
key_idString(クエリー)ノー署名された申請書、または 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キーを取得しません。それらはあなたのNIMから署名を取りますので、漏れたキーはそのキャップまで費やすことができますが、決して別のキーを作ったり、独自のキャップを上げたりすることはできません。

The app does this for you: everything in its 花火 sheet はこれらのエンドポイントを使用します. You only need this section to manage keys from your own code. あなたは自分のコードからキーを管理するためにこのセクションが必要です。

署名は、Nostr 27235 (NIP-98) 型のイベントであり、base64 で送信される。 Authorization header with the word シングル 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 is the full URL of the request, query string included, exactly as sent. は、リクエストの完全なURLであり、リクエスト文字列が含まれています。
  • method HTTPの方法です。
  • payload is the SHA-256 of the raw request body, in hex. It is required on POST そして PATCH, and the body you send must be byte for byte the one you hashed. あなたが送信する体は、あなたがハッシュしたものに対してバイトでなければなりません。
  • created_at サーバーの時計から60秒以内でなければなりません。
  • すべてのイベントは1回、A GET キャプチャしたヘッダーを再生することはできません. 各リクエストに新しいヘッダーをサインします. 追加 nonce ランダムな値でタグを指定し、同じ秒間に署名された 2 つのリクエストが依然として異なるようにします。
  • 署名されたリクエストの体は最大 64 KB で、体が必要です。 Content-Type: application/json.

行方不明のイベント復帰 401 missing_nostr_auth悪く形成されたもの、悪く署名されたもの、古すぎるもの、または異なるURL、方法、または体を返します。 invalid_nostr_authメッセージの中の理由で、再利用された1つが返ってくる。 nostr_auth_replayedこれらのエンドポイントに送信されたAPIキーは拒否されます。署名は体を読み取る前にチェックされ、各アドレスは1分間に30回(IPv6アドレスはその全体として数えられる /64)に失敗することがあります。 429 同 Retry-After.

ブラウザはこれらのエンドポイントをNymbotの独自のサイトからだけ呼び出すことができます(https://nymbot.ai, https://nymchat.app 他のどのサイトのページでも CORS ヘッダーが返ってこないため、返したものを読めない。 Origin影響されていない。

あなたの秘密の鍵

署名にはあなたのニムの秘密鍵が必要です。 nsec)はすべてを制御します:あなたのアイデンティティ、あなたの歴史、あなたのバランスを. あなたが信頼するマシンでスクリプトにそれを置いて、それをファイルに書き込むのではなく、環境から読んで、あなたが可能な限りアプリを好む。

これらのヘッダーを作成します。このページの後の例はそれらを使用します。 彼らはヘックスで秘密のキーを読みます。 NOSTR_SECRET_HEX; the cURL one uses the ナック コマンド ライン ツールは 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 必要 a 申請署名.

応答

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

キー管理

アプリのキーリストの背後にあるエンドポイント. All of them need a 申請署名各キーは、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ブレイク(query)ノー削除されたキーを含む. Default 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.

フィールドタイプ必要描写
nameStringはい1〜40文字、他のアクティブキーとは異なります(ケースを無視)。
limit_satsインテルノー支出カプセルはSATで、少なくとも1つは、カプセルなしで放置してください。
reset_periodStringノーdaily, weekly または monthlyニーズ 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); cap が少なくとも 1 の整数でない; reset 期間なしの cap; 過去の期限の有効期限; 未知のフィールド (unknown_parameter); または 25 つのアクティブなキーがすでに (too_many_keys).
429平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度 平成30年度rate_limit_exceeded, with 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);

読書 1 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 set, and can be seen with include_revoked=trueすでにリコールされているキーをリコールすると、同じ答えが返されます. Only the newest 50 revoked keys are retained; older keys are deleted when another key is revoked. リコールされたキーをリコールしたキーをリコールするには、新しいキーが保存されます。

応答

{ "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 リクエストがあなたが見るために選択したバランスを請求した後、そのバランスをあなたの値下に落ちた場合、Nymbotはあなたのトップアップ金額の請求書を作成し、あなたの財布にそれを支払うように依頼し、クレジットを追加します。 それはすべてのニムとバランスを5分ごとに最大で1回アップしますので、リクエストの爆発は財布を排出できません。アプリで費やすことはそれを引き起こさない。 最後のトップアップの時間とサイズ、そして最後のエラーは設定にあります。 TOP UP STATUS を信用する。

財布を接続する前に

Nymbotはそれを暗号化して保存し、独自のトップアップ請求書を支払うためにのみ使用しますが、このためだけに、財布に支出予算を持って接続しますので、最も支払うことはあなたを選んだ番号です。 pay_invoice.

財布の接続

POST https://nymbot.ai/api/v1/nwc-auto-topup/connect サインしました。

フィールドタイプ必要描写
nwc_urlStringはいコネクション ストレッチ 開始 nostr+walletconnect://Nymbot は財布を要求します。 get_info 保存する前に、それを保存し、暗号化して保存します。
threshold_satsインテルはいバランスがこれらの数値の下に落ちるときに上り、少なくとも1000。
topup_satsインテルはい毎回、いくら増やせばいいの? 1万から1万まで。
tierStringノー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)同じことは、他の2つのエンドポイントにも当てはまります。

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

Settingsを読み取る

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 サインしました。

保存された接続文字列を削除します. No more top-ups are made. To be sure, you can also revoke the connection in your wallet. もうトップアップは作成されません。

応答

{ "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チャット、応答、メッセージは常にキーを必要とします。キーを持ち込むリクエストは通常どおりバランスに請求されます。

Nymbotは、同じアイデアの2つのバックエンド「Lightning Labs」から発信しています。 L402 (古い名前の下で受け入れられ、 LSAT)およびIETFプロジェクト 支払い HTTP Authentication Scheme with the lightning 方法および charge クライアントが理解できるものを使用します。

独自のサーバーを実行する

鍵なしで支払うのは、ただし、 API_L402_SECRET 少なくとも 32 個のランダム バイトを、ヘクサス (64 文字) または base64 (44) として保持します。 openssl rand -hex 32. 短い値または推測可能な値は、機能をオフにし、なぜかをログします。 API_L402_SECRET_PREVIOUS 1日間:認証、ステータスURL、およびその下で作成された課題は、終了するまで動作し続ける。

挑戦

リクエストをノーで送信 Authorization header. If it is valid, nothing runs, and you get 402 Payment Required 請求のコストを正確に請求することによって:キーが支払う同一の価格、標準クレジットの10 satsまたはプロクレジットの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":"..."}}.

A challenge is bound to the endpoint, to the Content-Type (そのメディアタイプおよび、複数の部品の場合、その限界)および送信した正確な体バイトのSHA-256に、15分間続きます。 同一 再度申し込み:同じ Content-Type また、JSON バイトは、複数のエンドポイント(/images/edits, /audio/transcriptions, /audio/translationsほとんどの HTTP ライブラリは、フォームを暗号化するたびに新しい境界線を選択しますので、一度暗号化してそのバイトを 2 回送信してください。

各アドレスは1分間に30のチャレンジを要求することができます(IPv6アドレスは全体として /64として数えられます)。 アドレスが知られていないリクエストは1分間に10を割り当て、すべてのアドレスでNymbotのチャレンジの全体的なカップがあります。 429 同 Retry-Afterキーや認証なしで呼び出された有料エンドポイントは、アドレスごとに1分あたり120件の未認証要求の一般的な制限まで数えられます。 Content-Type ノー application/json (または multipart/form-data (アップロードは拒否) 415 決して請求書を受け取らない。

埋め込みは、入力中のトークンの見積もりから価格を設定し、実際の数値はその後のみ知られるので、15時間のマージンで。 トークン返品.

支払いを送信

請求書をすべてのライトウォレットで支払う。財布は64文字のプレビューを提供します。その後、これらのいずれかで同じ要求を送信します:

プログラムヘッダー
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}, and there is no X-Nymbot-Balance-Sats header. A request paid with the Payment scheme also gets a Payment-Receipt ヘッダー (base64url JSON with the challenge id, the payment hash as) reference, status そして timestamp支払ったリクエストは、任意の nym に結びつかないため、クエリの履歴に表示されません。

ステータスいつ
402 payment_already_used支払いごとに1件のリクエストが支払われます。その答えはこのリクエストに対する新たな挑戦です。 lnget 単純に、再び国を
402 payment_mismatch結論から言えば、もう一つの結論に基づいて、 Content-Type or body, or pays less than this request now costs. A new challenge for this request comes with it; if the payment was too small, what you paid comes back as a トークン返品 (refund_token そして refund_sats 体内では)。
402 payment_expired挑戦から15分以上が経過しました 新しい挑戦が加わります. プレビューがあなたが支払ったことを示している場合、あなたが支払ったものは返されます。 トークン返品 (refund_token そして refund_sats たった1回、その後、クレジットカードが使われます。
401 invalid_preimageプレビューは、請求書の支払いハッシュにハッシュしません。
401 invalid_payment_credential認証番号が誤り、Nymbot が発行した後に変更されたか、または支払いハッシュ Nymbot が請求書を発行したことがない名称です。
429 rate_limit_exceeded検証に失敗した30以上の認証またはキーが1分以内にこのアドレスから来たか、または1分間に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 ライトニングの方法で、支払いの挑戦を自分たちで処理し、エンドポイントに彼らを指し、彼らが支払うようにしてください。

動画

A 支払い POST /videos 答え 202 タイトル: Like a Keyed One, Plus A 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..."
  }
}

Keep the refund_token 画像はこちらで表示されますが、動画はこちらで表示されます(画像はこちらで表示されます)。GET /api/v1/l402/refunds 答え "status": "pending"); レンダリングが未請求に失敗した場合、支払いはその上に着陸します。 refund_sats 返金された仕事のためですが、トークンは決してありませんので、状態URLを共有することは返金を共有しません。

返金

支払ったリクエストが失敗し、プロバイダーが試行のためにNymbotを請求した場合、支払いは保持され、エラーはそう言います。 charged_sats, just as for a keyed request. If it fails without being billed, the error carries a トークン返品 あなたが支払った価値:

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

未使用の部品は同じように返信されます: 2 枚の写真を要求し、1 枚が請求されなかった場合、成功の答えは nymbot オブジェクトは、欠けているものに対して返金トークンを運ぶ; 長さが読み上げられなかったトランスクリプションは、ファイルが可能な限り長く(30分を超えることはありません)、実際の長さとの違いが返金トークンとして返されます。 413 すべての支払いが返されます. 埋め込みは、予想されたものを返します. 失敗したビデオは、提出したトークンに返します。

返金トークンは256ビットのランダムなコードです。Nymbotはそのハッシュだけを格納し、30日後に終了します。

  • それで支払う。 送る Authorization: Bearer REFUND-… トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ > トップ >refund_token_sats IN THE nymbot object). A token worth less than the request answers. リクエストの答えよりも価値の少ないトークン 402 refund_insufficient未請求の失敗は、同じトークンに sats を戻します。
  • チェックする GET /api/v1/l402/refunds 同じヘッダーが返ってくる。 {"sats": 237, "status": "open", "expires_at": "..."}.
  • トークンは1分間に最大60回使用できます。
  • ニムに移す。 「Paste It Into 返品プレゼント 「Nymbot App」または「Call POST /api/v1/l402/refunds/redeem Aと 申請署名 そして {"refund_token": "REFUND-...", "balance": "standard"} (または "pro"全体のクレジットは、バランスに入ります(標準でそれぞれ10セント、プロで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 } }