Integrate Ⱡ Credits into your service. Available in JavaScript and Ruby.
legendum.js — JavaScript (zero dependencies, uses global fetch)
legendum.rb — Ruby (zero dependencies beyond net/http)
legendum.md — full documentation
patterns.md — integration patterns (how to combine OAuth, linking, and billing)
Email pay@legendum.co.uk to register your service and receive your credentials. Then set environment variables or pass config directly:
LEGENDUM_API_KEY=lpk_...
LEGENDUM_SECRET=lsk_...
LEGENDUM_BASE_URL=https://legendum.co.uk
For charging credits from your backend:
// JavaScript
const legendum = require("./legendum.js");
const client = legendum.create({ apiKey, secret });
await client.charge(accountToken, 10, "API call");
await client.balance(accountToken);
const res = await client.reserve(accountToken, 50, "job");
await res.settle(); // or res.release()
await client.linkAccount("lak_...");
# Ruby
require_relative "legendum"
client = Legendum.create(api_key:, secret:)
client.charge(account_token, 10, "API call")
client.balance(account_token)
res = client.reserve(account_token, 50, "job")
res.settle # or res.release
client.link_account("lak_...")
| Method | Description |
|---|---|
charge(token, amount, desc) | Charge credits from a linked account |
balance(token) | Get balance for a linked account |
reserve(token, amount, desc) | Hold credits (up to 15 min), returns reservation |
request_link() | Request a pairing code for account linking |
poll_link(id) | Poll for link confirmation |
wait_for_link(id) | Poll until confirmed or expired |
auth_url(opts) | Build a "Login with Legendum" URL |
auth_and_link_url(opts) | Build a "Login and link" URL (after request_link) |
exchange_code(code, uri) | Exchange auth code for user info |
link_account(key) | Link an account to your service |
tab(token, desc, opts) | Batch micro-charges, flush at threshold |
middleware (JavaScript) / Legendum::Middleware (Ruby)Mount server-side routes: POST …/link, POST …/auth-link (JSON body redirect_uri, state → returns { url } for login-and-link), POST …/confirm, GET …/status. Keeps API credentials on the server.
linkController (JavaScript)For reactive UIs: legendum.linkController({ mountAt, onChange, ... }) returns startLink() (pairing popup + poll) and startAuthAndLink() with redirectUri + state. With mountAt, startAuthAndLink uses POST …/auth-link by default (no browser client). Or pass client from create() and set authLinkUrl: null to build the authorize URL in the browser after POST …/link.
For scripts and agents acting on behalf of a user:
// JavaScript
const acct = legendum.account("lak_...");
await acct.whoami();
await acct.balance();
await acct.transactions(50);
await acct.link("ABC123");
await acct.unlink("example.com");
await acct.authorize({ clientId, redirectUri, state });
# Ruby
acct = Legendum.account("lak_...")
acct.whoami
acct.balance
acct.transactions(50)
acct.link("ABC123")
acct.unlink("example.com")
acct.authorize(client_id:, redirect_uri:, state:)
// JavaScript
legendum.mock({
charge: (token, amount, desc) => ({ email: "mock@test.com", transaction_id: 1, balance: 50 }),
});
// ... run tests ...
legendum.unmock();
# Ruby
Legendum.mock(
charge: ->(token, amount, desc, **opts) { { "email" => "mock@test.com", "transaction_id" => 1, "balance" => 50 } }
)
# ... run tests ...
Legendum.unmock
All methods throw/raise on failure with code, status, and message:
| Code | Status | Meaning |
|---|---|---|
unauthorized | 401 | Invalid API key or secret |
insufficient_funds | 402 | Balance too low |
bad_request | 400 | Missing or invalid fields |
token_not_found | 404 | Account token not found |
invalid_state | 409 | Reservation not in held state |
expired | 410 | Reservation expired |