Μετάβαση στο περιεχόμενο
Επιστροφή στο Nymbot

Βάση γνώσεων Οι προγραμματιστές

Ισορροπία, κορυφές και κλειδιά

Ελέγξτε τι έχετε, ανεβάστε το 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_date
end_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 Χρησιμοποιήστε ό,τι καταλαβαίνει ο πελάτης σας.

Ξεκινήστε το δικό σας server

Η πληρωμή χωρίς κλειδί είναι ενεργοποιημένη μόνο όταν 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 χαρακτήρες. Στη συνέχεια στείλτε το ίδιο αίτημα με ένα από αυτά:

ΣΧΕΔΙΑΚεφαλονιά
Α402Authorization: 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 που αξίζει λιγότερο από τις απαντήσεις στο αίτημα 402 refund_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 } }