בסיס ידע מפתחים
רזולוציה, top-ups ו keys
בדוק מה יש לך, העלילה מעל Lightning, העלילה אוטומטית מן הארנק שלך, לראות מה כל בקשה עולה, ולנהל מפתחות מן הקוד.
דף זה תורגם במכונה לנוחיותך. המקור האנגלי הוא הגרסה החלה.
בדוק את האיזון
שניהם משאבים שלך, וכמה של כיסוי המפתח הזה משמש.
GET https://nymbot.ai/api/v1/credits/balance אתה צריך מפתח API. POST זה עובד גם עבור לקוחות שמחכים לזה.
balance הוא שני משקלים יחד בדולרים במחיר Bitcoin הנוכחי, עבור כלים שמצפים מספר יחיד (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 אין צורך במפתח.
Top-up הוא 10 עד 1,000,000 sats; Pro top-up חייב לקנות לפחות קרדיט Pro אחד, אז זה מתחיל ב 100 sats. bulk_bonus מציג את האשראי הנוסף על Top-ups גדולים יותר, אותו הדבר כמו באפליקציה: 10%, 15% או 20% יותר על Top-ups סטנדרטיים מ 500, 1,000 או 5,000 sats, ועל Pro Top-ups מ 5,000, 10,000 או 50,000 sats.
תשובות
{
"supported_methods": [
{
"method": "btc-lightning",
"display_name": "Bitcoin Lightning",
"supported_currencies": ["SATS", "USD", "BTC"],
"limits": {
"SATS": { "min": 10, "max": 1000000 },
"USD": { "min": 0.02, "max": 1170 },
"BTC": { "min": 1e-7, "max": 0.01 }
},
"tiers": ["standard", "pro"],
"default_tier": "pro",
"tier_min_sats": { "standard": 10, "pro": 100 },
"sats_per_credit": { "standard": 10, "pro": 100 },
"bulk_bonus": [
{ "bonus": 0.1, "standard_sats": 500, "pro_sats": 5000 },
{ "bonus": 0.15, "standard_sats": 1000, "pro_sats": 10000 },
{ "bonus": 0.2, "standard_sats": 5000, "pro_sats": 50000 }
]
}
]
}
cURL
curl https://nymbot.ai/api/v1/topup/payment-methods
Python
import requests
methods = requests.get("https://nymbot.ai/api/v1/topup/payment-methods").json()
print(methods["supported_methods"][0]["limits"])
JavaScript
const methods = await (await fetch("https://nymbot.ai/api/v1/topup/payment-methods")).json();
console.log(methods.supported_methods[0].limits);
צפייה ב-Up Over Lightning
יוצר חשבונית ברק שמוסיפה אשראי לניום שהמפתח שייך לו. בדוק את כדי להוסיף את ההלוואה.
POST https://nymbot.ai/api/v1/topup/create/btc-lightning אתה צריך מפתח API.
| שדה | סוג | דרושה | תיאור |
|---|---|---|---|
amount | מספר | כֵּן | עד כמה, בתוך currencyמספר שלם למטרה. |
currency | String | לא | SATS (ההתנצלות היא USD או BTCדולרים מוחלפים במחיר Bitcoin הנוכחי. |
tier | String | לא | pro (הפסקת התשלום) או standardאיזו איזון הלוואה הולכת אליו. |
אשראי סטנדרטי הוא 10 sats ו Pro אשראי 100 sats, בתוספת כל בונוס נפח;
credits תגידו מה יוסיף החשבון הזה.
תשובות
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"payment_request": "lnbc100u1p5...",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": "2026-09-30T09:27:00Z",
"status": "pending"
}
| סטטוס | מתי |
|---|---|
400 | שיטה נוספת בדרך (unsupported_method, מטבע לא ידוע (unsupported_currency(למשל, סכום שנמצא מתחת למינימום או סכום שחסר)amount_too_small(למעלה מ-100 אלף ש"ח)amount_too_large) או נדחתה על ידי הארנק Lightning (amount_out_of_range). |
429 | יותר מ 60 חשבונות עבור נימ הזה, או 120 מכתובת זו, בשעה אחת (rate_limit_exceededעם Retry-After). |
502 | כרגע לא ניתן להגיש חשבונית (invoice_unavailableעם Retry-After). |
cURL
curl https://nymbot.ai/api/v1/topup/create/btc-lightning \
-H "Authorization: Bearer $NYMBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{"amount": 10000, "currency": "SATS", "tier": "pro"}'
Python
import os
import requests
res = requests.post(
"https://nymbot.ai/api/v1/topup/create/btc-lightning",
headers={"Authorization": "Bearer " + os.environ["NYMBOT_API_KEY"]},
json={"amount": 10000, "currency": "SATS", "tier": "pro"},
)
invoice = res.json()
print(invoice["payment_request"])
JavaScript
const res = await fetch("https://nymbot.ai/api/v1/topup/create/btc-lightning", {
method: "POST",
headers: {
"Authorization": "Bearer " + process.env.NYMBOT_API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({ amount: 10000, currency: "SATS", tier: "pro" }),
});
const invoice = await res.json();
console.log(invoice.payment_request);
בדיקת Top-Up
שואל אם החשבונית כבר שילמה, ולאחר מכן מוסיף את האשראי. creditedבדיקה נוספת לאחר מכן היא בטוחה: האשראי נחת פעם אחת, לא משנה כמה פעמים אתה שואל.
GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - זקוק למפתח מהנימה שביצעה את החשבון.
status זה pending (עדיין לא הוגשה תשלום) paid (שלם, אבל עדיין לא הוענק; בדוק שוב), credited (על חשבון שלך) או expired (לא משלמים בזמן) שדות האיזון הם עבור הרמה שהחשבון עולה עליה.
תשובות
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"status": "credited",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": null,
"balance_credits": 523.33,
"balance_sats": 52333
}
| סטטוס | מתי |
|---|---|
400 | ה-ID אינו ה-ID בעל 64 תווים מהשיחה שנוצרה. |
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);
רוצה היסטוריה
שורה אחת לכל בקשה: מה זה היה, איזה מודל, כמה טוקינים וכמה זה עולה. אין תובנות או תשובות נשמרות, כך שאף אחד לא חוזר. שורות נשמרות במשך 90 ימים, העדכון הראשון. מפתח שהגיע לקו יכול עדיין לקרוא את ההיסטוריה שלו.
GET https://nymbot.ai/api/v1/queries/history - צריך מפתח API, אשר רואה את הבקשות שלו, או בקשת חתימה מהנימוס שלך, אשר רואה את כל המפתחות.
| שדה | סוג | דרושה | תיאור |
|---|---|---|---|
page | תגית: Query | לא | דפדפן 1, עד 1,000; דף גבוה יותר הוא 400 invalid_value. |
page_count | תגית: Query | לא | שורות לדף, כברירת מחדל 20, מקסימום 100. |
start_dateend_date | תגית: Query | לא | ISO 8601 תאריכים ושעות |
model | תגית: Query | לא | רק מודל זה. |
type | תגית: Query | לא | chat, responses, messages, image, video, speech, transcription או embedding. |
all_keys | בואינג (בואינג Query) | לא | עם מפתח אחד: true כולל כל מפתח של אותו nym.Default false. |
key_id | תגית: Query | לא | עם בקשה מסודרת או עם all_keys=trueרק המפתח הזה. |
תשובות
{
"data": [
{
"id": "q_71c4e9a0",
"timestamp": "2026-09-30T08:12:00Z",
"model": "anthropic/claude-sonnet-5",
"type": "chat",
"input_tokens": 1240,
"output_tokens": 380,
"cached_tokens": 0,
"cost_sats": 16.2,
"cost_usd": 0.01895,
"balance": "pro",
"key_id": "4f0c9a1be27d3856",
"web_search": false,
"status": "ok"
}
],
"pagination": { "page": 1, "page_count": 20, "total": 311, "total_pages": 16 }
}
cURL
curl "https://nymbot.ai/api/v1/queries/history?page_count=50&type=chat" \
-H "Authorization: Bearer $NYMBOT_API_KEY"
Python
import os
import requests
res = requests.get(
"https://nymbot.ai/api/v1/queries/history",
headers={"Authorization": "Bearer " + os.environ["NYMBOT_API_KEY"]},
params={"page_count": 50, "type": "chat"},
)
for row in res.json()["data"]:
print(row["timestamp"], row["model"], row["cost_sats"])
JavaScript
const res = await fetch("https://nymbot.ai/api/v1/queries/history?page_count=50&type=chat", {
headers: { "Authorization": "Bearer " + process.env.NYMBOT_API_KEY },
});
for (const row of (await res.json()).data) console.log(row.timestamp, row.model, row.cost_sats);
חתימת בקשות חשבונות
יצירת, שינוי וביטול מפתחות, סיכום החשבון ואת top-ups אוטומטיים לא לוקחים מפתח API.
האפליקציה עושה את זה בשבילך: הכל בתוכו אש אתה רק צריך את החלק הזה כדי לנהל את המפתחות מהקוד שלך.
החתימה היא אירוע Nostr מסוג 27235 (NIP-98), שנשלח על-ידי Base64
Authorization Header עם המילה Nostr על החזית :
האירוע
{
"kind": 27235,
"created_at": 1790726400,
"tags": [
["u", "https://nymbot.ai/api/v1/keys"],
["method", "POST"],
["nonce", "9c4e21f07a3b...16 random bytes in hex"],
["payload", "3f1a0d7c8e2b...sha256 of the exact request body in hex"]
],
"content": "",
"pubkey": "your public key in hex",
"id": "...",
"sig": "..."
}
uהוא ה-URL המלא של הבקשה, כולל שורת השאילתה, בדיוק כפי שנשלחה.methodזהו שיטת HTTP.payloadהוא SHA-256 של הגוף של בקשת גלם, בהקצאה.POSTוPATCH, ואת הגוף שאתה שולח חייב להיות בייט עבור בייט אחד שאתה hashed.created_atזה חייב להיות בתוך 60 שניות מהשעון של השרת.- כל אירוע עובד פעם אחת, a
GETלא ניתן לשחק מחדש את הכותרת שנלכדה.חתום על כותרת חדשה עבור כל בקשה.nonceתווית עם ערך אקראי כך ששתי בקשות שנחתמו באותה שניה עדיין שונות. - הגוף של בקשה חתומה יכול להיות עד 64 KB, והגוף צריך
Content-Type: application/json.
אירוע אבוד חוזר 401 missing_nostr_authאחד שנוצר רע, חתום רע, ישן מדי, או עבור כתובת URL שונה, שיטה או גוף חוזרים
invalid_nostr_auth, עם הסיבה בהודעה; שימוש חוזר אחד חוזר
nostr_auth_replayedהחתימה נבדקת לפני שקראת את הגוף, וכל כתובת יכולה להיכשל בזה 30 פעמים לדקה (כתובת IPv6 נחשבת לכל /64); לאחר מכן היא מקבלת 429 עם
Retry-After.
דפדפנים יכולים להתקשר לנקודות הקצה הללו רק מהאתרים של Nymbot (https://nymbot.ai,
https://nymchat.app דף בכל אתר אחר לא מקבל כותרות CORS בחזרה, כך שהוא לא יכול לקרוא את מה שהם חוזרים.
Originהם לא מושפעים.
חתימה צריכה את המפתח הסודי של נים שלך (The nsecרק לשים את זה בסקריפט על מכונה שאתה סומך עליה, לקרוא אותו מהסביבה במקום לכתוב אותו לקובץ, ולהעדיף את האפליקציה כאשר אתה יכול.
עוזרים אלה בונים את הכותרת. הדוגמאות המאוחרות בדף זה משתמשות בהם. NOSTR_SECRET_HEXcURL one משתמש ב
נוק כלי שורת הפקודה, אשר לוקח מפתח 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 של האפליקציה מראה בחלק העליון: המפתח הציבורי שלך, שניהם שווים, כמה מפתחות פעילים (לא בוטלו או נעלמו), ואת Top-up אוטומטי הגדרות או
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());
ניהול מפתחות
נקודות הקצה שמאחורי רשימת המפתח של האפליקציה. בקשת חתימהכל מפתח חוזר בצורה זו, עם זמנים ב- 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.
| שדה | סוג | דרושה | תיאור |
|---|---|---|---|
name | String | כֵּן | 1 עד 40 תווים, שונים מפתחות הפעילות האחרות שלך (עלול להתעלם מקרה). |
limit_sats | אינטגר | לא | מחירי המזומנים במזומן, לפחות 1.השאיר את זה בחוץ ללא מחירי. |
reset_period | String | לא | daily, weekly או monthlyדרושים limit_satsהשאירו את זה בחוץ עבור כובע שמעולם לא מחזיר. |
expire_at | String או 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(למשל, לא ניתן להשיג את כל המספרים המלאים (למשל, לא ניתן להשיג את כל המספרים המלאים של המספרים המלאים של המספרים המלאים של המספרים המלאים של המספרים המלאים של המספרים המלאים של המספרים המלאים של המספרים המלאים של המספרים המלאים של המספרים המלאים).unknown_parameter); או 25 מפתחות פעיל כבר (too_many_keys). |
429 | יותר מ 60 מפתחות שנוצרו על ידי ניום זה, או 120 מכתובת זו, בשעה אחת (rate_limit_exceededעם Retry-After). |
cURL
URL=https://nymbot.ai/api/v1/keys
BODY='{"name":"laptop scripts","limit_sats":20000,"reset_period":"monthly"}'
curl "$URL" \
-H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
-H "Content-Type: application/json" \
-d "$BODY"
Python
import json
import requests
url = "https://nymbot.ai/api/v1/keys"
body = json.dumps({"name": "laptop scripts", "limit_sats": 20000, "reset_period": "monthly"}).encode()
res = requests.post(
url,
data=body,
headers={"Authorization": nostr_auth("POST", url, body), "Content-Type": "application/json"},
)
print(res.json()["data"]["key"])
JavaScript
const url = "https://nymbot.ai/api/v1/keys";
const body = JSON.stringify({ name: "laptop scripts", limit_sats: 20000, reset_period: "monthly" });
const res = await fetch(url, {
method: "POST",
headers: { "Authorization": nostrAuth("POST", url, body), "Content-Type": "application/json" },
body,
});
console.log((await res.json()).data.key);
קריאת מפתח אחד
GET https://nymbot.ai/api/v1/keys/{id} חתם על
חזרה {"data": {…}} עם האובייקט המפתח, או 404
key_not_found אם אין מפתח שלך יש מזהה זה.
cURL
URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json()["data"])
JavaScript
const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
console.log((await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json()).data);
שינוי מפתח
PATCH https://nymbot.ai/api/v1/keys/{id} חתם על
שלח כל אחד name, limit_sats, reset_period ו
expire_atעם אותם כללים כמו בעת ביצוע מפתח. null שחרור שדה: אין כיסוי, אין הגדרת מחדש, אין תוקף. שינוי תקופת הגדרת מחדש מתחיל תקופה חדשה מאפס.400 key_revoked) החזרה
{"data": {…}} עם האובייקט המפתח המעודכן.
cURL
URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
BODY='{"limit_sats":50000,"expire_at":null}'
curl -X PATCH "$URL" \
-H "Authorization: $(nostr_auth PATCH "$URL" "$BODY")" \
-H "Content-Type: application/json" \
-d "$BODY"
Python
import json
import requests
url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
body = json.dumps({"limit_sats": 50000, "expire_at": None}).encode()
res = requests.patch(
url,
data=body,
headers={"Authorization": nostr_auth("PATCH", url, body), "Content-Type": "application/json"},
)
print(res.json()["data"])
JavaScript
const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
const body = JSON.stringify({ limit_sats: 50000, expire_at: null });
const res = await fetch(url, {
method: "PATCH",
headers: { "Authorization": nostrAuth("PATCH", url, body), "Content-Type": "application/json" },
body,
});
console.log((await res.json()).data);
ביטול מפתח
DELETE https://nymbot.ai/api/v1/keys/{id} חתם על
עוצר את המפתח בבת אחת, טוב.הוא נשאר ברשימה עם revoked_at מופיע, ניתן לראות עם include_revoked=trueביטול מפתח שכבר בוטל עונה באותו אופן: רק 50 המפתחות החדשות ביותר שנמחקו נשמרות; אלה הישנים נמחקים כאשר מפתח אחר בוטל.
תשובות
{ "data": { "id": "4f0c9a1be27d3856", "revoked": true } }
cURL
URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
curl -X DELETE "$URL" -H "Authorization: $(nostr_auth DELETE "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
print(requests.delete(url, headers={"Authorization": nostr_auth("DELETE", url)}).json())
JavaScript
const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
const res = await fetch(url, { method: "DELETE", headers: { "Authorization": nostrAuth("DELETE", url) } });
console.log(await res.json());
תגית: NWC Auto-top-up
חיבור ארנק Lightning עם Nostr Wallet Connect ו- Nymbot מעלה את האיזון בעצמם כאשר הוצאות API פועלות אותו נמוך. בקשת חתימה.
איך זה עובד: לאחר בקשת API מוטלת על הסכום שבחרת לצפות, אם הסכום הזה ירד מתחת לסף שלך, Nymbot עושה חשבונית עבור הסכום העליון שלך, מבקש את הארנק שלך לשלם את זה, ומוסיף את ההלוואה. זה עולה למעלה פעם אחת בכל 5 דקות עבור כל נים ומשקל, כך שבץ של בקשות לא יכול לשטוף את הארנק. הוצאות באפליקציות לא להפעיל את זה. הזמן והגודל של העליון האחרון, ואת השגיאה האחרונה, נמצאים בהגדרות; אם תשלום עבר לאחר שגיאה, בדוק את החשבונית שלה עם מצב Top-Up אשראי את זה.
מחרוזת חיבור מאפשרת לכל מי שמחזיק אותה לבקש את הארנק שלך לשלם.Nymbot שומר אותו מוצפן ורק משתמש בו כדי לשלם את החשבונות העליונים שלו, אבל ליצור חיבור רק בשביל זה, עם תקציב הוצאות בארנק שלך, אז הכי זה יכול לשלם הוא מספר בחר אותך. pay_invoice.
חיבור ארנק
POST https://nymbot.ai/api/v1/nwc-auto-topup/connect חתם על
| שדה | סוג | דרושה | תיאור |
|---|---|---|---|
nwc_url | String | כֵּן | הקשר המשותף, מתחיל nostr+walletconnect://Nymbot מבקש את הארנק עבור get_info לפני שאתה שומר אותו, ולאחסן אותו מוצפן. |
threshold_sats | אינטגר | כֵּן | מעלה את זה כאשר האיזון נופל מתחת לזה הרבה sats. |
topup_sats | אינטגר | כֵּן | כמה להוסיף בכל פעם. 1,000 עד 1,000,000 sats. |
tier | String | לא | pro (הפסקת התשלום) או standard: את האיזון לצפות ולמעלה. |
תשובות
{
"data": {
"connected": true,
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
"last_topup_at": null,
"last_topup_sats": null,
"last_error": null
}
}
| סטטוס | מתי |
|---|---|
400 | לא קישור לקטגוריה (invalid_nwc_url(החוברת לא ענתה על השידור שלה)nwc_unreachable) או סירב לבדוק (nwc_rejected); החיבור אינו יכול לשלם חשבונות (nwc_missing_permission); או סכום מחוץ לגבולות. |
501 | לא ניתן להפעיל את המכשיר באופן אוטומטי (nwc_unavailableכך גם לגבי שתי נקודות הסוף האחרות. |
cURL
URL=https://nymbot.ai/api/v1/nwc-auto-topup/connect
BODY='{"nwc_url":"nostr+walletconnect://...","threshold_sats":5000,"topup_sats":20000,"tier":"pro"}'
curl "$URL" \
-H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
-H "Content-Type: application/json" \
-d "$BODY"
Python
import json, os
import requests
url = "https://nymbot.ai/api/v1/nwc-auto-topup/connect"
body = json.dumps({
"nwc_url": os.environ["NWC_URL"],
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
}).encode()
res = requests.post(
url,
data=body,
headers={"Authorization": nostr_auth("POST", url, body), "Content-Type": "application/json"},
)
print(res.json())
JavaScript
const url = "https://nymbot.ai/api/v1/nwc-auto-topup/connect";
const body = JSON.stringify({
nwc_url: process.env.NWC_URL,
threshold_sats: 5000,
topup_sats: 20000,
tier: "pro",
});
const res = await fetch(url, {
method: "POST",
headers: { "Authorization": nostrAuth("POST", url, body), "Content-Type": "application/json" },
body,
});
console.log(await res.json());
לקרוא את ההגדרות
GET https://nymbot.ai/api/v1/nwc-auto-topup חתם על
מחזירה את אותו אובייקט כמו חיבור, עם connected: false ושאר השדות
null כאשר לא קיים חיבור לכספת, הקשר עצמו לעולם אינו חוזר.
cURL
URL=https://nymbot.ai/api/v1/nwc-auto-topup
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/nwc-auto-topup"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json())
JavaScript
const url = "https://nymbot.ai/api/v1/nwc-auto-topup";
console.log(await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json());
מחסום
DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection חתם על
מוחק את מחרוזת החיבור המאוחסנת. לא מתבצעות עוד עליות.כדי להיות בטוחים, באפשרותך גם לבטל את החיבור בארנק שלך.
תשובות
{ "data": { "connected": false, "threshold_sats": null, "topup_sats": null, "tier": null, "last_topup_at": null, "last_topup_sats": null, "last_error": null } }
cURL
URL=https://nymbot.ai/api/v1/nwc-auto-topup/connection
curl -X DELETE "$URL" -H "Authorization: $(nostr_auth DELETE "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/nwc-auto-topup/connection"
print(requests.delete(url, headers={"Authorization": nostr_auth("DELETE", url)}).json())
JavaScript
const url = "https://nymbot.ai/api/v1/nwc-auto-topup/connection";
const res = await fetch(url, { method: "DELETE", headers: { "Authorization": nostrAuth("DELETE", url) } });
console.log(await res.json());
תשלום לפי בקשה ללא מפתח
נקודות הקצה במחיר קבוע ניתן לשלם על בקשה אחת בכל פעם על ידי Lightning, ללא מפתח, ללא חשבון ואין איזון: POST /images/generations, POST /images/edits,
POST /videos, POST /audio/speech, POST /audio/transcriptions,
POST /audio/translations ו POST /embeddingsהצ'אט, התשובות והודעות תמיד זקוקות למפתח; בקשה שמחזיקה במפתח מחויבת לאיזון כרגיל; זרימת התשלום מתחילה רק כאשר אין מפתח שנשלח.
Nymbot מדבר על שתי גרסאות של אותו רעיון, מאותו backend: Lightning Labs'
א 402 (גם תחת השם הישן שלו, LSAT) ופרויקט IETF
תשלום תוכנית אימות HTTP עם lightning שיטה ו
charge השתמש במה שהלקוח שלך מבין.
תשלום ללא מפתח הוא רק כאשר API_L402_SECRET מחזיק לפחות 32 bytes אקראיים, כגון hex (64 תווים) או base64 (44). openssl rand -hex 32ערך קצר יותר או אפשרי לנחש מפעיל את התכונה ומזכיר מדוע. API_L402_SECRET_PREVIOUS במשך יום אחד: אישורים, כתובות URL של מצב ואתגרים שנעשו תחת זה ממשיכים לעבוד עד שהם נופלים.
האתגר
שלח את הבקשה עם לא Authorization אם זה נכון, שום דבר לא פועל, ואתה מקבל 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 base64url JSON
{"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.
האתגר הוא קשור לנקודה הסופית, ל Content-Type (הסוג של המדיה, ובמקרה של חלקים מרובים, הגבול שלה) ול- SHA-256 של הבייטים המדויקים של הגוף שאתה שולח, והוא נמשך 15 דקות. זהות בקשה נוספת: אותו דבר
Content-Type תגיות קשורות תגיות קשורות תגיות קשורות תגיות קשורות תגיות קשורות תגיות קשורות תגיות קשורות תגיות קשורות תגיות קשורות תגיות קשורות תגיות/images/edits, /audio/transcriptions, /audio/translationsרוב ספריות HTTP בוחרות גבול חדש בכל פעם שהם מקודדים טופס, אז לקודד אותו פעם אחת ולשלוח את הבייטים האלה פעמיים.
כל כתובת יכולה לבקש 30 אתגרים לדקה (כתובת IPv6 מחושבת כ /64 שלמה). בקשות שהכתובת שלהם לא ידועה חולקות 10 דקה יותר קפדנית, ויש מגבלת כללית על אתגרים Nymbot בעיות בכל הכתובות; בקשה נדחתה לפני שנעשה אתגר (לדוגמה, עם גוף שאינו JSON תקף) לא נחשב כלפי זה. 429 עם Retry-Afterנקודות קצה בתשלום שהתקבלו ללא מפתח או הכרזה נחשבות גם למגבלת הכללית של 120 בקשות לא מאושרות לדקה לכל כתובת. Content-Type זה לא application/json (או
multipart/form-data על פי ההסכם, הוא מסרב 415 אף פעם לא מקבלים חשבונית.
השבבים מוערכים על-ידי הערכה של התוויות בהכנסה, עם 1.5× מרווח, שכן המספר האמיתי ידוע רק לאחר מכן. חזר טוקיו.
לשלוח את התשלום
לשלם את החשבון עם כל ארנק אש. הארנק נותן לך את התמונה הקדמית, 64 תווים שישים.
| התכנית | Header |
|---|---|
| א 402 | Authorization: L402 <macaroon>:<preimage> (LSAT גם זה עובד) |
| תשלום | Authorization: Payment <base64url JSON>היכן נמצא JSON {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}} |
בקשה בתשלום עונה בדיוק כמו זו שנעשתה עם מפתח, למעט nymbot
לאובייקט אין שדות איזון: {"payment": "l402", "tier": "pro", "paid_sats": 237,
"charged_sats": 237}וכאן אין X-Nymbot-Balance-Sats בקשה ששולמה עם תוכנית התשלום מקבלת גם Payment-Receipt כותרת (base64url JSON with the challenge id, the payment hash as reference, status ו
timestampבקשות בתשלום אינן קשורות לכל נים, ולכן הן לא מופיעות בהיסטוריה של השאילתה.
| סטטוס | מתי |
|---|---|
402 payment_already_used | כל תשלום משלם עבור בקשה אחת.התשובה היא אתגר חדש עבור בקשה זו, כך לקוח שמאחסן את הסמכות האחרונה שלו (כגון lnget א) פשוט לחזור על זה. |
402 payment_mismatch | ההרשמה נמסרה לנקודה נוספת, Content-Type או גוף, או לשלם פחות מאשר בקשה זו עכשיו עולה. אתגר חדש עבור בקשה זו מגיע עם זה; אם התשלום היה קטן מדי, מה שילמתם חוזר כאתגר. חזר טוקיו (refund_token ו refund_sats בתוך הגוף ) |
402 payment_expired | יותר מ-15 דקות חלפו מאז האתגר.אתגר חדש מגיע איתו.אם התמונה הקדמית מראה שאתה שילמת, מה ששילמת חוזר כאתגר. חזר טוקיו (refund_token ו refund_sats לאחר מכן, לאחר מכן, המשתמש משתמש. |
401 invalid_preimage | התמונה המוקדמת אינה חותמת את חותמת התשלום של החשבונית. |
401 invalid_payment_credential | הכרזה שגויה, השתנתה לאחר ש-Nymbot הוציאה אותה, או שמות שקיות תשלום ש-Nymbot מעולם לא הוציאה חשבונית. |
429 rate_limit_exceeded | יותר מ-30 אישורים או מפתחות שלא הצליחו לאמת הגיעו מהכתובת הזו בתוך דקה, או טוקן החזר אחד נשלח יותר מ 60 פעמים בדקה. Retry-After. |
cURL
BODY='{"model":"nano-banana","prompt":"a lighthouse at dusk","response_format":"b64_json"}'
URL=https://nymbot.ai/api/v1/images/generations
# 1. Get the challenge
CH=$(curl -s -D - -o /dev/null "$URL" -H "Content-Type: application/json" -d "$BODY" | grep -i '^www-authenticate: L402')
MAC=$(echo "$CH" | sed -E 's/.*macaroon="([^"]+)".*/\1/')
INVOICE=$(echo "$CH" | sed -E 's/.*invoice="([^"]+)".*/\1/')
# 2. Pay $INVOICE with your wallet and copy the preimage
PREIMAGE=...
# 3. Send the identical request with the credential
curl "$URL" -H "Content-Type: application/json" -H "Authorization: L402 $MAC:$PREIMAGE" -d "$BODY"
lnget
# lnget (Lightning Labs) pays L402 challenges from your own lnd node and retries for you
lnget -X POST -H "Content-Type: application/json" \
-d '{"model":"nano-banana","prompt":"a lighthouse at dusk","response_format":"b64_json"}' \
https://nymbot.ai/api/v1/images/generations
Python
import base64, json, re
import requests
url = "https://nymbot.ai/api/v1/images/generations"
body = json.dumps({"model": "nano-banana", "prompt": "a lighthouse at dusk", "response_format": "b64_json"}).encode()
headers = {"Content-Type": "application/json"}
challenge = requests.post(url, data=body, headers=headers)
assert challenge.status_code == 402
info = challenge.json()
print("Pay", info["amount_sats"], "sats:", info["invoice"])
preimage = pay_with_your_wallet(info["invoice"]) # 64 hex characters
# L402
mac = re.search(r'L402 macaroon="([^"]+)"', challenge.headers["WWW-Authenticate"]).group(1)
res = requests.post(url, data=body, headers={**headers, "Authorization": f"L402 {mac}:{preimage}"})
print(res.json()["nymbot"])
JavaScript
const url = "https://nymbot.ai/api/v1/images/generations";
const body = JSON.stringify({ model: "nano-banana", prompt: "a lighthouse at dusk", response_format: "b64_json" });
const headers = { "Content-Type": "application/json" };
const challenge = await fetch(url, { method: "POST", headers, body });
const www = challenge.headers.get("www-authenticate");
// The Payment scheme: echo every challenge parameter back with the preimage
const start = www.indexOf("Payment ");
const params = Object.fromEntries([...www.slice(start + 8).matchAll(/(\w+)="((?:[^"\\]|\\.)*)"/g)].map((m) => [m[1], m[2]]));
const { invoice } = JSON.parse(Buffer.from(params.request, "base64url").toString()).methodDetails;
const preimage = await payWithYourWallet(invoice);
const credential = Buffer.from(JSON.stringify({ challenge: params, payload: { preimage } })).toString("base64url");
const res = await fetch(url, { method: "POST", headers: { ...headers, Authorization: `Payment ${credential}` }, body });
console.log((await res.json()).nymbot, res.headers.get("payment-receipt"));
הלקוחות נבנו על mppx עם שיטת ברק להתמודד עם אתגר התשלום עצמם; להדגיש אותם בנקודה הסופית ולתת להם לשלם.
וידאו
תשלום POST /videos תשובות 202 כמו מפתח אחד, פלוס 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..."
}
}
שמור את refund_token התשובה היא פשוטה: זה לא מופיע בסרטון, זה לא מופיע (GET /api/v1/l402/refunds תשובות "status": "pending"); אם ההפצה נכשלה ללא חיוב, התשלום נחת על זה.
refund_sats עבור עבודה משולמת, אך לעולם לא את ה- token, כך שיתוף ה- URL של המצב אינו משתף את ההחזר.
החזר
אם בקשה בתשלום נכשלה והספק חשב על Nymbot עבור הניסיון, התשלום נשמר והשגיאה אומרת כך, עם charged_sats, בדיוק כמו בקשה מפתח.אם זה נכשל ללא חיוב, השגיאה נושאת חזר טוקיו שווה מה ששילמתם:
{
"error": {
"message": "The image generator failed. Nothing was charged. Please try again. The 237 sats you paid are on refund token REFUND-...",
"type": "api_error",
"code": "upstream_error",
"refund_token": "REFUND-0C15DBED145D59131BA70298A413ADEB3D9B9AB082C476EA70A5BD38FCA5DE6D",
"refund_sats": 237,
"refund_expires_at": "2026-10-30T12:00:00.000Z"
}
}
החלקים הלא משתמשים חוזרים באותו אופן: אם ביקשתם שתי תמונות ואחת לא הוגשה, התשובה הצליחה. nymbot אובייקט נושאת חותם החזר עבור החסר; עותק שהאורך שלו לא יכול להיקרא מראש הוא מוערך עבור הארוך ביותר הקובץ יכול להיות (לעולם לא יותר מ 30 דקות), ואת ההבדל לאורך האמיתי חוזר כ חותם החזר; אם זה מתברר להיות יותר מ 30 דקות, זה נדחה עם 413
התשלומים מחזירים את מה שההערכה מחזיקה בחזרה.וידאו שנכשל מחזיר את הכרטיס שהצגת.
טוקן החזר כספי הוא קוד אקראי של 256 סיביות. Nymbot מאחסן רק את ההאש שלו, והוא נופל לאחר 30 ימים.
- לשלם עם זה. שלח
Authorization: Bearer REFUND-…על כל אחד מהחומרים המופיעים לעיל (החומרים המופיעים לעיל אינם מופיעים במקומות מסוימים, אלא אם כן הם מופיעים במקומות מסוימים).refund_token_satsב Thenymbotמטען שווה פחות מהתשובות לבקשתו402refund_insufficient· כישלון ללא חיוב מטיל את התעריף בחזרה על אותו טוקן. - בדוק את זה.
GET /api/v1/l402/refundsעם אותו header חוזר{"sats": 237, "status": "open", "expires_at": "..."}. - ניתן להשתמש בטוקיו אחד עד 60 פעמים לדקה.
- העבירו את זה ל-NIM. תכניסו אותו לתוך מחזירים מתנה באפליקציית Nymbot, או להתקשר
POST /api/v1/l402/refunds/redeemעם A בקשת חתימה ו{"refund_token": "REFUND-...", "balance": "standard"}(או"pro"כל הכרטיסים הולכים לאיזון (10 sats כל אחד על סטנדרטי, 100 על פרו); 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 } }