On this page

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.

bash
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 only

serve writes an owner token with every scope to ~/.repoblock/admin_token (--home or $REPOBLOCK_HOME moves the data directory). Then:

curl

bash
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

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

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

bash
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 20

The 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:

Operations available per deployment
Areareuseforge.comPython node
Meta5 of 55 of 5
Identity2 of 22 of 2
Tokens3 of 30 of 3
Items8 of 85 of 8
Reviews3 of 32 of 3
Versions6 of 64 of 6
Distribution2 of 20 of 2
Verification2 of 20 of 2
Planning6 of 66 of 6
Orders12 of 129 of 12
Projects0 of 1210 of 12
Webhooks9 of 90 of 9
Ledger0 of 22 of 2
All58 of 7245 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-Key is required on create_order, pay_order, back_project and transfer_units, with replay, reuse and in-progress behaviour as in the idempotency guide (in memory for 24 hours).
  • get_item and the OpenAPI document send ETags and honour If-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 is me and acts for every wallet identity. Tokens cannot be created through the API; the owner token is the credential.
  • Money. Payments use the simulated rail. 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 with deliver_order.
  • Disputes. resolve_order_item is operator only and resolves a whole order (seller_bps 10000 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_model is free or fixed.
  • 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 Host header against loopback names (421 otherwise), 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-token shows 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-auth on 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:

bash
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: