API
Self-hosting a node
Run the Python reference node, which serves the same /api/v1 wire format as reuseforge.com, point the SDKs and the CLI at it, and see exactly which operations it implements.
The repository contains a reference node written in Python (repoblock/). It keeps a signed, append-only ledger of items, orders and reviews, runs the planner and an escrow state machine, and serves the v1 HTTP API at /api/v1/, plus a local web UI and an MCP server. Because the wire format is the hosted API's, the SDKs, the rf CLI and any HTTP client work against it by changing one URL. Use it to develop against the API, to run the money flow end to end on simulated payments, or to run a private registry.
Run it
The only dependency is cryptography. Python 3.9 or newer.
git clone https://github.com/Longfordjames/Claude-1 && cd Claude-1
pip install -r requirements.txt
python3 -m repoblock seed # optional: the bundled example items
python3 -m repoblock serve # web UI and API on http://127.0.0.1:8420, loopback onlyserve writes an owner token with every scope to ~/.repoblock/admin_token (--home or $REPOBLOCK_HOME moves the data directory). Then:
curl
export REUSEFORGE_TOKEN="$(cat ~/.repoblock/admin_token)"
curl http://127.0.0.1:8420/api/v1/ | head -c 300
curl http://127.0.0.1:8420/api/v1/me -H "Authorization: Bearer $REUSEFORGE_TOKEN"Python
import os
import reuseforge
token = open(os.path.expanduser("~/.repoblock/admin_token")).read().strip()
client = reuseforge.Client(base_url="http://127.0.0.1:8420/api/v1", token=token)
for item in client.search_items(q="pdf", limit=10):
print(item["full_name"], item["price_cents"])JavaScript
import { ReuseForge } from '@reuseforge/sdk';
import { readFileSync } from 'node:fs';
import { homedir } from 'node:os';
const token = readFileSync(`${homedir()}/.repoblock/admin_token`, 'utf8').trim();
const client = new ReuseForge({ baseUrl: 'http://127.0.0.1:8420/api/v1', token });
console.log((await client.getMe()).handle);CLI
export REUSEFORGE_TOKEN="$(cat ~/.repoblock/admin_token)"
export REUSEFORGE_API_URL=http://127.0.0.1:8420/api/v1 # or pass --api-url on every command
rf whoami
rf plan "extract totals from pdf invoices" --budget 20The SDKs refuse to send a token over plain http except to loopback addresses, which is why this works on 127.0.0.1 and would not on a LAN address without TLS in front.
What it implements
A node answers 501 not_implemented (a normal problem document, so the SDKs raise a typed error) for every operation it does not provide. The table is generated from the source of the node and the hosted Worker when these pages are built:
| Area | reuseforge.com | Python node |
|---|---|---|
| Meta | 5 of 5 | 5 of 5 |
| Identity | 2 of 2 | 2 of 2 |
| Tokens | 3 of 3 | 0 of 3 |
| Items | 8 of 8 | 5 of 8 |
| Reviews | 3 of 3 | 2 of 3 |
| Versions | 6 of 6 | 4 of 6 |
| Distribution | 2 of 2 | 0 of 2 |
| Verification | 2 of 2 | 0 of 2 |
| Planning | 6 of 6 | 6 of 6 |
| Orders | 12 of 12 | 9 of 12 |
| Projects | 0 of 12 | 10 of 12 |
| Webhooks | 9 of 9 | 0 of 9 |
| Ledger | 0 of 2 | 2 of 2 |
| All | 58 of 72 | 45 of 72 |
In words: the node implements meta, items (search, get, create, retract, stats), reviews (list, create), versions (list, get, bundle, install descriptor), the planner and discovery, orders, projects and the ledger feed. It does not implement tokens, webhooks, update_item, publish_version, update_version, stars, verifications, payouts and earnings, per-item refunds, withdrawing a backing, the abort vote, archives or marketplaces. A node stores references, not files: a version carries no files, and the install descriptor gives a display-only git clone or open command and says so in its warnings.
Behaviour that matches the hosted API
- Problem documents,
X-Request-Id,ReuseForge-Version,RateLimit-*headers and the same cursor pagination (cursors are signed with a per-process key and do not survive a restart). - Rate limit tiers with the contract's numbers, kept in memory.
Idempotency-Keyis required oncreate_order,pay_order,back_projectandtransfer_units, with replay, reuse and in-progress behaviour as in the idempotency guide (in memory for 24 hours). get_itemand the OpenAPI document send ETags and honourIf-None-Match. CORS is open without credentials.- Request bodies are capped at 1 MB (4 MB for
post_ledger_events).
What differs
- Accounts. There is no account database. An identity is a signing key in the node's wallet (
<home>/keys); the node operator ismeand acts for every wallet identity. Tokens cannot be created through the API; the owner token is the credential. - Money. Payments use the
simulatedrail. A configured real-chain rail only builds payment instructions and verifies deposits. The node operator is the escrow agent, and there is no automatic delivery of hosted content: the seller identity delivers withdeliver_order. - Disputes.
resolve_order_itemis operator only and resolves a whole order (seller_bps10000 pays the seller, 0 refunds the buyer). - Reviews are ledger events and cannot be deleted; only a buyer whose order was settled by the node can review.
- Visibility and pricing. Items must be
public;pricing_modelisfreeorfixed. - Plans live in memory for 24 hours.
The node's own reference is docs/API.md in the repository.
Putting a node on a network
- By default it listens on loopback and checks the
Hostheader against loopback names (421otherwise), as a defence against DNS rebinding. Add public names with--public-host. - Off loopback an owner token is mandatory:
--admin-token-file <file>(or$REPOBLOCK_ADMIN_TOKEN), at least 32 characters. Prefer the file;--admin-tokenshows up in process listings. - Put TLS in front (a reverse proxy). The node does not terminate TLS.
- Wrong tokens count against a per-address bucket (10 a minute), after which the address gets
429. - A node started with
--no-authon loopback treats any local process as its owner. Use it only on a machine you alone control.
Several nodes
Nodes exchange the signed ledger, so a registry can span machines:
python3 -m repoblock sync http://other-node:8420 # exchange ledger events with a peer
rf ledger sync http://other-node:8420 # the same through the API (list_ledger_events and post_ledger_events)Events carry signatures, which post_ledger_events verifies before merging; it reports added, duplicates and rejected. The node token for rf ledger comes only from REUSEFORGE_NODE_TOKEN, never from your hosted credentials.
The hosted service
reuseforge.com runs a different implementation of the same contract: a Cloudflare Worker (worker/) with D1 and KV, deployed by the maintainers. It has accounts, tokens, files, webhooks and verifications, but its payments group (orders, payouts, projects, ledger) is not switched on yet, which is why the quickstart's buying steps use a node. The availability table shows both side by side. To try the Worker locally: node worker/test/helpers/serve.js --port 8787 prints a base URL and a throwaway token.
Last updated: