On this page

Docs

Selling an item

A listing describes something reusable: where it lives, what it does, under what licence and at what price. Buyers' plans pick it up when its capabilities match their goal. On the hosted app you publish through a form, an import or the API. On a self-hosted node a listing is a signed item you publish from the CLI.

Where you can sell today. You can publish, import and version listings on the hosted app, free or with a price. Nobody can buy a paid listing there yet: checkout, orders, earnings and payouts are coming soon, and the files of a paid listing stay locked, except files the owner marks as previews. Escrow, delivery and payout work only on a self-hosted node or in the simulator, and there they run in test mode: no real money moves. Bundled listings labelled DEMO are examples with placeholder addresses. Never send funds to them.

What you can list

On the hosted app: repo, skill, harness, mcp_server, model, dataset, prompt or template. On a node: any item kind except paper, which includes design. Free and paid listings use the same form. A price of zero means free: it never enters escrow and earns no fee. A price above zero means every buyer deposits it into escrow first. Escrow runs in test mode only, so no real money changes hands yet.

List what you own or are licensed to resell. Do not list someone else's open-source project as yours. Free items found on GitHub, the MCP registry and Hugging Face already appear in plans without any action from you.

Publish on the hosted app

Sign in, then open /app/new (or Publish in the app). Everything on the form can be edited after you publish, except the kind and the URL name. If you belong to an organization, a Publish as menu lets you choose it as the owner; you need the write role or higher there.

FieldRequiredDescription
kindYesOne of the eight kinds above. Cannot be changed later.
titleYesUp to 120 characters. Shown in lists and search.
slugDerived from the titleThe name in the URL: /app/OWNER/SLUG. Lowercase letters, digits, dots, underscores and hyphens, up to 100 characters. Cannot be changed later. A taken name is refused, including the name of an item that was deleted.
summaryIn the formUp to 280 characters. Say what it does. Title, summary, tags and capabilities are what search reads.
licenseIn the formOne of: MIT, Apache-2.0, BSD-3-Clause, BSD-2-Clause, ISC, MPL-2.0, LGPL-3.0, GPL-3.0, AGPL-3.0, CC0-1.0, CC-BY-4.0, CC-BY-SA-4.0, CC-BY-NC-4.0, Unlicense, OpenRAIL, Commercial-Single-Project, Commercial-Team, Proprietary, UNKNOWN. Declared by you and not checked.
capabilitiesNo, up to 8 in the formIds from the capability list. They feed the planner and the capability filter on Explore.
tagsNoUp to 20 tags of up to 40 characters.
visibilityDefault publicpublic is listed and searchable. unlisted is reachable by URL only. private is visible to you and to organization members.
pricing_model, price_centsDefault freefree, fixed or pwyw (pay what you want, with a minimum). A price runs from $1.00 to $1,000.00. Paid listings need a verified email address.
source_url, homepage_urlNoWhere the code lives and where its documentation is.
installNoFor an MCP server, the command, arguments, environment placeholders or URL; for anything else, one install command. Shown on the item page. Up to 4 KB. Use placeholders such as <your-api-key> and never paste a secret: this text is public.
readmeNoMarkdown, up to 100,000 characters. Images must be https links.

The form saves an unpublished draft in your browser and checks the URL name as you type. The same listing can be created with POST /api/items and a token that has the write scope. Only kind and title are required there, and the API does not require a licence, so a listing made without one is stored as UNKNOWN. You can publish 30 new listings and import 20 repositories per hour.

Import from GitHub

Open /app/new/import and paste a public repository link such as https://github.com/owner/repo. The Worker reads the repository's name, description, licence, topics, star count, homepage and README from GitHub, creates a public listing and takes you to it. Check it afterwards: you can edit everything except the kind and the URL name.

  • The kind is mcp_server when the repository has the topic mcp-server, otherwise repo. You can choose another kind before importing.
  • Capabilities are inferred from the name, description, topics and README, unless you pick up to eight yourself.
  • The licence is taken from GitHub when it is on the list above, otherwise UNKNOWN. That adds risk to every plan that uses the listing, so set it if you know it.
  • The install command is set to git clone of the repository. The GitHub star count is shown as GitHub stars.
  • Code files, issues and releases stay on GitHub. Add files later as a version. Private repositories cannot be imported, and importing the same repository twice under one owner is refused.
  • The API call is POST /api/items/import with {"url": "https://github.com/owner/repo"} and optional owner, kind and capabilities.

Versions and files

A listing can exist without files, as an index entry that points at its source. To host files, add a version from the item's Release page, or while publishing in the form. A version is an immutable snapshot of its files.

  • The version is a semantic version such as 1.2.0. Publishing the same number twice is refused.
  • Limits per version: 100 files, 512 KB per file and 2 MB in total. Paths cannot contain .. or start with /.
  • The content hash is a SHA-256 over the sorted paths and file hashes, shown with the version. You can yank a version: it stays reachable but is no longer chosen as the latest.
  • Anyone can fetch a free public listing's files: GET /api/items/OWNER/SLUG/bundle returns the latest version as JSON, and GET /api/items/OWNER/SLUG/raw/VERSION/PATH returns one file.
  • Publishing from a script: POST /api/items/OWNER/SLUG/versions with {"version", "changelog", "files": [{"path", "content"}]}. Use a token with the write scope. See API tokens.

The Use this menu on an item page also shows a reuseforge pull OWNER/SLUG command. The command line tool behind it is in the repository (cli/, version 0.1.0) and is not installed from the site, so use the REST bundle line from the same menu.

Listings on a self-hosted node

The sections from here to the end of the page describe a self-hosted node, where a listing is a signed item (the node calls it a block, so its CLI, routes and JSON fields keep that word) and the escrow steps work in test mode.

Item fields

FieldRequiredDescription
nameYesDisplay name. Together with your key it makes the item id, so renaming creates a new item.
kindYesrepo, skill, harness, mcp_server, dataset, design or model.
summaryYesWhat it does, in one or two plain sentences. Name, summary and capabilities are what search and the planner read.
urlYesWhere the code or listing lives. Shown to buyers; only http and https links are made clickable.
capabilitiesNo, but needed to be plannedList of capability tags. Tags are lowercased and hyphenated. A declared capability is the strongest match signal.
licenseNoSPDX id such as MIT, or a commercial label. Default UNKNOWN, which adds risk.
price_usdNo0 for free. Never negative.
payoutFor any rail but the simulated oneMap of rail to address. See Payout addresses.
versionNoFree text, default 0.0.0.
content_hashRecommended for paid listingsThe git commit or tarball hash the price refers to. Buyers compare what they receive to it.
signalsNoNumbers that feed quality: tests_pass_rate (0 to 1), stars, downloads, citations. Self-reported until verified.
project_idNoId of a crowdfunded build whose unit holders should share this item's revenue.

Set by the system, ignored if you send them: owner (your public key, from the signature), id, rating and rating_count.

Publish an item from the CLI

block.json
{
  "name": "invoice-extractor",
  "kind": "skill",
  "summary": "Extracts line items, totals and tax ids from PDF invoices into JSON.",
  "url": "https://github.com/acme/invoice-extractor",
  "capabilities": ["document-parsing", "data-analysis"],
  "license": "MIT",
  "price_usd": 18,
  "version": "1.2.0",
  "content_hash": "sha256:9f2c1e0a",
  "payout": { "usdc-base": "0x0000000000000000000000000000000000000001" },
  "signals": { "tests_pass_rate": 0.96 }
}
bash
python -m repoblock publish block.json --as acme   # signs with the key "acme" and prints the block

--as names one of the identities in your node's key folder, created on first use. A running node does not see CLI writes until it restarts. To publish into a running node, post the same JSON, plus an identity field, to POST /api/blocks. Publishing again under the same name and key replaces the earlier version.

Licences

The licence is what you declare, on the hosted app and on a node. ReuseForge does not scan your code or confirm the declaration. Be accurate:

  • An UNKNOWN or missing licence adds 0.4 risk to every plan that uses the item. Declaring a real licence is the cheapest way to rank higher.
  • For paid code, state the terms you grant in the repository and in the delivery. The bundled demo listings use the label Commercial-Single-Project to mean one project per purchase. ReuseForge does not define or enforce that term for you.
  • The planner does not yet check that the licences of the items in one plan are compatible with each other. That check is open work. Buyers are told each item's licence and have to read them.

Payout addresses

In test mode nothing is sent to these addresses. payout maps a rail id to the address that should receive your money on that rail: usdc-base (an address on Base), usdt-ethereum (an Ethereum address), btc (a Bitcoin address). Give one per rail you accept.

  • The simulated rail needs no address. It pays to your public key.
  • On any other rail, a buyer cannot create an order for your item unless it has an address for that rail.
  • The address is copied into each order when it is created. Changing your listing later does not change orders already in flight.
  • On-chain transfers cannot be undone. A wrong address loses the money. Test with a small price first, once real rails are enabled.

Delivery

When a buyer's deposit is confirmed, you have until the delivery deadline (7 days by default) to deliver every paid item in that order. Delivering means signing a step that records an access link (by default your listing url) and the content hash from your listing. The link might be an invite to a private repository or a signed download. Make sure the buyer can reach it. Only you can mark your own item delivered.

bash
curl -s -X POST http://127.0.0.1:8420/api/orders/ORDER_ID/deliver \
  -d '{"identity":"acme","access":"https://github.com/acme/invoice-extractor/invitations"}'

There is no order inbox on a self-hosted node yet. You hear about an order from the buyer, or by reading the ledger at GET /api/events. If an order has several sellers and one is late, the whole order is refunded, so deliver early.

Show test evidence

A tests_pass_rate you type into the listing is a claim. Anyone can replace it with a signed result from actually running your tests:

bash
python -m repoblock verify BLK_ID                        # default: python -m unittest discover -q
python -m repoblock verify BLK_ID --cmd "make test"      # your own test command

It clones the item's url (a plain https git URL), runs the command in a throwaway folder with a timeout, reads the result, and appends a signed block.attest event with the pass rate and test count. The newest attestation replaces the claim in the item's quality score.

  • The result reader understands unittest output (Ran N tests). If your runner prints no such line, the test count is 0 and the rate is recorded as 0, even if the command passed. Make your test command print a summary in that form.
  • The clone times out after 120 seconds and the tests after 300.
  • Verify runs the repository's code on your machine. Read the sandbox warning before running it on anything you do not control.

Fees and getting paid

You receive the listed price minus the network fee (1% by default on a self-hosted node), rounded down to the cent. Today this is a record in test mode, not money: on the simulated rail it is a balance in memory, and a node does not send on-chain payouts. The record is made when the order is released, and you do not need to ask. If the order is refunded after a dispute or a missed deadline, you are paid nothing for it. Free listings never pay a fee. The hosted app takes no orders yet, and its earnings page is coming soon. For hosted-app fees see Pricing.

Reviews and reputation

On the hosted app any signed-in user except the owner can leave one review per listing, rated 1 to 5, and the owner can reply. A review is marked as a verified purchase only after an order for the item is released, which cannot happen yet. On a node, buyers can rate an item from 1 to 5, but only if their own order for that item was released. The score is an average pulled toward 3 until an item has several reviews, so a single rating cannot make or break a listing. It feeds directly into quality.

A new listing has no reviews and carries a small extra risk (0.2) for that reason. Good descriptions, a real licence, a content hash and an independent test attestation are what move it up in the meantime.

Updating and retracting

  • On the hosted app, edit the listing from its Settings tab and add versions from its Release tab. You can archive a listing or transfer it to an organization you own.
  • On a node, publish again with the same name and key to ship a new version. The latest publish wins.
  • A new price applies to new orders only.
  • Retracting is a signed block.retract event. The CLI does not expose it yet; call Registry.retract from Python.

Last updated: