Βάση γνώσεων Οι προγραμματιστές
Ισορροπία, κορυφές και κλειδιά
Ελέγξτε τι έχετε, ανεβάστε το 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);
Σηκώνοντας πάνω από την αστραπή
Δημιουργεί ένα λογαριασμό Lightning που προσθέτει πίστωση στο nym στο οποίο ανήκει το κλειδί. Πληρώστε το από οποιοδήποτε πορτοφόλι Lightning, στη συνέχεια Ελέγξτε το Για να προστεθεί η πίστωση.
POST https://nymbot.ai/api/v1/topup/create/btc-lightning Χρειάζεστε ένα API κλειδί.
| Το πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
amount | Αριθμός | Ναί | Πόσο, σε currencyΈνας ολόκληρος αριθμός για το ποντάρισμα. |
currency | Στρογγυλο | Όχι | SATS (Η αποτυχία είναι USD ή BTCΤα δολάρια μετατρέπονται στην τρέχουσα τιμή του Bitcoin. |
tier | Στρογγυλο | Όχι | 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Περισσότερα από 1 εκατομμύριο δολάρια (amount_too_large) ή απορρίφθηκε από το πορτοφόλι Lightning (amount_out_of_range). |
429 | Περισσότερα από 60 τιμολόγια για αυτό το nym, ή 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} - χρειάζεται ένα κλειδί από το nym που έκανε το τιμολόγιο.
status είναι pending (δεν έχει ακόμη καταβληθεί) paid (Πληρώθηκε, αλλά δεν έχει πιστωθεί ακόμα, ελέγξτε ξανά) credited (στην ισορροπία σας) ή expired (δεν πληρώνονται εγκαίρως).Τα πεδία ισοζυγίου είναι για το επίπεδο του τιμολογίου που κορυφώνεται.
Απάντηση
{
"invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
"status": "credited",
"amount_sats": 10000,
"credits": 115,
"tier": "pro",
"expires_at": null,
"balance_credits": 523.33,
"balance_sats": 52333
}
| Το καθεστώς | Πότε |
|---|---|
400 | Το αναγνωριστικό δεν είναι το αναγνωριστικό 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);
ΘΕΛΕΙ ΙΣΤΟΡΙΑ
Μια γραμμή ανά αίτημα: τι ήταν, ποιο μοντέλο, πόσα tokens και τι κοστίζει. Δεν διατηρούνται ειδοποιήσεις ή απαντήσεις, οπότε δεν επιστρέφονται. Οι γραμμές διατηρούνται για 90 ημέρες, το νεότερο πρώτα. Ένα κλειδί που έχει φτάσει στο κατώφλι του μπορεί ακόμα να διαβάσει το ιστορικό του.
GET https://nymbot.ai/api/v1/queries/history - χρειάζεται ένα κλειδί API, το οποίο βλέπει τα δικά του αιτήματα, ή ένα Υπογράφηκε αίτηση από το νύχι σου, που βλέπει κάθε κλειδί.
| Το πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
page | Ολόκληρο το αίτημα (query) | Όχι | Προεπιλεγμένη 1, με μέγιστο 1.000, μια υψηλότερη σελίδα είναι 400 invalid_value. |
page_count | Ολόκληρο το αίτημα (query) | Όχι | Πλατφόρμες ανά σελίδα. Προεπιλεγμένο 20, με μέγιστο 100. |
start_dateend_date | Ετικέτα (query) | Όχι | ISO 8601 ημερομηνίες ή ώρες. |
model | Ετικέτα (query) | Όχι | Μόνο αυτό το μοντέλο. |
type | Ετικέτα (query) | Όχι | chat, responses, messages, image, video, speech, transcription ή embedding. |
all_keys | Βούλγαρος (ερωτηθείς | Όχι | Με ένα κλειδί: true περιλαμβάνει κάθε κλειδί του ίδιου nym. false. |
key_id | Ετικέτα (query) | Όχι | Με υπογεγραμμένη αίτηση, ή με all_keys=trueΜόνο αυτό το κλειδί. |
Απάντηση
{
"data": [
{
"id": "q_71c4e9a0",
"timestamp": "2026-09-30T08:12:00Z",
"model": "anthropic/claude-sonnet-5",
"type": "chat",
"input_tokens": 1240,
"output_tokens": 380,
"cached_tokens": 0,
"cost_sats": 16.2,
"cost_usd": 0.01895,
"balance": "pro",
"key_id": "4f0c9a1be27d3856",
"web_search": false,
"status": "ok"
}
],
"pagination": { "page": 1, "page_count": 20, "total": 311, "total_pages": 16 }
}
cURL
curl "https://nymbot.ai/api/v1/queries/history?page_count=50&type=chat" \
-H "Authorization: Bearer $NYMBOT_API_KEY"
Python
import os
import requests
res = requests.get(
"https://nymbot.ai/api/v1/queries/history",
headers={"Authorization": "Bearer " + os.environ["NYMBOT_API_KEY"]},
params={"page_count": 50, "type": "chat"},
)
for row in res.json()["data"]:
print(row["timestamp"], row["model"], row["cost_sats"])
JavaScript
const res = await fetch("https://nymbot.ai/api/v1/queries/history?page_count=50&type=chat", {
headers: { "Authorization": "Bearer " + process.env.NYMBOT_API_KEY },
});
for (const row of (await res.json()).data) console.log(row.timestamp, row.model, row.cost_sats);
Υπογραφή αιτήσεων λογαριασμού
Η δημιουργία, η αλλαγή και η ανάκληση κλειδιών, η περίληψη του λογαριασμού και οι αυτόματες κορυφές δεν λαμβάνουν ένα κλειδί API. Λαμβάνουν μια υπογραφή από το nym σας, έτσι ώστε ένα κλειδί που έχει διαρρεύσει να μπορεί να δαπανήσει μέχρι το καπάκι του, αλλά δεν μπορεί ποτέ να κάνει άλλο κλειδί ή να αυξήσει το δικό του καπάκι.
Η εφαρμογή το κάνει αυτό για εσάς: τα πάντα μέσα της Φωτιά Το φύλλο χρησιμοποιεί αυτά τα τερματικά σημεία. Χρειάζεστε μόνο αυτή την ενότητα για να διαχειριστείτε τα κλειδιά από τον δικό σας κώδικα.
Η υπογραφή είναι ένα συμβάν 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 του σώματος του ακατέργαστου αιτήματος, σε hex.POSTκαιPATCH, και το σώμα που στέλνετε πρέπει να είναι byte για byte αυτό που hashed.created_atπρέπει να είναι εντός 60 δευτερολέπτων από το ρολόι του διακομιστή.- Κάθε εκδήλωση λειτουργεί μία φορά, α
GETσυμπεριλαμβάνεται, έτσι ώστε να μην μπορεί να αναπαραχθεί μια καταγεγραμμένη κεφαλίδα. Υπογράψτε μια νέα για κάθε αίτηση.nonceετικέτα με μια τυχαία τιμή, έτσι ώστε δύο αιτήματα που υπογράφονται στο ίδιο δευτερόλεπτο εξακολουθούν να διαφέρουν. - Το σώμα ενός υπογεγραμμένου αιτήματος μπορεί να είναι έως 64 KB, και ένα σώμα χρειάζεται
Content-Type: application/json.
Ένα χαμένο γεγονός επιστρέφει 401 missing_nostr_authένα που είναι κακώς σχηματισμένο, κακώς υπογεγραμμένο, πολύ παλιό ή για διαφορετική διεύθυνση URL, μέθοδο ή σώμα επιστρέφει
invalid_nostr_auth, με το λόγο στο μήνυμα, ένα επαναχρησιμοποιημένο ένα επιστρέφει
nostr_auth_replayedΈνα κλειδί API που αποστέλλεται σε αυτά τα τερματικά σημεία απορρίπτεται.Η υπογραφή ελέγχεται πριν από την ανάγνωση του σώματος και κάθε διεύθυνση μπορεί να αποτύχει 30 φορές το λεπτό (μια διεύθυνση IPv6 μετράει ως ολόκληρη /64)? 429 Με
Retry-After.
Τα προγράμματα περιήγησης μπορούν να καλέσουν αυτά τα τερματικά σημεία μόνο από τους δικούς τους ιστότοπους του Nymbot (https://nymbot.ai,
https://nymchat.app Μια σελίδα σε οποιοδήποτε άλλο site δεν παίρνει πίσω κεφαλίδες CORS, οπότε δεν μπορεί να διαβάσει αυτό που επιστρέφουν.
OriginΚαι δεν επηρεάζονται.
Η υπογραφή χρειάζεται το μυστικό κλειδί του nym σας (το nsecΤο οποίο ελέγχει τα πάντα: την ταυτότητά σας, το ιστορικό σας και το ισοζύγιο σας. Απλά βάλτε το σε ένα σενάριο σε μια μηχανή που εμπιστεύεστε, διαβάστε το από το περιβάλλον αντί να το γράψετε στο αρχείο και προτιμήστε την εφαρμογή όταν μπορείτε.
Αυτοί οι βοηθοί δημιουργούν την κεφαλίδα. Τα μεταγενέστερα παραδείγματα σε αυτή τη σελίδα τα χρησιμοποιούν. Διαβάζουν το μυστικό κλειδί σε hex από NOSTR_SECRET_HEXΤο CURL ένα χρησιμοποιεί το
Νίκος εργαλείο γραμμής εντολών, το οποίο λαμβάνει ένα κλειδί 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 Χρειάζεται α Υπογράφηκε αίτηση.
Απάντηση
{
"data": {
"pubkey": "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d",
"balances": {
"standard": { "credits": 120.4, "sats": 1204 },
"pro": { "credits": 408.33, "sats": 40833 }
},
"keys_active": 3,
"nwc_auto_topup": {
"connected": true, "threshold_sats": 5000, "topup_sats": 20000, "tier": "pro",
"last_topup_at": null, "last_topup_sats": null, "last_error": null
}
}
}
cURL
URL=https://nymbot.ai/api/v1/account
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/account"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json())
JavaScript
const url = "https://nymbot.ai/api/v1/account";
const res = await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } });
console.log(await res.json());
Διαχείριση κλειδιών
Τα τερματικά σημεία πίσω από τη λίστα κλειδιών της εφαρμογής. όλα χρειάζονται ένα Υπογράφηκε αίτησηΚάθε κλειδί επιστρέφεται σε αυτή τη φόρμα, με χρόνους στο ISO 8601 και ποσά σε sats:
Κλειδί αντικείμενο
{
"id": "4f0c9a1be27d3856",
"name": "laptop scripts",
"hint": "sk-nymbot-Qm7x…c2Lw",
"limit_sats": 20000,
"reset_period": "monthly",
"reset_at": "2026-10-01T00:00:00Z",
"expire_at": null,
"period_used_sats": 3412,
"total_used_sats": 18230,
"created_at": "2026-08-14T09:21:07Z",
"updated_at": "2026-09-02T17:40:55Z",
"last_used_at": "2026-09-30T08:12:00Z",
"revoked_at": null
}
hint Είναι αρκετό για να αναγνωρίσετε ένα κλειδί, αλλά όχι για να το χρησιμοποιήσετε.Το ίδιο το κλειδί επιστρέφεται μόνο μία φορά, όταν δημιουργείται.
Λίστα κλειδιών
GET https://nymbot.ai/api/v1/keys και υπογράφηκε.
| Το πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
include_revoked | Βούλγαρος (ερωτηθείς | Όχι | Περιλαμβάνει ανακληθέντα κλειδιά. προεπιλογή false. |
Απάντηση
{ "data": [ { "id": "4f0c9a1be27d3856", "name": "laptop scripts", "hint": "sk-nymbot-Qm7x…c2Lw", "...": "..." } ] }
cURL
URL=https://nymbot.ai/api/v1/keys
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/keys"
for key in requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json()["data"]:
print(key["id"], key["name"], key["period_used_sats"], key["limit_sats"])
JavaScript
const url = "https://nymbot.ai/api/v1/keys";
const { data } = await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json();
for (const key of data) console.log(key.id, key.name, key.period_used_sats, key.limit_sats);
Κάντε ένα κλειδί
POST https://nymbot.ai/api/v1/keys ΕΠΙΣΤΡΟΦΗ - ΕΠΙΣΤΡΟΦΗ 201.
| Το πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
name | Στρογγυλο | Ναί | 1 έως 40 χαρακτήρες, διαφορετικοί από τα άλλα ενεργά κλειδιά σας (παραμέληση περιπτώσεων). |
limit_sats | ΙΝΤΕΡ | Όχι | Το κεφάλαιο δαπανών στο sats, τουλάχιστον 1. |
reset_period | Στρογγυλο | Όχι | daily, weekly ή monthlyανάγκες limit_satsΑφήστε το για ένα καπάκι που δεν επαναφέρεται ποτέ. |
expire_at | Σύνδεσμος ή 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)· ένα καπάκι που δεν είναι ένας ολόκληρος αριθμός τουλάχιστον 1· μια περίοδο επαναφοράς χωρίς καπάκι· μια λήξη στο παρελθόν· ένα άγνωστο πεδίο (unknown_parameter) · ή 25 ενεργά κλειδιά ήδη (too_many_keys). |
429 | Περισσότερα από 60 κλειδιά που δημιουργήθηκαν από αυτό το νύχι, ή 120 από αυτή τη διεύθυνση, σε μία ώρα (rate_limit_exceeded, με Retry-After). |
cURL
URL=https://nymbot.ai/api/v1/keys
BODY='{"name":"laptop scripts","limit_sats":20000,"reset_period":"monthly"}'
curl "$URL" \
-H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
-H "Content-Type: application/json" \
-d "$BODY"
Python
import json
import requests
url = "https://nymbot.ai/api/v1/keys"
body = json.dumps({"name": "laptop scripts", "limit_sats": 20000, "reset_period": "monthly"}).encode()
res = requests.post(
url,
data=body,
headers={"Authorization": nostr_auth("POST", url, body), "Content-Type": "application/json"},
)
print(res.json()["data"]["key"])
JavaScript
const url = "https://nymbot.ai/api/v1/keys";
const body = JSON.stringify({ name: "laptop scripts", limit_sats: 20000, reset_period: "monthly" });
const res = await fetch(url, {
method: "POST",
headers: { "Authorization": nostrAuth("POST", url, body), "Content-Type": "application/json" },
body,
});
console.log((await res.json()).data.key);
Διαβάστε ένα κλειδί
GET https://nymbot.ai/api/v1/keys/{id} και υπογράφηκε.
Επιστροφή {"data": {…}} με το βασικό αντικείμενο, ή 404
key_not_found αν κανένα από τα κλειδιά σας δεν έχει αυτό το αναγνωριστικό
cURL
URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json()["data"])
JavaScript
const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
console.log((await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json()).data);
Αλλαγή κλειδιού
PATCH https://nymbot.ai/api/v1/keys/{id} και υπογράφηκε.
Στείλτε οποιοδήποτε name, limit_sats, reset_period και
expire_at, με τους ίδιους κανόνες όπως όταν κάνετε ένα κλειδί. null Καθαρίζει ένα πεδίο: χωρίς καπάκι, χωρίς επαναφορά, χωρίς λήξη. Η αλλαγή της περιόδου επαναφοράς ξεκινά μια νέα περίοδο από το μηδέν.400 key_revoked) Επιστροφή
{"data": {…}} με το ενημερωμένο αντικείμενο κλειδιού.
cURL
URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
BODY='{"limit_sats":50000,"expire_at":null}'
curl -X PATCH "$URL" \
-H "Authorization: $(nostr_auth PATCH "$URL" "$BODY")" \
-H "Content-Type: application/json" \
-d "$BODY"
Python
import json
import requests
url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
body = json.dumps({"limit_sats": 50000, "expire_at": None}).encode()
res = requests.patch(
url,
data=body,
headers={"Authorization": nostr_auth("PATCH", url, body), "Content-Type": "application/json"},
)
print(res.json()["data"])
JavaScript
const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
const body = JSON.stringify({ limit_sats: 50000, expire_at: null });
const res = await fetch(url, {
method: "PATCH",
headers: { "Authorization": nostrAuth("PATCH", url, body), "Content-Type": "application/json" },
body,
});
console.log((await res.json()).data);
Ακύρωση κλειδιού
DELETE https://nymbot.ai/api/v1/keys/{id} και υπογράφηκε.
Σταματάει το κλειδί αμέσως, για καλό. παραμένει στη λίστα με revoked_at Εμφανίζεται και μπορεί να δει με include_revoked=trueΗ ανάκληση ενός κλειδιού που έχει ήδη ανακληθεί απαντά με τον ίδιο τρόπο. μόνο τα τελευταία 50 ανακληθέντα κλειδιά διατηρούνται. τα παλαιότερα διαγράφονται όταν ανακληθεί ένα άλλο κλειδί.
Απάντηση
{ "data": { "id": "4f0c9a1be27d3856", "revoked": true } }
cURL
URL=https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856
curl -X DELETE "$URL" -H "Authorization: $(nostr_auth DELETE "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856"
print(requests.delete(url, headers={"Authorization": nostr_auth("DELETE", url)}).json())
JavaScript
const url = "https://nymbot.ai/api/v1/keys/4f0c9a1be27d3856";
const res = await fetch(url, { method: "DELETE", headers: { "Authorization": nostrAuth("DELETE", url) } });
console.log(await res.json());
Ετικέτες NWC Auto-top-up
Συνδέστε ένα πορτοφόλι Lightning με το Nostr Wallet Connect και το Nymbot ανυψώνει το υπόλοιπο από μόνο του όταν οι δαπάνες API το εκτελούν χαμηλά. το φύλλο API της εφαρμογής έχει τις ίδιες ρυθμίσεις. Υπογράφηκε αίτηση.
Πώς λειτουργεί: Μετά από μια αίτηση API χρεώνεται στο υπόλοιπο που επιλέξατε να παρακολουθήσετε, αν το υπόλοιπο έχει πέσει κάτω από το κατώφλι σας, το Nymbot εκδίδει τιμολόγιο για το ανώτατο ποσό σας, ζητά από το πορτοφόλι σας να το πληρώσει και προσθέτει την πίστωση. Ανυψώνεται το πολύ μία φορά κάθε 5 λεπτά για κάθε nym και ισοζύγιο, έτσι μια έκρηξη αιτημάτων δεν μπορεί να αποστραγγίσει το πορτοφόλι. Η δαπάνη στις εφαρμογές δεν το ενεργοποιεί. Ο χρόνος και το μέγεθος της τελευταίας επάνω, και το τελευταίο σφάλμα, είναι στις ρυθμίσεις. αν μια πληρωμή πέρασε μετά από ένα σφάλμα, ελέγξτε το τιμολόγιο Το top-up της κατάστασης Πιστεύω σε αυτό.
Μια αλυσίδα σύνδεσης επιτρέπει σε όποιον το κατέχει να ζητήσει από το πορτοφόλι σας να πληρώσει.Το Nymbot το αποθηκεύει κρυπτογραφημένο και το χρησιμοποιεί μόνο για να πληρώσει τα δικά του τιμολόγια, αλλά κάνει μια σύνδεση μόνο γι 'αυτό, με έναν προϋπολογισμό δαπανών στο πορτοφόλι σας, έτσι ώστε το περισσότερο που θα μπορούσε ποτέ να πληρώσει είναι ένας αριθμός που επιλέξατε. pay_invoice.
Συνδέοντας ένα πορτοφόλι
POST https://nymbot.ai/api/v1/nwc-auto-topup/connect και υπογράφηκε.
| Το πεδίο | Τύπος | Απαιτείται | Περιγραφή |
|---|---|---|---|
nwc_url | Στρογγυλο | Ναί | Η γραμμή σύνδεσης, ξεκινώντας nostr+walletconnect://Το Nymbot ζητά το πορτοφόλι για get_info πριν από την αποθήκευση και αποθηκεύει κρυπτογραφημένα. |
threshold_sats | ΙΝΤΕΡ | Ναί | Πιο πάνω όταν το υπόλοιπο πέσει κάτω από αυτά τα πολλά sats. |
topup_sats | ΙΝΤΕΡ | Ναί | Πόσο να προσθέσετε κάθε φορά. 1.000 έως 1.000.000 sats. |
tier | Στρογγυλο | Όχι | pro (η αποτυχία) ή standardΗ ισορροπία να παρακολουθεί και να ανεβαίνει. |
Απάντηση
{
"data": {
"connected": true,
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
"last_topup_at": null,
"last_topup_sats": null,
"last_error": null
}
}
| Το καθεστώς | Πότε |
|---|---|
400 | Δεν υπάρχει σύνδεση σύνδεσης (invalid_nwc_url(το πορτοφόλι δεν απάντησε για την αναμετάδοσή του)nwc_unreachable) ή αρνήθηκε τον έλεγχο (nwc_rejected(η σύνδεση δεν μπορεί να πληρώσει τους λογαριασμούς)nwc_missing_permission) ή ένα ποσό πέρα από τα όρια. |
501 | Οι αυτόματες κορυφές δεν είναι ενεργοποιημένες για αυτόν τον διακομιστή (nwc_unavailableΤο ίδιο ισχύει και για τα άλλα δύο τέλη. |
cURL
URL=https://nymbot.ai/api/v1/nwc-auto-topup/connect
BODY='{"nwc_url":"nostr+walletconnect://...","threshold_sats":5000,"topup_sats":20000,"tier":"pro"}'
curl "$URL" \
-H "Authorization: $(nostr_auth POST "$URL" "$BODY")" \
-H "Content-Type: application/json" \
-d "$BODY"
Python
import json, os
import requests
url = "https://nymbot.ai/api/v1/nwc-auto-topup/connect"
body = json.dumps({
"nwc_url": os.environ["NWC_URL"],
"threshold_sats": 5000,
"topup_sats": 20000,
"tier": "pro",
}).encode()
res = requests.post(
url,
data=body,
headers={"Authorization": nostr_auth("POST", url, body), "Content-Type": "application/json"},
)
print(res.json())
JavaScript
const url = "https://nymbot.ai/api/v1/nwc-auto-topup/connect";
const body = JSON.stringify({
nwc_url: process.env.NWC_URL,
threshold_sats: 5000,
topup_sats: 20000,
tier: "pro",
});
const res = await fetch(url, {
method: "POST",
headers: { "Authorization": nostrAuth("POST", url, body), "Content-Type": "application/json" },
body,
});
console.log(await res.json());
Διαβάστε τις ρυθμίσεις
GET https://nymbot.ai/api/v1/nwc-auto-topup και υπογράφηκε.
Επιστρέφει το ίδιο αντικείμενο με τη σύνδεση, με connected: false Και τα υπόλοιπα πεδία
null Όταν δεν υπάρχει συνδεδεμένο πορτοφόλι, η ίδια η σειρά σύνδεσης δεν επιστρέφεται ποτέ.
cURL
URL=https://nymbot.ai/api/v1/nwc-auto-topup
curl "$URL" -H "Authorization: $(nostr_auth GET "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/nwc-auto-topup"
print(requests.get(url, headers={"Authorization": nostr_auth("GET", url)}).json())
JavaScript
const url = "https://nymbot.ai/api/v1/nwc-auto-topup";
console.log(await (await fetch(url, { headers: { "Authorization": nostrAuth("GET", url) } })).json());
Αποσύνδεση
DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection και υπογράφηκε.
Διαγράφει τη γραμμή σύνδεσης που έχει αποθηκευτεί. Δεν δημιουργούνται περισσότερες υπερ-επισκευές. Για να είστε σίγουροι, μπορείτε επίσης να ανακαλέσετε τη σύνδεση στο πορτοφόλι σας.
Απάντηση
{ "data": { "connected": false, "threshold_sats": null, "topup_sats": null, "tier": null, "last_topup_at": null, "last_topup_sats": null, "last_error": null } }
cURL
URL=https://nymbot.ai/api/v1/nwc-auto-topup/connection
curl -X DELETE "$URL" -H "Authorization: $(nostr_auth DELETE "$URL")"
Python
import requests
url = "https://nymbot.ai/api/v1/nwc-auto-topup/connection"
print(requests.delete(url, headers={"Authorization": nostr_auth("DELETE", url)}).json())
JavaScript
const url = "https://nymbot.ai/api/v1/nwc-auto-topup/connection";
const res = await fetch(url, { method: "DELETE", headers: { "Authorization": nostrAuth("DELETE", url) } });
console.log(await res.json());
Πληρωμή χωρίς κλειδί
Τα τερματικά σημεία σταθερής τιμής μπορούν να καταβληθούν για ένα αίτημα τη φορά πάνω από το Lightning, χωρίς κλειδί, χωρίς λογαριασμό και χωρίς υπόλοιπο: POST /images/generations, POST /images/edits,
POST /videos, POST /audio/speech, POST /audio/transcriptions,
POST /audio/translations και POST /embeddingsΜια αίτηση που φέρει ένα κλειδί χρεώνεται στο υπόλοιπο όπως συνήθως. η ροή πληρωμών ξεκινά μόνο όταν δεν αποστέλλεται κανένα κλειδί.
Nymbot μιλάει δύο εκδοχές της ίδιας ιδέας, από ένα 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 ένα Pro πιστωτικό και στρογγυλοποιείται σε ένα ολόκληρο sat (τουλάχιστον 1 sat, και τουλάχιστον το 0.05 πιστωτικό ελάχιστο). WWW-Authenticate Προκλήσεις για τον ίδιο λογαριασμό:
HTTP/1.1 402 Payment Required
Content-Type: application/problem+json; charset=utf-8
Cache-Control: no-store
WWW-Authenticate: L402 macaroon="AgJC...", invoice="lnbc2370n1..."
WWW-Authenticate: LSAT macaroon="AgJC...", invoice="lnbc2370n1..."
WWW-Authenticate: Payment id="kM9x...", realm="nymbot", method="lightning", intent="charge",
request="eyJhbW91bnQiOiIyMzciLC...", description="Nymbot API POST /images/generations (237 sats)",
digest="sha-256=:X48E9qOokqqrvdts8nOJRJN3OWDUoyWxBf7kbu9DBPE=:", expires="2026-09-30T12:15:00.000Z",
opaque="eyJlbmRwb2ludCI6IlBPU1QgL2ltYWdlcy9nZW5lcmF0aW9ucyJ9"
{
"type": "https://paymentauth.org/problems/payment-required",
"title": "Payment Required",
"status": 402,
"detail": "This request costs 237 sats. Pay the Lightning invoice, then send the identical request again ...",
"challengeId": "kM9x...",
"amount_sats": 237,
"invoice": "lnbc2370n1...",
"payment_hash": "9db1370f...",
"expires_at": "2026-09-30T12:15:00.000Z",
"error": { "message": "This request costs 237 sats. ...", "type": "payment_required", "code": "payment_required", "param": null }
}
Η πληρωμή request Η παράμετρος είναι base64url JSON:
{"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.
Μια πρόκληση συνδέεται με το τελικό σημείο, με την Content-Type (τον τύπο του μέσου και, για πολλαπλά τμήματα, το όριο του) και στο SHA-256 του ακριβούς σώματος bytes που έχετε στείλει, και διαρκεί 15 λεπτά. ΙΔΙΟΤΗΤΑ Για άλλη μια φορά: το ίδιο
Content-Type και τα ίδια bytes JSON, ή για τα πολλαπλά τερματικά σημεία (/images/edits, /audio/transcriptions, /audio/translationsΟι περισσότερες βιβλιοθήκες HTTP επιλέγουν ένα νέο όριο κάθε φορά που κωδικοποιούν μια φόρμα, οπότε κωδικοποιήστε το μία φορά και στείλτε αυτά τα bytes δύο φορές.
Κάθε διεύθυνση μπορεί να ζητήσει 30 προκλήσεις ανά λεπτό (μια διεύθυνση IPv6 μετράει ως ολόκληρη /64). Αιτήσεις των οποίων η διεύθυνση δεν είναι γνωστή μοιράζονται ένα αυστηρότερο 10 ανά λεπτό, και υπάρχει ένα συνολικό όριο για τα προβλήματα Nymbot προκλήσεις σε όλες τις διευθύνσεις. ένα αίτημα που απορρίφθηκε πριν γίνει μια πρόκληση (για παράδειγμα με ένα σώμα που δεν είναι έγκυρο JSON) δεν μετράει προς αυτήν. 429 Με Retry-AfterΤα πληρωμένα τερματικά σημεία που καλούνται χωρίς κλειδί ή διαπιστευτήρια μετρούν επίσης προς το γενικό όριο των 120 μη επαληθευμένων αιτημάτων ανά λεπτό ανά διεύθυνση. Content-Type Δεν είναι application/json (ή
multipart/form-data για ανεβάσεις) απορρίπτεται με 415 Ποτέ δεν παίρνει λογαριασμό.
Οι ενσωματώσεις τιμολογούνται από μια εκτίμηση των tokens στην είσοδο, με περιθώριο 1,5 φορές, καθώς ο πραγματικός αριθμός είναι γνωστός μόνο μετά. ΕΠΙΣΤΡΟΦΗ ΤΟΚΕΝ.
Στείλτε την πληρωμή
Πληρώστε το λογαριασμό με οποιοδήποτε πορτοφόλι Lightning. Το πορτοφόλι σας δίνει την προεικόνα, 64 hex χαρακτήρες. Στη συνέχεια στείλτε το ίδιο αίτημα με ένα από αυτά:
| ΣΧΕΔΙΑ | Κεφαλονιά |
|---|---|
| Α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 με το id πρόκλησης, το hash πληρωμής ως reference, status και
timestampΤα πληρωμένα αιτήματα δεν συνδέονται με κανένα nym, επομένως δεν εμφανίζονται στο ιστορικό ερωτήματος.
| Το καθεστώς | Πότε |
|---|---|
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 ή ονομάζει ένα hash πληρωμής για το οποίο το Nymbot δεν έχει εκδώσει ποτέ τιμολόγιο. |
429 rate_limit_exceeded | Περισσότερα από 30 διαπιστευτήρια ή κλειδιά που απέτυχαν να επαληθευτούν ήρθαν από αυτή τη διεύθυνση σε ένα λεπτό, ή ένα token επιστροφής αποστέλλεται περισσότερες από 60 φορές σε ένα λεπτό. Retry-After. |
cURL
BODY='{"model":"nano-banana","prompt":"a lighthouse at dusk","response_format":"b64_json"}'
URL=https://nymbot.ai/api/v1/images/generations
# 1. Get the challenge
CH=$(curl -s -D - -o /dev/null "$URL" -H "Content-Type: application/json" -d "$BODY" | grep -i '^www-authenticate: L402')
MAC=$(echo "$CH" | sed -E 's/.*macaroon="([^"]+)".*/\1/')
INVOICE=$(echo "$CH" | sed -E 's/.*invoice="([^"]+)".*/\1/')
# 2. Pay $INVOICE with your wallet and copy the preimage
PREIMAGE=...
# 3. Send the identical request with the credential
curl "$URL" -H "Content-Type: application/json" -H "Authorization: L402 $MAC:$PREIMAGE" -d "$BODY"
lnget
# lnget (Lightning Labs) pays L402 challenges from your own lnd node and retries for you
lnget -X POST -H "Content-Type: application/json" \
-d '{"model":"nano-banana","prompt":"a lighthouse at dusk","response_format":"b64_json"}' \
https://nymbot.ai/api/v1/images/generations
Python
import base64, json, re
import requests
url = "https://nymbot.ai/api/v1/images/generations"
body = json.dumps({"model": "nano-banana", "prompt": "a lighthouse at dusk", "response_format": "b64_json"}).encode()
headers = {"Content-Type": "application/json"}
challenge = requests.post(url, data=body, headers=headers)
assert challenge.status_code == 402
info = challenge.json()
print("Pay", info["amount_sats"], "sats:", info["invoice"])
preimage = pay_with_your_wallet(info["invoice"]) # 64 hex characters
# L402
mac = re.search(r'L402 macaroon="([^"]+)"', challenge.headers["WWW-Authenticate"]).group(1)
res = requests.post(url, data=body, headers={**headers, "Authorization": f"L402 {mac}:{preimage}"})
print(res.json()["nymbot"])
JavaScript
const url = "https://nymbot.ai/api/v1/images/generations";
const body = JSON.stringify({ model: "nano-banana", prompt: "a lighthouse at dusk", response_format: "b64_json" });
const headers = { "Content-Type": "application/json" };
const challenge = await fetch(url, { method: "POST", headers, body });
const www = challenge.headers.get("www-authenticate");
// The Payment scheme: echo every challenge parameter back with the preimage
const start = www.indexOf("Payment ");
const params = Object.fromEntries([...www.slice(start + 8).matchAll(/(\w+)="((?:[^"\\]|\\.)*)"/g)].map((m) => [m[1], m[2]]));
const { invoice } = JSON.parse(Buffer.from(params.request, "base64url").toString()).methodDetails;
const preimage = await payWithYourWallet(invoice);
const credential = Buffer.from(JSON.stringify({ challenge: params, payload: { preimage } })).toString("base64url");
const res = await fetch(url, { method: "POST", headers: { ...headers, Authorization: `Payment ${credential}` }, body });
console.log((await res.json()).nymbot, res.headers.get("payment-receipt"));
Οι πελάτες που χτίστηκαν mppx Με τη μέθοδο Lightning χειρίζονται οι ίδιοι την πρόκληση πληρωμής, τους δείχνουν στο σημείο τερματισμού και τους αφήνουν να πληρώσουν.
ΒΙΝΤΕΟ
Η πληρωμένη POST /videos απαντήσεις 202 σαν ένα κλειστό ένα, συν ένα
status_url: GET Είναι υπογεγραμμένο και λειτουργεί για 24 ώρες, εφόσον διατηρείται η εργασία.
{
"id": "vid_...",
"status": "in_progress",
"status_url": "https://nymbot.ai/api/v1/videos/vid_...?exp=1790000000&sig=...",
"nymbot": {
"payment": "l402", "tier": "pro", "paid_sats": 4800, "charged_sats": 4800,
"refund_token": "REFUND-5E0B..."
}
}
Κρατήστε το refund_token από αυτή την απάντηση: εμφανίζεται μόνο εδώ. Είναι κενό ενώ το βίντεοGET /api/v1/l402/refunds απαντήσεις "status": "pending"); αν η αναπαραγωγή αποτύχει χωρίς χρέωση, η πληρωμή προσγειώνεται σε αυτήν.
refund_sats για μια επιστρεφόμενη εργασία, αλλά ποτέ το 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 το αντικείμενο φέρει ένα token επιστροφής χρημάτων για το λείπουν? μια μεταγραφή του οποίου το μήκος δεν θα μπορούσε να διαβαστεί εκ των προτέρων τιμολογείται για όσο περισσότερο το αρχείο θα μπορούσε να είναι (ποτέ περισσότερο από 30 λεπτά), και η διαφορά στο πραγματικό μήκος επιστρέφει ως token επιστροφής χρημάτων? αν αποδειχθεί ότι είναι μεγαλύτερη από 30 λεπτά, απορρίπτεται με 413
Και η πλήρης πληρωμή επιστρέφει.Οι ενσωματώσεις επιστρέφουν ό, τι η εκτίμηση κράτησε πίσω.Ένα αποτυχημένο βίντεο επιστρέφει το token της υποβολής του.
Ένα token επιστροφής χρημάτων είναι ένας τυχαίος 256-bit κώδικας. Το Nymbot αποθηκεύει μόνο το hash του και λήγει μετά από 30 ημέρες.
- Πληρώστε με αυτό. Στείλτε
Authorization: Bearer REFUND-…Σε οποιοδήποτε από τα ανωτέρω σημεία τερματισμού (ένα OpenAI SDK το παίρνει ως κλειδί API).refund_token_satsΣτηνnymbotΈνα token που αξίζει λιγότερο από τις απαντήσεις στο αίτημα402refund_insufficientΜια αποτυχία χωρίς χρέωση τοποθετεί το sats πίσω στο ίδιο token. - Να το ελέγξεις.
GET /api/v1/l402/refundsΤο ίδιο κεφάλαιο επιστρέφει{"sats": 237, "status": "open", "expires_at": "..."}. - Ένα token μπορεί να χρησιμοποιηθεί έως και 60 φορές το λεπτό.
- Μετακινήστε το σε ένα nym. Βάλτε το σε Αποκτήστε ένα δώρο στην εφαρμογή Nymbot, ή καλέστε
POST /api/v1/l402/refunds/redeemΜε α Υπογράφηκε αίτηση και{"refund_token": "REFUND-...", "balance": "standard"}(ή"pro"Όλες οι πιστώσεις πηγαίνουν στο υπόλοιπο (10 πονταρίσματα το καθένα στο πρότυπο, 100 στο Pro)? πονταρίσματα που δεν κάνουν μια ολόκληρη πίστωση παραμονή στο token για αιτήματα 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 } }