Recipes
Each recipe needs a token with the scopes it names, in an EONAUTH_TOKEN environment variable on
your server.
A small client
Section titled “A small client”Most recipes use this helper (Node 18 or newer).
const BASE = "https://panel.eonauth.fyi/seller/v1";
export async function eon(method, path, body) { const res = await fetch(BASE + path, { method, headers: { Authorization: `Bearer ${process.env.EONAUTH_TOKEN}`, ...(body ? { "Content-Type": "application/json" } : {}), }, body: body ? JSON.stringify(body) : undefined, }); if (res.status === 429) { const wait = Number(res.headers.get("Retry-After") ?? 60); throw Object.assign(new Error(`rate limited, retry in ${wait}s`), { retryAfter: wait }); } const json = await res.json(); if (!json.ok) throw Object.assign(new Error(`${json.error.code}: ${json.error.message}`), { code: json.error.code }); return json.data;}
export const APP_ID = "app_ea9745b1df9e4a9bacb22cb1c200993b";Deliver a key from a Discord bot
Section titled “Deliver a key from a Discord bot”Scope: licenses. Give the key to the buyer in a direct message once your payment provider confirms
the order.
import { eon, APP_ID } from "./eonauth.js";
const PRO_TIER = "tier_e26fe8d406f94e13bff9d10c9291c37f";
export async function issueKey(orderId) { const batch = await eon("POST", "/license/create", { app_id: APP_ID, tier_id: PRO_TIER, preset: "month", quantity: 1, note: `discord order ${orderId}`, }); return batch.licenses[0].key; // shown once: send it now and keep your own record}Refund: revoke the key and ban the buyer
Section titled “Refund: revoke the key and ban the buyer”Scopes: licenses, users.
import { eon, APP_ID } from "./eonauth.js";
export async function refund(orderId) { const { items } = await eon("GET", `/licenses?app_id=${APP_ID}&q=${encodeURIComponent(`order ${orderId}`)}`); for (const key of items) { await eon("POST", "/license/revoke", { license_id: key.id, reason: `refund ${orderId}` }); if (key.user_id) await eon("POST", "/user/ban", { user_id: key.user_id, reason: `refund ${orderId}` }); }}Revoking takes away the time the key gave. Banning also ends the user’s other sessions, whatever keys they hold.
A support command: reset someone’s PC
Section titled “A support command: reset someone’s PC”Scope: users. For a “I got a new PC” request.
import { eon, APP_ID } from "./eonauth.js";
export async function resetPc(username) { const { items } = await eon("GET", `/users?app_id=${APP_ID}&q=${encodeURIComponent(username)}`); const user = items.find((u) => u.username === username); if (!user) return "No such user."; try { const r = await eon("POST", "/user/reset-hwid", { user_id: user.id }); return r.reset ? `Done. ${r.hwid_resets_used} of ${r.allowance} resets used.` : r.reason; } catch (err) { if (err.code === "HWID_RESET_QUOTA_EXCEEDED") return "No resets left. Ask the owner."; if (err.code === "HWID_RESET_COOLDOWN") return "Reset too recently. Try again later."; throw err; }}Make up for an outage
Section titled “Make up for an outage”Scope: users. Give everyone a day back.
curl -X POST https://panel.eonauth.fyi/seller/v1/users/time \ -H "Authorization: Bearer $EONAUTH_TOKEN" \ -H "Content-Type: application/json" \ -d '{"app_id":"app_ea9745b1df9e4a9bacb22cb1c200993b","all_users":true,"seconds":86400,"reason":"outage 12 Nov"}'Nightly backup of keys and users
Section titled “Nightly backup of keys and users”Scopes: licenses, users. Exports hold up to 5,000 rows each and never contain whole keys.
import json, os, datetime, requests
BASE = "https://panel.eonauth.fyi/seller/v1"APP_ID = "app_ea9745b1df9e4a9bacb22cb1c200993b"H = {"Authorization": f"Bearer {os.environ['EONAUTH_TOKEN']}"}
day = datetime.date.today().isoformat()for name in ("licenses", "users"): r = requests.get(f"{BASE}/{name}/export", params={"app_id": APP_ID}, headers=H, timeout=60) data = r.json()["data"] if data["truncated"]: print(f"warning: {name} export hit 5,000 rows") with open(f"backup-{name}-{day}.json", "w") as f: json.dump(data["items"], f)Ship a new download link to Pro users
Section titled “Ship a new download link to Pro users”Scope: variables. Your app reads the variable by ID, so changing it reaches users the next time
the app fetches it.
import { eon } from "./eonauth.js";
await eon("POST", "/variable/update", { variable_id: "var_342c8c7e97e24ae1b79183b18d7011d5", value: "https://cdn.example.com/pro/build-1.5.0.zip",});