Skip to content

The credits API

The one read-only route on your domain that names who wrote each article and where their cut goes.

On this page

This is the one endpoint you build. The toll calls it to learn who wrote an article and where their share goes, and its answer also decides whether the article is tolled. It is read-only and never sees a payment.

The request

GET https://your-site.example/api/credits/<slug>

<slug> is your article's identifier, the same one in its URL. The toll derives it from the path of the incoming read. The base URL is whatever you give us as your credits endpoint; the /credits/<slug> shape is fixed.

Make the route public and cacheable. The toll may call it often; a few minutes of caching (ISR, a CDN, Cache-Control) is enough. It must not require auth beyond an optional shared token.

The two responses

Tolled: return the credits

For an article you want to charge agents for, return 200 with this JSON:

{
  "slug": "the-river-and-the-name",
  "title": "The River and the Name",
  "contributors": [
    { "authorId": "ravi",  "wallet": "0x6b1f…a90c", "weight": 2 },
    { "authorId": "guest", "wallet": "0x9d22…41fe", "weight": 1 }
  ]
}
Field Meaning
slug Echo of the slug requested.
title Human title, used in receipts and the operator view.
contributors Who gets paid. At least one entry.
contributors[].authorId Your stable handle for whoever gets paid: an author, or the site itself.
contributors[].wallet The payee's EVM address (0x + 40 hex). Their share settles here. It has to be able to receive USDC on your site's settlement network; an exchange deposit address issued for a different one loses the funds. Optional, so see "an author you have no address for" below.
contributors[].weight Relative share. Omit for an equal split; 2 and 1 means two-thirds and one-third.

A contributor can stand for a group instead of a single wallet by carrying members (a nested list of contributors) instead of wallet. The group's share re-splits among its members by their weights. Use it only for a collective that divides its share internally.

Pages with no author

Docs, a changelog, a pricing page or a company blog may have no byline. Return a single contributor standing for the site, pointed at the wallet you settle to:

{
  "slug": "pricing",
  "title": "Pricing",
  "contributors": [{ "authorId": "site", "wallet": "0x6b1f…a90c" }]
}

authorId only has to be stable and unique within your site, so site or your domain works. The toll, the licence and the receipt behave the same; the money lands in one wallet.

If your whole site works this way, you don't need this endpoint. Set one payout wallet on the site and every page under your article prefixes tolls to it. Use this endpoint when you want per-article control over who is paid: free pages, author splits, a different wallet per piece.

The response carries no amount, so it cannot set prices. A page's price comes from your site's base toll and per-path price rules in the site's Price row. See getting tolled.

Free: return 404

HTTP/1.1 404 Not Found

A 404 means this article is free. The toll lets every reader through, agent or not. Return 404 for:

  • anything you want open to agents,
  • drafts and unpublished pieces,
  • articles whose author has no wallet (there's nothing to pay into),
  • anything behind your own membership or paywall. Don't toll what you already gate another way, or readers pay twice.

Decide this server-side from your own data: return credits only when the article is published, public, and has at least one author with a wallet. Otherwise, 404.

Rules

  • Wallets are real addresses. Each wallet must be a valid EVM address. A malformed address is rejected, not guessed at, and so is the burn address (0x0000…0000), where a transfer succeeds and destroys the money.

  • Use checksummed addresses. A mixed-case address carries an EIP-55 checksum, so a transposed character in it can be caught. An all-lowercase address carries none, and nothing at any layer can tell it from a typo. npx naulon check reports which of yours are in that state.

  • Weights are relative, money is exact. The toll splits the fee by weight in whole micro-USDC. This API carries who and where, never amounts.

  • No secrets in the response. Return attribution only: no settlement secrets, API tokens, or anything an author wouldn't want public. Read from a privileged path on your side and serve only the safe fields.

  • An author you have no address for: name them, omit the wallet. A contributor may carry an authorId and no wallet. That is better than leaving them out, because we can fill it from an address the author registered with us. When you invite an author, they set their own payout address, and every article on your site that names them by that authorId routes to it without you handling it.

    The registration is per site, keyed on the authorId you use here, so an author who writes for two sites accepts an invitation on each, and may point each one at a different address. Ids do not have to agree across sites.

    If nothing fills it, their weight goes to the contributors that do have addresses, and if none do, the article reads free. It never pays someone else. Your site's own wallet catches those shares instead while Sites → Manage → Payouts → Unclaimed author shares is on, which it is by default for new sites.

    Dropping the contributor entirely also works and also means "free if nobody else is payable", but loses the credit and the chance to route it.

Checking it

Two requests check the wiring:

# A gated article → 200 with contributors
curl https://your-site.example/api/credits/the-river-and-the-name

# A free or unknown article → 404
curl -i https://your-site.example/api/credits/something-free

If the first returns the shape above and the second a bare 404, you're done. Next, read settlement.