Springe zum Inhalt
Zurück zu Nymbot

Wissensdatenbank Entwickler

Balance, Top-ups und Schlüssel

Überprüfen Sie, was Sie haben, überprüfen Sie Lightning, überprüfen Sie automatisch aus Ihrer eigenen Brieftasche, sehen Sie, was jede Anfrage kostet und verwalten Sie Schlüssel aus Code.

Das Gleichgewicht überprüfen

Sowohl Ihre Balance, und wie viel von diesem Schlüssel Kappe verwendet wird.

GET https://nymbot.ai/api/v1/credits/balance Sie benötigen einen API-Schlüssel POST Es funktioniert auch für Kunden, die es erwarten.

balance ist die beiden Guthaben zusammen in Dollar zum aktuellen Bitcoin-Preis, für Tools, die eine einzige Zahl erwarten (null Der Rest ist in Credits und Sats, das ist, wie die Salden tatsächlich gehalten werden. key beschreibt den Schlüssel, der gefragt wurde.Ein Schlüssel, der seine Kappe erreicht hat, kann immer noch das Gleichgewicht überprüfen.

Reaktionen

{
  "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"
  }
}
StatusWann
401Der Schlüssel ist fehlend, unbekannt, widerrufen oder abgelaufen.

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

Zahlungsmethoden

Wie kann man aufsteigen, und die Grenzen. Lightning ist die einzige Methode.

GET https://nymbot.ai/api/v1/topup/payment-methods Kein Schlüssel benötigt.

Ein Top-up ist 10 bis 1.000.000 Sätze; ein Pro-Top-up muss mindestens ein Pro-Kredit kaufen, so dass es bei 100 Sätze beginnt. bulk_bonus die zusätzliche Gutschrift auf größeren Top-ups, die gleiche wie in der app: 10%, 15% oder 20% mehr auf Standard-Top-ups von 500, 1.000 oder 5.000 Sätzen, und auf Pro-Top-ups von 5.000, 10.000 oder 50.000 Sätzen.

Reaktionen

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

Aufstieg über Lightning

Erstellt eine Lightning-Rechnung, die dem Nym, dem der Schlüssel gehört, Kredit hinzufügt. Überprüfen Sie es Um den Kredit hinzuzufügen.

POST https://nymbot.ai/api/v1/topup/create/btc-lightning Sie benötigen einen API-Schlüssel

FeldTyperforderlichBeschreibung
amountAnzahlJaWie viel, in currencyEine ganze Zahl für Satz.
currencyStringNeinSATS (Das ist ein Default) USD oder BTCDollars werden zum aktuellen Bitcoin-Preis umgewandelt.
tierStringNeinpro (die Verzögerung) oder standard: zu welchem Gleichgewicht der Kredit geht.

Ein Standardkredit beträgt 10 Sätze und ein Pro-Kredit 100 Sätze, plus jeder Bonus; credits sagt, was diese Rechnung hinzufügen wird.

Reaktionen

{
  "invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
  "payment_request": "lnbc100u1p5...",
  "amount_sats": 10000,
  "credits": 115,
  "tier": "pro",
  "expires_at": "2026-09-30T09:27:00Z",
  "status": "pending"
}
StatusWann
400Eine andere Methode auf dem Weg (unsupported_method, eine unbekannte Währung (unsupported_currency) oder tier, einen fehlenden Betrag oder einen Betrag unter dem Mindestbetrag (amount_too_small) über 1 000 000 Sätze (amount_too_large) oder von der Lightning-Wallet abgelehnt (amount_out_of_range).
429Mehr als 60 Rechnungen für diese nym, oder 120 von dieser Adresse, in einer Stunde (rate_limit_exceeded, mit Retry-After).
502Derzeit konnte keine Rechnung abgegeben werden (invoice_unavailable, mit 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);

Überprüfen eines Top-ups

Fragt, ob die Rechnung bezahlt wurde und, sobald es ist, fügt den Kredit hinzu. Überprüfung ist, was es kreditiert, also nach der Zahlung, überprüfen Sie, bis der Status ist creditedDie Überprüfung danach ist sicher: Die Kredite landen einmal, egal wie oft Sie fragen.

GET https://nymbot.ai/api/v1/topup/status/{invoice_id} - benötigt einen Schlüssel vom NIM, der die Rechnung erstellt hat.

status ist pending (noch nicht bezahlt) paid (bezahlt, aber noch nicht gutgeschrieben; noch einmal überprüfen), credited (auf Ihrer Bilanz) oder expired (nicht pünktlich bezahlt). Die Balancefelder sind für die Ebene, auf der die Rechnung ankommt.

Reaktionen

{
  "invoice_id": "b7d41e0c95a2f38e6c1d0e9a4b7f2c61d3e8a05f9b2c4d7e1a6f3b8c0d5e2a9f4",
  "status": "credited",
  "amount_sats": 10000,
  "credits": 115,
  "tier": "pro",
  "expires_at": null,
  "balance_credits": 523.33,
  "balance_sats": 52333
}
StatusWann
400Die id ist nicht die 64-Zeichen-id aus dem erstellten Anruf.
404Keine Rechnung durch diese id für deinen 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);

Wünsche Geschichte

Eine Zeile pro Anfrage: was es war, welches Modell, wie viele Token und was es kostet. Keine Anrufe oder Antworten werden beibehalten, so dass keine zurückgegeben werden. Zeilen werden für 90 Tage beibehalten, neueste zuerst. Ein Schlüssel, der seine Obergrenze erreicht hat, kann immer noch seine Geschichte lesen.

GET https://nymbot.ai/api/v1/queries/history — benötigt einen API-Schlüssel, der seine eigenen Anfragen sieht, oder Unterschriebener Antrag von deinem Nym, der jeden Schlüssel sieht.

FeldTyperforderlichBeschreibung
pageIntegrierter Query (Query)NeinStandard 1, maximal 1000; eine höhere Seite ist 400 invalid_value.
page_countIntegrierter Query (Query)NeinZeilen pro Seite. Standard 20, maximal 100.
start_date
end_date
String für QueryNeinISO 8601 Datum oder Uhrzeit.
modelString für QueryNeinNur dieses Modell.
typeString für QueryNeinchat, responses, messages, image, video, speech, transcription oder embedding.
all_keysDas Boolean (Query)NeinMit einem Schlüssel: true enthält jeden Schlüssel des gleichen nym. Default false.
key_idString für QueryNeinMit einem unterschriebenen Antrag oder mit all_keys=trueNur diesen Schlüssel.

Reaktionen

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

Kontoanfragen unterschreiben

Erstellen, ändern und widerrufen von Schlüsseln, Konto Zusammenfassung und automatische Top-ups nehmen keinen API-Schlüssel. Sie nehmen eine Signatur von Ihrem NIM, so dass ein gelöschter Schlüssel bis zu seiner Kappe verbringen kann, aber niemals einen anderen Schlüssel machen oder seine eigene Kappe erhöhen kann.

Die App tut dies für Sie: Alles in seiner Feuer Sie benötigen diesen Abschnitt nur, um Schlüssel aus Ihrem eigenen Code zu verwalten.

Die Signatur ist ein Nostr-Ereignis der Art 27235 (NIP-98), gesendet bas64-verschlüsselt in der Authorization Header mit dem Wort Nostr Auf der Front:

Die Veranstaltung

{
  "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 ist die vollständige URL der Anfrage, die Abfragezeile enthalten, genau wie gesendet.
  • method Das ist die HTTP Methode.
  • payload ist die SHA-256 des Rohanforderungskörpers, in Hex. POST Und PATCH, und der Körper, den Sie senden, muss Byte für Byte sein, den Sie hashten.
  • created_at Es muss innerhalb von 60 Sekunden der Uhr des Servers sein.
  • Jedes Ereignis funktioniert einmal, a GET enthalten ist, so dass ein erfasster Header nicht wiedergegeben werden kann. Für jede Anfrage einen neuen nonce Tag mit einem zufälligen Wert, so dass zwei Anfragen, die in der gleichen Sekunde signiert sind, immer noch unterschiedlich sind.
  • Der Körper einer unterzeichneten Anfrage kann maximal 64 KB betragen, und ein Körper benötigt Content-Type: application/json.

Eine fehlende Veranstaltung kehrt zurück 401 missing_nostr_auth; eine, die schlecht gebildet, schlecht signiert, zu alt oder für eine andere URL, Methode oder Körper zurückgibt invalid_nostr_auth, mit dem Grund in der Botschaft; ein wiederverwendeter kehrt zurück nostr_auth_replayedDie Signatur wird geprüft, bevor der Körper gelesen wird, und jede Adresse kann 30 Mal pro Minute versagen (eine IPv6-Adresse zählt als ihre ganze /64); danach erhält sie 429 mit Retry-After.

Browser können diese Endpunkte nur von den eigenen Websites von Nymbot anrufen (https://nymbot.ai, https://nymchat.app Eine Seite auf einer anderen Website erhält keine CORS-Header zurück, sodass sie nicht lesen kann, was sie zurückgeben. OriginSie sind nicht betroffen.

Dein geheimer Schlüssel

Die Unterschrift benötigt den geheimen Schlüssel Ihres Nims (der nsec), die alles kontrolliert: Ihre Identität, Ihre Geschichte und Ihr Gleichgewicht.Legen Sie es nur in ein Skript auf einer Maschine, der Sie vertrauen, lesen Sie es aus der Umgebung, anstatt es in die Datei zu schreiben, und bevorzugen Sie die App, wenn Sie können.

Diese Helfer bauen den Header auf. Die späteren Beispiele auf dieser Seite verwenden sie. Sie lesen den geheimen Schlüssel in Hex aus NOSTR_SECRET_HEX; die cURL eins verwendet die Nackt Befehlszeilen-Tool, das einen nsec- oder hexenschlüssel nimmt, und sha256sum Bei 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");
}

Konto Zusammenfassung

Was das API-Blatt der App oben zeigt: Ihr öffentlicher Schlüssel, beide Balances, wie viele Schlüssel aktiv sind (nicht widerrufen oder abgelaufen) und die Automatischer Top-Up Einstellungen oder null wenn der Server nicht anbietet.

GET https://nymbot.ai/api/v1/account Sie benötigen a Unterschriebener Antrag.

Reaktionen

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

Verwaltung der Schlüssel

Die Endpunkte hinter der Schlüsselliste der App. Alle benötigen eine Unterschriebener AntragJeder Schlüssel wird in dieser Form mit Zeiten in ISO 8601 und Beträgen in Sats zurückgegeben:

Schlüsselobjekt

{
  "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 Es genügt, einen Schlüssel zu erkennen, aber nicht zu verwenden.Der Schlüssel selbst wird nur einmal zurückgegeben, wenn er erstellt wird.

Liste der Schlüssel

GET https://nymbot.ai/api/v1/keys Und unterschrieben haben.

FeldTyperforderlichBeschreibung
include_revokedDas Boolean (Query)NeinEnthält abgebrochenen Schlüssel. Default false.

Reaktionen

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

Erstellen eines Schlüssels

POST https://nymbot.ai/api/v1/keys Unterschrieben - zurück 201.

FeldTyperforderlichBeschreibung
nameStringJa1 bis 40 Zeichen, die sich von Ihren anderen aktiven Tasten unterscheiden (Fall ignorieren).
limit_satsintegrierenNeinDie Ausgabenkappe in Sats, mindestens 1. Lassen Sie sie für keine Kappe.
reset_periodStringNeindaily, weekly oder monthlyBedürfnisse limit_satsLassen Sie es für eine Kappe, die nie reset.
expire_atString oder IntegerNeinWenn der Schlüssel nicht mehr funktioniert: eine ISO 8601-Zeit oder Millisekunden seit 1970.

Die Antwort (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"
  }
}
StatusWann
400Ein fehlender oder zu langer Name; ein Name, der bereits verwendet wird (duplicate_name); eine Kappe, die keine ganze Zahl von mindestens 1 ist; eine Wiederherstellungsperiode ohne Kappe; ein Ablauf in der Vergangenheit; ein unbekanntes Feld (unknown_parameter); oder 25 aktive Schlüssel bereits (too_many_keys).
429Mehr als 60 Schlüssel von diesem Nym gemacht, oder 120 von dieser Adresse, in einer Stunde (rate_limit_exceeded, mit 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);

Ein Schlüssel lesen

GET https://nymbot.ai/api/v1/keys/{id} Und unterschrieben haben.

Rückkehr {"data": {…}} mit dem Schlüsselobjekt, oder 404 key_not_found wenn kein Schlüssel von Ihnen diese ID hat.

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

Ändern eines Schlüssels

PATCH https://nymbot.ai/api/v1/keys/{id} Und unterschrieben haben.

Senden Sie eine von name, limit_sats, reset_period Und expire_at, mit den gleichen Regeln wie beim Erstellen eines Schlüssels. null löscht ein Feld: keine Kappe, keine Wiederherstellung, keine Ablaufzeit. Wenn Sie die Wiederherstellungsperiode ändern, beginnt eine neue Periode bei null. Ein widerrufter Schlüssel kann nicht geändert werden (400 key_revoked) Rückkehr {"data": {…}} mit dem aktualisierten Schlüsselobjekt.

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

Widerruf eines Schlüssels

DELETE https://nymbot.ai/api/v1/keys/{id} Und unterschrieben haben.

Stoppt den Schlüssel sofort, für gut. Es bleibt in der Liste mit revoked_at eingerichtet, und kann mit include_revoked=trueWenn Sie einen Schlüssel widerrufen, der bereits widerrufen wurde, antworten Sie auf die gleiche Weise.Nur die neuesten 50 widerrufenen Schlüssel werden beibehalten; ältere werden gelöscht, wenn ein anderer Schlüssel widerrufen wird.

Reaktionen

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

Verbinden Sie eine Lightning-Wallet mit Nostr Wallet Connect und Nymbot erhöht das Gleichgewicht, wenn die API-Ausgaben niedrig sind. Das API-Blatt der App hat die gleichen Einstellungen; das sind die Endpunkte dahinter. Unterschriebener Antrag.

Wie es funktioniert: Nachdem eine API-Anfrage auf das Saldo aufgeladen wurde, das Sie auswählen, zu beobachten, wenn dieses Saldo unter Ihre Schwelle gefallen ist, macht Nymbot eine Rechnung für Ihren Top-up-Betrag, bittet Ihr Portemonnaie, es zu zahlen, und fügt den Kredit hinzu. Es erhöht sich maximal einmal alle 5 Minuten für jeden Nym und Balance, so dass ein Ausbruch von Anfragen das Portemonnaie nicht entleeren kann. Ausgeben in den Apps löst es nicht aus. Die Zeit und Größe des letzten Top-up und des letzten Fehlers sind in den Einstellungen; wenn eine Zahlung nach einem Fehler durchgeführt wurde, überprüfen Sie seine Rechnung mit Der Top-Up Status kreditieren Sie es.

Bevor Sie eine Brieftasche verbinden

Nymbot speichert es verschlüsselt und verwendet es nur jemals, um seine eigenen Top-up-Rechnungen zu bezahlen, aber erstellen Sie eine Verbindung nur dafür, mit einem Ausgabenbudget in Ihrer Brieftasche, so dass das meiste, was es jemals zahlen könnte, eine Zahl ist, die Sie gewählt haben. pay_invoice.

Ein Portemonnaie verbinden

POST https://nymbot.ai/api/v1/nwc-auto-topup/connect Und unterschrieben haben.

FeldTyperforderlichBeschreibung
nwc_urlStringJaDie Verbindungskette, beginnend nostr+walletconnect://Nymbot bittet um die Brieftasche get_info vor dem Speichern und speichert es verschlüsselt.
threshold_satsintegrierenJaTop up, wenn das Gleichgewicht unter diesen vielen sats fällt. mindestens 1.000.
topup_satsintegrierenJaWie viel jedes Mal hinzufügen. 1.000 bis 1.000.000 Sätze.
tierStringNeinpro (die Verzögerung) oder standard: das Gleichgewicht zu beobachten und top up.

Reaktionen

{
  "data": {
    "connected": true,
    "threshold_sats": 5000,
    "topup_sats": 20000,
    "tier": "pro",
    "last_topup_at": null,
    "last_topup_sats": null,
    "last_error": null
  }
}
StatusWann
400Keine Verbindungskette (invalid_nwc_url); die Brieftasche antwortete nicht über ihr Relay (nwc_unreachable) oder die Prüfung abgelehnt (nwc_rejected); die Verbindung kann keine Rechnungen bezahlen (nwc_missing_permission) oder einen Betrag außerhalb der Grenzen.
501Automatische Top-ups sind für diesen Server nicht aktiviert (nwc_unavailableDas Gleiche gilt für die anderen beiden Endpunkte.

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

Lesen der Einstellungen

GET https://nymbot.ai/api/v1/nwc-auto-topup Und unterschrieben haben.

Gibt das gleiche Objekt als verbinden zurück, mit connected: false und die anderen Felder null Wenn keine Brieftasche angeschlossen ist, wird die Verbindungskette selbst niemals zurückgegeben.

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

Entkoppeln

DELETE https://nymbot.ai/api/v1/nwc-auto-topup/connection Und unterschrieben haben.

Löscht die gespeicherte Verbindungszeile. Es werden keine weiteren Top-ups hergestellt. Um sicher zu sein, können Sie auch die Verbindung in Ihrer Brieftasche widerrufen.

Reaktionen

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

Bezahlen auf Anfrage ohne Schlüssel

Die Fixpreis-Endpunkte können für eine Anfrage zu einer Zeit über Lightning bezahlt werden, ohne Schlüssel, ohne Konto und ohne Saldo: POST /images/generations, POST /images/edits, POST /videos, POST /audio/speech, POST /audio/transcriptions, POST /audio/translations Und POST /embeddingsChat, Antworten und Nachrichten benötigen immer einen Schlüssel.Eine Anfrage, die einen Schlüssel trägt, wird wie gewohnt an das Gleichgewicht berechnet; der Zahlungsfluss beginnt nur, wenn kein Schlüssel gesendet wird.

Nymbot spricht zwei Versionen derselben Idee aus einem Backend: Lightning Labs Die L402 (auch unter seinem alten Namen akzeptiert, LSAT) und der IETF-Entwurf Bezahlung HTTP-Authentifizierung mit dem lightning Methode und charge Nutzen Sie, was Ihr Kunde versteht.

Führen Sie Ihren eigenen Server

Bezahlen ohne Schlüssel ist nur dann aktiviert, wenn API_L402_SECRET hält mindestens 32 zufällige Byte, wie hex (64 Zeichen) oder base64 (44). openssl rand -hex 32Ein kürzerer oder vermutlicher Wert schaltet das Feature aus und registriert warum. Um es zu drehen, verschieben Sie den alten Wert auf API_L402_SECRET_PREVIOUS für einen Tag: Anmeldeinformationen, Status-URLs und Herausforderungen, die unter ihnen gestellt wurden, arbeiten weiter, bis sie ablaufen.

Die Herausforderung

Senden Sie Ihre Anfrage mit NEIN Authorization header. Wenn es gültig ist, läuft nichts, und Sie erhalten 402 Payment Required mit einer Rechnung für genau das, was die Anfrage kostet: den gleichen Preis, den ein Schlüssel zahlen würde, umgewandelt bei 10 Sats ein Standardkredit oder 100 Sats ein Pro-Kredit und auf einen ganzen Sats abgerundet (mindestens 1 Sats und mindestens das 0,05 Kreditminimum). WWW-Authenticate Herausforderungen für die gleiche Rechnung:

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

Die Zahlung request Der Parameter ist base64url JSON: {"amount":"237","currency":"sat","methodDetails":{"invoice":"lnbc...","network":"mainnet","paymentHash":"..."}}.

Eine Herausforderung ist an den Endpunkt gebunden, an die Content-Type (sein Medientyp und, bei mehreren Teilen, seine Grenze) und an die SHA-256 der genauen Körper-Bytes, die Sie gesendet haben, und dauert 15 Minuten. identisch Wiederaufforderung: dasselbe Content-Type und die gleichen JSON-Bytes oder für die vielfältigen Endpunkte (/images/edits, /audio/transcriptions, /audio/translationsDie meisten HTTP-Bibliotheken wählen jedes Mal, wenn sie ein Formular kodieren, eine neue Grenze, so kodieren Sie es einmal und senden Sie diese Bytes zweimal.

Jede Adresse kann 30 Herausforderungen pro Minute anfordern (eine IPv6-Adresse zählt als ihre ganze /64). Anfragen, deren Adresse nicht bekannt ist, teilen eine strengere 10 pro Minute, und es gibt eine Gesamtobergrenze für die Herausforderungen Nymbot-Probleme über alle Adressen; eine Anfrage, die vor einer Herausforderung abgelehnt wird (z. B. mit einem Körper, der nicht gültig ist JSON) zählt nicht dazu. 429 mit Retry-AfterBezahlte Endpunkte, die ohne Schlüssel oder Credential angerufen werden, zählen auch zur allgemeinen Grenze von 120 nicht authentifizierten Anfragen pro Minute pro Adresse. Content-Type ist nicht application/json (oder multipart/form-data für uploads) wird abgelehnt 415 Und bekommt nie eine Rechnung.

Embeddings werden auf der Grundlage einer Schätzung der Token in der Eingabe mit einer Marge von 1,5 mal berechnet, da die tatsächliche Anzahl erst danach bekannt ist. Rückerstattung Token.

Senden der Zahlung

Bezahlen Sie die Rechnung mit jeder Lightning Brieftasche. Die Brieftasche gibt Ihnen das Vorbild, 64 Hexezeichen. Dann senden Sie die gleiche Anfrage mit einem dieser:

SchemaHeader
Die L402Authorization: L402 <macaroon>:<preimage> (LSAT funktioniert auch)
BezahlungAuthorization: Payment <base64url JSON>Wo der JSON ist {"challenge": {every parameter of the challenge, as sent}, "payload": {"preimage": "<hex>"}}

Eine bezahlte Anfrage antwortet genau wie eine mit einem Schlüssel gemacht, außer dass die nymbot Das Objekt hat keine Balancefelder: {"payment": "l402", "tier": "pro", "paid_sats": 237, "charged_sats": 237}Und es gibt keine X-Nymbot-Balance-Sats Header. Eine Anfrage, die mit dem Zahlungssystem bezahlt wird, erhält auch eine Payment-Receipt header (base64url JSON mit der Herausforderung id, der Zahlungs-Hash als reference, status Und timestampBezahlte Anfragen sind nicht an einen Nimm gebunden, so dass sie in der Abfrageverlauf nicht angezeigt werden.

StatusWann
402 payment_already_usedJede Zahlung zahlt für eine Anfrage.Die Antwort ist eine neue Herausforderung für diese Anfrage, so dass ein Client, der seine letzte Credential (wie lnget Es geht einfach wieder um Land.
402 payment_mismatchDie Credential wurde für einen anderen Endpunkt ausgestellt, Content-Type Eine neue Herausforderung für diese Anfrage kommt mit ihm; wenn die Zahlung zu klein war, kommt das, was Sie bezahlt haben, als eine Rückerstattung Token (refund_token Und refund_sats auf dem Körper)
402 payment_expiredMehr als 15 Minuten sind seit der Herausforderung vergangen. Eine neue Herausforderung kommt mit. Wenn das Vorbild zeigt, dass Sie bezahlt haben, kommt das, was Sie bezahlt haben, als eine neue Herausforderung zurück. Rückerstattung Token (refund_token Und refund_sats im Körper), einmal; dann wird das Credential aufgebraucht.
401 invalid_preimageDas Vorbild hasht nicht auf den Zahlungs-Hash der Rechnung.
401 invalid_payment_credentialDas Credential ist fehlerhaft, wurde geändert, nachdem Nymbot es ausgestellt hat, oder benennt einen Zahlungshash, für den Nymbot nie eine Rechnung ausgestellt hat.
429 rate_limit_exceededMehr als 30 Anmeldeinformationen oder Schlüssel, die nicht überprüft werden konnten, kamen innerhalb einer Minute von dieser Adresse, oder ein Rückerstattungstoken wurde mehr als 60 Mal in einer Minute gesendet. 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"));

Kunden bauen auf mppx mit einer Lightning-Methode die Zahlungsaufforderung selbst bewältigen; zeigen Sie sie am Endpunkt und lassen Sie sie bezahlen.

Videos zu

Eine bezahlte POST /videos Antworten 202 wie ein Schlüssel eins, plus a status_url: GET Es ist unterzeichnet und funktioniert für 24 Stunden, solange der Job gehalten wird.

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

Halten Sie die refund_token aus dieser Antwort: es wird nur hier gezeigt. Es ist leer, während das VideoGET /api/v1/l402/refunds Antworten "status": "pending"); wenn die Renderung fehlschlägt, läuft die Zahlung darauf. refund_sats für einen zurückerstatteten Job, aber niemals den Token, so dass das Teilen der Status-URL die Rückerstattung nicht teilt.

Rückerstattung

Wenn eine bezahlte Anfrage fehlschlägt und der Anbieter Nymbot für den Versuch berechnet hat, wird die Zahlung beibehalten und der Fehler sagt so, mit charged_sats, genau wie bei einer geöffneten Anfrage. Wenn sie ohne Abrechnung fehlschlägt, führt der Fehler zu einem Rückerstattung Token Es lohnt sich, was Sie bezahlt haben:

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

Unbenutzte Teile werden auf die gleiche Weise zurückgegeben: Wenn Sie zwei Bilder angefordert haben und eines nicht berechnet wurde, ist die erfolgreiche Antwort nymbot Objekt trägt ein Rückerstattungs-Token für das fehlende; eine Transkription, deren Länge nicht vorlesen werden konnte, wird für die längste Datei beziffert (nicht mehr als 30 Minuten), und der Unterschied zur tatsächlichen Länge kommt als Rückerstattungs-Token zurück; wenn es länger als 30 Minuten ist, wird es abgelehnt. 413 Die Embeddings geben zurück, was die Schätzung zurückgehalten hat.Ein versäumtes Video gibt den Token zurück, den seine Einreichung zurückgegeben hat.

Ein Rückerstattungstoken ist ein zufälliger 256-Bit-Code. Nymbot speichert nur seinen Hash, und er läuft nach 30 Tagen aus.

  • Bezahlen Sie mit ihm. Senden Sie Authorization: Bearer REFUND-… auf einem der oben genannten Endpunkte (ein OpenAI SDK nimmt es als API-Schlüssel).refund_token_sats In der nymbot Ein Token, der weniger wert ist als die Antworten auf die Anfrage 402 refund_insufficient; ein nicht gebuchtes Versagen legt den Satz auf denselben Token zurück.
  • Überprüfen Sie es. GET /api/v1/l402/refunds Der gleiche Header kehrt zurück {"sats": 237, "status": "open", "expires_at": "..."}.
  • Ein Token kann maximal 60 Mal pro Minute verwendet werden.
  • Bewegen Sie es zu einem Nym. Passe es in Geben Sie ein Geschenk in der Nymbot-App oder anrufen POST /api/v1/l402/refunds/redeem Mit a Unterschriebener Antrag Und {"refund_token": "REFUND-...", "balance": "standard"} (oder "pro"Gesamtkredite gehen in das Gleichgewicht (10 Sätze jeweils auf Standard, 100 auf Pro); Sätze, die für API-Anfragen keinen ganzen Kredit auf dem Token machen.

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"

Reaktionen

{ "data": { "credited": 23, "tier": "standard", "balance_credits": 123, "remaining_sats": 7 } }