Pangkalan pengetahuan Pengembang
Keseimbangan, top-ups dan kunci
Semak apa yang anda mempunyai, top up atas Lightning, top up secara automatik daripada dompet anda sendiri, lihat berapa kos setiap permintaan, dan menguruskan kunci daripada kod.
Halaman ini diterjemahkan mesin untuk kemudahan. Versi asal bahasa Inggeris ialah versi yang digunakan.
Memeriksa keseimbangan
Kedua-dua keseimbangan anda, dan berapa banyak cap kunci ini digunakan.
GET https://nymbot.ai/api/v1/credits/balance Anda memerlukan kunci api. POST Ia juga berfungsi untuk pelanggan yang mengharapkannya.
balance ialah dua keseimbangan bersama dalam dolar pada harga Bitcoin semasa, untuk alat yang mengharapkan nombor tunggal (null jika harga tidak boleh dibaca). sisanya dalam kredit dan sats, yang merupakan cara keseimbangan sebenarnya disimpan. key Kunci yang telah mencapai capnya masih boleh memeriksa baki.
Jawapan
{
"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"
}
}
| Status | bila |
|---|---|
401 | Kunci hilang, tidak diketahui, dibatalkan atau tamat tempoh. |
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);
Kaedah Pembayaran
Bagaimana anda boleh top up, dan had. Lightning adalah satu-satunya kaedah.
GET https://nymbot.ai/api/v1/topup/payment-methods Tiada kunci yang diperlukan.
Top-up ialah 10 hingga 1,000,000 sats; top-up Pro mesti membeli sekurang-kurangnya satu kredit Pro, jadi ia bermula pada 100 sats. bulk_bonus senarai kredit tambahan pada top-up yang lebih besar, sama seperti dalam app: 10%, 15% atau 20% lebih pada top-up standard dari 500, 1,000 atau 5,000 sats, dan pada top-up Pro daripada 5,000, 10,000 atau 50,000 sats.
Jawapan
{
"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);
Tumping di atas Lightning
Mencipta invois Lightning yang menambah kredit kepada nym yang kunci itu milik. membayarnya dari mana-mana dompet Lightning, kemudian Periksa ia untuk mendapatkan kredit tambahan.
POST https://nymbot.ai/api/v1/topup/create/btc-lightning Anda memerlukan kunci api.
| Lapangan | Jenis | diperlukan | Penerangan |
|---|---|---|---|
amount | Nombor | ya | Berapa banyak, dalam currencySatu nombor penuh untuk tarikh. |
currency | String yang | Tidak | SATS (Dalam hal yang demikian, USD atau BTCDolar ditukar pada harga Bitcoin semasa. |
tier | String yang | Tidak | pro (Perkara yang telah ditetapkan) atau standard: mana keseimbangan kredit akan pergi. |
Kredit standard ialah 10 sats dan kredit Pro 100 sats, ditambah bonus bulk apa-apa;
credits menyatakan apa yang akan ditambahkan dalam akaun ini.
Jawapan
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"payment_request": "lnbc100u1p5...",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": "2026-09-30T09:27:00Z",
"status": "pending"
}
| Status | bila |
|---|---|
400 | Kaedah-kaedah lain dalam jalan (unsupported_method, sebuah mata wang yang tidak diketahui (unsupported_currency(b) jumlah yang kurang atau jumlah yang lebih rendah daripada jumlah minimum)amount_too_small(dalam jumlah yang lebih daripada 100,000 orang)amount_too_large) atau ditolak oleh dompet Lightning (amount_out_of_range). |
429 | Lebih daripada 60 faktur untuk nym ini, atau 120 dari alamat ini, dalam satu jam (rate_limit_exceeded, dengan Retry-After). |
502 | Tiada akaun boleh dibuat pada masa ini (invoice_unavailable, dengan 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);
Melakukan pemeriksaan top-up
Menanyakan sama ada invois telah dibayar dan, sebaik sahaja ia telah, menambah kredit. pemeriksaan adalah apa kreditnya, jadi selepas membayar, semak sehingga status creditedSemak semula selepas itu selamat: kredit mendarat sekali, tidak kira berapa kali anda meminta.
GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - memerlukan kunci daripada nym yang membuat invoice.
status ialah pending (Tidak dibayar sehingga kini) paid (Dibayar tetapi belum dikreditkan; semak semula), credited (dalam pertukaran anda) atau expired (tidak dibayar pada masanya). medan keseimbangan adalah untuk peringkat yang invoice top up.
Jawapan
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"status": "credited",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": null,
"balance_credits": 523.33,
"balance_sats": 52333
}
| Status | bila |
|---|---|
400 | ID bukan 64-karakter id daripada panggilan cipta. |
404 | Tiada akaun oleh id itu untuk nym anda (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);
mahu sejarah
Satu baris setiap permintaan: apa itu, model mana, berapa banyak token dan apa kosnya. Tiada prompts atau jawapan disimpan, jadi tiada yang dikembalikan. Barisan disimpan selama 90 hari, terkini pertama. Kunci yang telah mencapai capnya masih boleh membaca sejarahnya.
GET https://nymbot.ai/api/v1/queries/history memerlukan kunci API, yang melihat permintaan sendiri, atau Permintaan ditandatangani daripada nym anda, yang melihat setiap kunci.
| Lapangan | Jenis | diperlukan | Penerangan |
|---|---|---|---|
page | Penyelesaian (query) | Tidak | Default 1, sehingga 1,000; halaman yang lebih tinggi ialah 400 invalid_value. |
page_count | Penyelesaian (query) | Tidak | Baris per halaman. Default 20, pada maksimum 100. |
start_dateend_date | Penyelesaian (Query) | Tidak | ISO 8601 tarikh atau masa. |
model | Penyelesaian (Query) | Tidak | Hanya model ini sahaja. |
type | Penyelesaian (Query) | Tidak | chat, responses, messages, image, video, speech, transcription atau embedding. |
all_keys | Melayu kepada Melayu (query) | Tidak | Dengan satu kunci: true mengandungi setiap kunci yang sama.Default false. |
key_id | Penyelesaian (Query) | Tidak | Dengan permintaan yang ditandatangani, atau dengan all_keys=trueHanya kunci ini sahaja. |
Jawapan
{
"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);
Menandatangani permintaan akaun
Mencipta, mengubah dan membatalkan kunci, ringkasan akaun dan top-up automatik tidak mengambil kunci API.Mereka mengambil tanda tangan daripada nym anda, jadi kunci yang bocor boleh menghabiskan sehingga capnya tetapi tidak boleh membuat kunci lain atau menaikkan capnya sendiri.
Aplikasi ini buat untuk anda: segala-galanya dalam Kebakaran sheet menggunakan titik akhir ini. Anda hanya memerlukan seksyen ini untuk menguruskan kunci daripada kod anda sendiri.
Tanda tangan ini ialah peristiwa Nostr jenis 27235 (NIP-98), dihantar dengan kod base64 dalam
Authorization Header dengan perkataan Nostr Di hadapan :
peristiwa
{
"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": "..."
}
uadalah URL penuh permintaan, string pertanyaan termasuk, persis seperti yang dihantar.methodIni ialah kaedah HTTP.payloadialah SHA-256 badan permintaan mentah, dalam hex.POSTdanPATCH, dan badan yang anda hantar mesti byte untuk byte yang anda hashed.created_atIa mesti berada dalam masa 60 saat daripada jam pelayan.- Setiap peristiwa berlaku sekali, a
GETtermasuk, supaya tajuk yang ditangkap tidak boleh diputar semula. Tandatangani tajuk baru untuk setiap permintaan. Tambahnoncetag dengan nilai rawak supaya dua permintaan yang ditandatangani pada saat yang sama masih berbeza. - Badan permintaan yang ditandatangani boleh mempunyai maksimum 64 KB, dan badan memerlukan
Content-Type: application/json.
Peristiwa yang hilang kembali 401 missing_nostr_authsatu yang terbentuk buruk, ditandatangani buruk, terlalu lama, atau untuk URL, kaedah atau badan yang berbeza mengembalikan
invalid_nostr_authOleh yang demikian, al-Quran mengingatkan kepada orang yang kembali kepada Al-Quran.
nostr_auth_replayedKunci API yang dihantar ke titik akhir ini ditolak. tanda tangan disemak sebelum badan dibaca, dan setiap alamat boleh gagal 30 kali setiap minit (sebuah alamat IPv6 dihitung sebagai keseluruhan /64); selepas itu ia mendapat 429 dengan
Retry-After.
Pelayar boleh memanggil titik akhir ini hanya dari laman web Nymbot sendiri (https://nymbot.ai,
https://nymchat.app dan subdomain mereka). halaman di mana-mana laman lain tidak mendapat tajuk CORS kembali, jadi ia tidak boleh membaca apa yang mereka kembalikan. skrip dan aplikasi asli, yang menghantar tiada
OriginMereka tidak terpengaruh.
Menandatangani memerlukan kunci rahsia nym anda (yang nsec), yang mengawal segala-galanya: identiti anda, sejarah anda dan keseimbangan anda. hanya meletakkannya dalam skrip pada mesin yang anda percayai, baca dari persekitaran bukannya menulisnya ke dalam fail, dan lebih suka aplikasi apabila anda boleh.
Penolong-penolong ini membina tajuk. contoh-contoh yang kemudian di halaman ini menggunakan mereka. Mereka membaca kunci rahsia dalam hex daripada NOSTR_SECRET_HEX; cURL satu menggunakan
nak alat baris perintah, yang mengambil kunci nsec atau hex, dan sha256sum Pada 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");
}
Akaun ringkasan
Apa lembaran API aplikasi menunjukkan di bahagian atas: kunci awam anda, kedua-dua keseimbangan, berapa banyak kunci yang aktif (tidak dibatalkan atau tamat tempoh), dan automatik top-up pengaturan, atau
null apabila pelayan tidak menawarkan.
GET https://nymbot.ai/api/v1/account memerlukan a Permintaan ditandatangani.
Jawapan
{
"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());
Pengurusan Kunci
Titik akhir di sebalik senarai kunci aplikasi. semua mereka memerlukan Permintaan ditandatanganiSetiap kunci dikembalikan dalam bentuk ini, dengan masa dalam ISO 8601 dan jumlah dalam sats:
objek utama
{
"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 hanya cukup untuk mengenali kunci tetapi tidak untuk menggunakannya. kunci itu sendiri hanya dikembalikan sekali, apabila ia dibuat.
Senarai Kunci
GET https://nymbot.ai/api/v1/keys telah ditandatangani.
| Lapangan | Jenis | diperlukan | Penerangan |
|---|---|---|---|
include_revoked | Melayu kepada Melayu (query) | Tidak | Termasuk kunci yang dibatalkan. Default false. |
Jawapan
{ "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);
Membuat Kunci
POST https://nymbot.ai/api/v1/keys telah ditandatangani. kembali 201.
| Lapangan | Jenis | diperlukan | Penerangan |
|---|---|---|---|
name | String yang | ya | 1 hingga 40 watak, berbeza daripada kunci aktif anda yang lain (mengabaikan kes). |
limit_sats | Integra | Tidak | Pengeluaran cap dalam sats, sekurang-kurangnya 1. biarkan ia keluar tanpa cap. |
reset_period | String yang | Tidak | daily, weekly atau monthlykeperluan limit_satsTinggalkan untuk cap yang tidak pernah reset. |
expire_at | string atau integer | Tidak | Apabila kunci berhenti berfungsi: masa ISO 8601, atau milisekunder sejak 1970. |
Penyelesaian (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"
}
}
| Status | bila |
|---|---|
400 | Nama yang hilang atau terlalu panjang; nama yang sudah digunakan (duplicate_name); cap yang bukan nombor keseluruhan sekurang-kurangnya 1; tempoh reset tanpa cap; tamat tempoh di masa lalu; medan yang tidak diketahui (unknown_parameter); atau 25 kunci aktif sudah (too_many_keys). |
429 | Lebih daripada 60 kunci yang dibuat oleh nym ini, atau 120 dari alamat ini, dalam satu jam (rate_limit_exceeded, dengan 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);
Membaca satu kunci
GET https://nymbot.ai/api/v1/keys/{id} telah ditandatangani.
Kembali {"data": {…}} dengan objek utama, atau 404
key_not_found jika tiada kunci anda mempunyai id itu.
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);
Menukar Kunci
PATCH https://nymbot.ai/api/v1/keys/{id} telah ditandatangani.
Hantar mana-mana daripada name, limit_sats, reset_period dan
expire_at, dengan peraturan yang sama seperti apabila membuat kunci. null Mengubah tempoh reset memulakan tempoh baru pada nol. kunci yang dibatalkan tidak boleh diubah (400 key_revoked) Kembali
{"data": {…}} dengan objek kunci yang dikemas kini.
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);
Membatalkan Kunci
DELETE https://nymbot.ai/api/v1/keys/{id} telah ditandatangani.
Menghentikan kunci pada bila-bila masa, untuk kebaikan. ia kekal dalam senarai dengan revoked_at ditubuhkan, dan boleh dilihat dengan include_revoked=trueMembatalkan kunci yang telah dibatalkan menjawab dengan cara yang sama.Satu-satunya 50 kunci yang telah dibatalkan terkini disimpan; yang lebih tua dipadamkan apabila kunci lain dibatalkan.
Jawapan
{ "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());
Perkhidmatan NWC Auto-top-up
Menghubungkan dompet Lightning dengan Nostr Wallet Connect dan Nymbot menampung keseimbangan dengan sendirinya apabila pengeluaran API berjalan rendah. Permintaan ditandatangani.
Bagaimana ia berfungsi: selepas permintaan API dikenakan bayaran kepada baki yang anda pilih untuk menonton, jika baki itu telah jatuh di bawah ambang anda, Nymbot membuat invois untuk jumlah top-up anda, meminta dompet anda untuk membayarnya, dan menambah kredit. Ia melebihi maksimum sekali setiap 5 minit untuk setiap nym dan baki, jadi letupan permintaan tidak boleh mengosongkan dompet. Menghabiskan dalam aplikasi tidak memicu ia. Masa dan saiz top-up terakhir, dan kesilapan terakhir, berada dalam tetapan; jika pembayaran berlaku selepas kesilapan, semak invoisnya dengan Status Top-Up kredit kepada mereka.
Rantaian sambungan membolehkan sesiapa yang memegangnya meminta dompet anda untuk membayar.Nymbot menyimpannya disulitkan dan hanya pernah menggunakannya untuk membayar invois top-up sendiri, tetapi buat sambungan hanya untuk ini, dengan bajet pengeluaran dalam dompet anda, jadi yang paling ia boleh membayar adalah nombor yang dipilih anda. pay_invoice.
Menghubungkan Dompet
POST https://nymbot.ai/api/v1/nwc-auto-topup/connect telah ditandatangani.
| Lapangan | Jenis | diperlukan | Penerangan |
|---|---|---|---|
nwc_url | String yang | ya | Rangkaian sambungan, bermula nostr+walletconnect://Nymbot meminta dompet untuk get_info sebelum disimpan, dan menyimpan ia tersembunyi. |
threshold_sats | Integra | ya | Top up apabila baki jatuh di bawah ini banyak sats. sekurang-kurangnya 1,000. |
topup_sats | Integra | ya | Berapa banyak untuk menambah setiap kali. 1,000 hingga 1,000,000 sats. |
tier | String yang | Tidak | pro (Perkara yang telah ditetapkan) atau standard: keseimbangan untuk melihat dan top up. |
Jawapan
{
"data": {
"connected": true,
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
"last_topup_at": null,
"last_topup_sats": null,
"last_error": null
}
}
| Status | bila |
|---|---|
400 | Tiada rangkaian rangkaian (invalid_nwc_url(Baca juga: Perbincangan di atas tidak boleh dijawab)nwc_unreachable) atau menolak cek (nwc_rejected); sambungan tidak boleh membayar invois (nwc_missing_permission); atau jumlah di luar had. |
501 | Perkhidmatan ini tidak boleh diakses secara automatik (nwc_unavailable) Sama berlaku untuk kedua-dua titik akhir yang lain. |
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());
Membaca tetapan
GET https://nymbot.ai/api/v1/nwc-auto-topup telah ditandatangani.
Mengembalikan objek yang sama seperti menyambung, dengan connected: false dan bidang-bidang lain
null apabila tiada dompet yang disambungkan. rantaian sambungan itu sendiri tidak dikembalikan.
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());
Penyelesaian
DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection telah ditandatangani.
Menghapuskan string sambungan yang disimpan. Tiada lagi top-up dibuat. Untuk memastikan, anda juga boleh membatalkan sambungan dalam dompet anda.
Jawapan
{ "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());
Pembayaran Permintaan Tanpa Kunci
Titik akhir harga tetap boleh dibayar untuk satu permintaan pada satu masa sepanjang Lightning, tanpa kunci, tiada akaun dan tiada baki: POST /images/generations, POST /images/edits,
POST /videos, POST /audio/speech, POST /audio/transcriptions,
POST /audio/translations dan POST /embeddingsChat, Jawapan dan Mesej sentiasa memerlukan kunci. permintaan yang membawa kunci dikira ke baki seperti biasa; aliran pembayaran hanya bermula apabila tiada kunci dihantar.
Nymbot berbicara dua versi idea yang sama, daripada satu latar belakang: Lightning Labs
S402 (juga diterima di bawah nama lama, LSAT) dan rancangan IETF
Pembayaran Skim pengesahan HTTP dengan lightning kaedah dan
charge Gunakan apa sahaja yang pelanggan anda faham.
Bayar tanpa kunci hanya pada apabila API_L402_SECRET mempunyai sekurang-kurangnya 32 byte acak, seperti hex (64 watak) atau base64 (44). openssl rand -hex 32Nilai yang lebih pendek atau boleh ditebak mematikan ciri dan mencatat mengapa. API_L402_SECRET_PREVIOUS untuk satu hari: credentials, status URL dan cabaran yang dibuat di bawahnya terus berfungsi sehingga kedaluwarsa.
cabaran
Hantar permintaan dengan tidak Authorization header. jika ia sah, tiada apa-apa berjalan, dan anda mendapat 402 Payment Required dengan invois untuk apa yang kos permintaan itu: harga yang sama kunci akan membayar, ditukar kepada 10 sats kredit standard atau 100 sats kredit Pro dan disegerakkan sehingga keseluruhan sat (sekurang-kurangnya 1 sat, dan sekurang-kurangnya 0.05 minimum kredit). WWW-Authenticate Soalan-soalan untuk akaun yang sama:
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 }
}
Pembayaran request parameter ini ialah base64url JSON:
{"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.
Tindakan ini dikaitkan dengan titik akhir, kepada Content-Type (tipe media dan, untuk pelbagai bahagian, sempadan) dan kepada SHA-256 daripada bajet badan yang tepat yang anda hantar, dan berlangsung selama 15 minit. identik Soalan lain : sama
Content-Type dan sama byte JSON, atau untuk pelbagai titik akhir bahagian (/images/edits, /audio/transcriptions, /audio/translationsKebanyakan pustaka HTTP memilih sempadan baru setiap kali mereka mengkodkan borang, jadi mengkodnya sekali dan menghantar bajet itu dua kali.
Setiap alamat boleh meminta 30 cabaran setiap minit (sebuah alamat IPv6 dihitung sebagai keseluruhan /64). Permintaan yang alamat yang tidak diketahui berkongsi 10 yang lebih ketat setiap minit, dan terdapat cap keseluruhan pada cabaran Nymbot masalah di semua alamat; permintaan yang ditolak sebelum cabaran dibuat (contohnya dengan badan yang tidak sah JSON) tidak dihitung ke arahnya. 429 dengan Retry-After, dihantar sebelum badan dibaca. titik akhir dibayar yang dipanggil tanpa kunci atau credential juga dihitung ke arah had umum 120 permintaan yang tidak disahkan per minit setiap alamat. Content-Type Bukan application/json ( atau
multipart/form-data Oleh yang demikian, ia telah ditolak oleh 415 dan tidak pernah menerima akaun.
Embeddings dinilai daripada anggaran token dalam input, dengan 1.5× margin, kerana bilangan sebenar hanya dikenali selepas itu. Kembalikan Token.
Menghantar Pembayaran
Bayar invois dengan mana-mana dompet Lightning. Dompet memberi anda imej pra, 64 watak hex. Kemudian hantar permintaan yang sama dengan salah satu daripada ini:
| Rancangan | Header yang |
|---|---|
| S402 | Authorization: L402 <macaroon>:<preimage> (LSAT juga boleh bekerja) |
| Pembayaran | Authorization: Payment <base64url JSON>Di mana JSON ialah {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}} |
Permintaan berbayar menjawab persis seperti yang dibuat dengan kunci, kecuali bahawa nymbot
objek tidak mempunyai medan keseimbangan: {"payment": "l402", "tier": "pro", "paid_sats": 237,
"charged_sats": 237}Dan terdapat tidak X-Nymbot-Balance-Sats permohonan yang dibayar dengan skim Pembayaran juga menerima Payment-Receipt header (base64url JSON dengan id cabaran, hash pembayaran sebagai reference, status dan
timestampPermintaan berbayar tidak dikaitkan dengan sebarang nym, jadi mereka tidak muncul dalam sejarah pertanyaan.
| Status | bila |
|---|---|
402 payment_already_used | Setiap bayaran membayar untuk satu permintaan. jawapan adalah cabaran baru untuk permintaan ini, jadi pelanggan yang memadamkan credential terakhir (seperti lnget (Sebenarnya, ia hanya berlaku sekali lagi. |
402 payment_mismatch | Pendaftaran telah dikeluarkan untuk titik akhir yang lain, Content-Type atau badan, atau membayar kurang daripada permintaan ini sekarang kos. cabaran baru untuk permintaan ini datang dengan ia; jika bayaran terlalu kecil, apa yang anda bayar kembali sebagai Kembalikan Token (refund_token dan refund_sats dalam badan yang lain). |
402 payment_expired | Lebih daripada 15 minit telah berlalu sejak cabaran. cabaran baru datang dengan itu. Jika gambar pra menunjukkan anda telah dibayar, apa yang anda telah dibayar kembali sebagai Kembalikan Token (refund_token dan refund_sats dalam badan), sekali; kredensial kemudian digunakan. |
401 invalid_preimage | Preimage tidak hash kepada hash pembayaran invoice. |
401 invalid_payment_credential | Kredensial itu disalah bentuk, telah diubah selepas Nymbot mengeluarkan, atau nama hash pembayaran Nymbot tidak pernah mengeluarkan invoice untuk. |
429 rate_limit_exceeded | Lebih daripada 30 credentials atau kunci yang gagal untuk mengesahkan datang dari alamat ini dalam satu minit, atau satu token bayaran balik dihantar lebih daripada 60 kali dalam satu minit. 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"));
Pelanggan yang dibina mppx dengan kaedah Lightning menangani cabaran Pembayaran sendiri; tunjukkan mereka di titik akhir dan biarkan mereka membayar.
Video yang
yang dibayar POST /videos Jawapan 202 seperti sebuah kunci, plus a
status_url: GET ia tanpa sebarang kunci untuk mengikuti kerja. ia ditandatangani dan berfungsi selama 24 jam, selagi kerja disimpan.
{
"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..."
}
}
simpanlah refund_token daripada jawapan ini: ia dipaparkan hanya di sini. Ia kosong sementara videoGET /api/v1/l402/refunds Jawapan "status": "pending"); jika render gagal dibayar, bayaran mendarat di atasnya. URL status menunjukkan
refund_sats untuk kerja yang dikembalikan tetapi tidak pernah token, jadi berkongsi URL status tidak berkongsi pengembalian.
Pengembalian
Jika permintaan berbayar gagal dan pembekal dikenakan bayaran kepada Nymbot untuk percubaan, bayaran disimpan dan kesilapan berkata demikian, dengan charged_sats, sama seperti permintaan kunci.Jika ia gagal tanpa dikira, kesilapan membawa Kembalikan Token Berharga apa yang anda bayar:
{
"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"
}
}
Bahagian-bahagian yang tidak digunakan kembali dengan cara yang sama: jika anda meminta dua imej dan satu gagal dibebankan, jawapan kejayaan nymbot objek membawa token pengembalian wang untuk yang hilang; transkrip yang panjangnya tidak boleh dibaca di hadapan harga untuk yang paling lama fail boleh (tidak lebih daripada 30 minit), dan perbezaan kepada panjang sebenar kembali sebagai token pengembalian wang; jika ia ternyata lebih lama daripada 30 minit, ia ditolak dengan 413
dan semua bayaran dikembalikan. embeddings mengembalikan apa yang dikehendaki. video yang gagal mengembalikan token yang dikembalikan.
Token pengembalian wang adalah kod 256-bit acak. Nymbot hanya menyimpan hashnya, dan ia tamat tempoh selepas 30 hari. Ia memegang baki sat, dan anda boleh:
- Bayarlah dengan itu. hantar
Authorization: Bearer REFUND-…Perbezaan di antara kedua-duanya ialah di mana-mana kawasan yang mempunyai kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang mempunyai kawasan-kawasan yang berlainan.refund_token_satsDi dalamnymbotobjek). token bernilai kurang daripada jawapan permintaan402refund_insufficient; kegagalan yang tidak dikira meletakkan sats kembali pada token yang sama. - Periksa ia
GET /api/v1/l402/refundsdengan header yang sama kembali{"sats": 237, "status": "open", "expires_at": "..."}. - Satu token boleh digunakan sehingga 60 kali setiap minit.
- Masukkan ke dalam nym. Masukkan ke dalam Kembalikan hadiah dalam aplikasi Nymbot, atau panggilan
POST /api/v1/l402/refunds/redeemDengan a Permintaan ditandatangani dan{"refund_token": "REFUND-...", "balance": "standard"}( atau"pro"Semua kredit pergi ke baki (10 sats masing-masing pada standard, 100 pada Pro); sats yang tidak membuat keseluruhan kredit tinggal pada token untuk permintaan 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"
Jawapan
{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }