Skip to content

Paid Apps ​

Publish an app once and get paid on every coin page that installs it, two ways:

  • Items your app sells. Passes and things owned once, priced in dollars. Each page that installs your app sells them, and every sale pays you your share.
  • An install price. A one-time price a coin page pays to install your app.

Every sale goes through the Chain Daddy checkout. The buyer's own transaction pays each wallet directly: the page, you and the fee. Chain Daddy never holds the money, so there is no payout schedule, balance or minimum.

Installing an app works on every plan. A page installs an app that sells on Free too.

Before you start ​

  1. Join the Developer Beta Program: any paid plan, and the program agreement signed with the wallet that holds it.
  2. Sign the Paid Apps Addendum. Open your app in the Developer Portal and go to its Paid tab. The addendum is signed with your wallet, like the program agreement.

The Developer Beta Program Agreement itself includes no revenue share. The Paid Apps Addendum is the separate agreement that adds selling through your apps: you sell only through the Chain Daddy checkout, all sales are final, and the items you may not sell stay off your app. Moving value outside the checkout is grounds for delisting.

The current version is dated October 14, 2026. If you signed an earlier version, your app keeps selling for 30 days after the new one is published; the Paid tab shows the date to sign by. After that, it sells again as soon as you sign.

When your app sells ​

Your app sells while all of these hold. When one does not, every order through it is refused with 409 APP_NOT_SELLING and a reason, on every page, until it is put right. Buyers keep what they already hold, and receipts already issued stay valid.

You read why in the app's Paid tab, or with GET /api/v2/developer/apps/{appId}/paid/selling, which answers selling and the reason below. A buyer is told less: where the reason is about your standing with us, the refused order says only developer_unavailable.

Your reasonThe refused order's reasonWhat it meansWhat to do
app_not_publishedthe sameThe app is not publishedPublish it, or get an approved build live
selling_switched_offthe sameChain Daddy stopped this app sellingThe notice we sent says why and how to contest it
developer_suspendeddeveloper_unavailableYour Developer Program access is suspended, on any wallet of your accountThe notice we sent says why and how to contest it
addendum_not_signeddeveloper_unavailableYou have never signed a Paid Apps Addendum, or you have not signed the current one and the 30 days to sign it are overSign it in the app's Paid tab. Selling resumes at once
developer_pausedthe sameYou paused sellingResume it (below)
not in your read: it depends on the page's chainno_payout_on_chain, payout_contract_missingYou are not paid on that page's chain: no payout wallet for it, or a contract wallet that does not exist thereSet a payout wallet for that chain under Set up your app

A new addendum. When we publish a new version of the Paid Apps Addendum, your apps keep selling for 30 days if you signed an earlier version. An app takes no payment of any kind for its developer, a pay included, until that developer has signed an addendum at least once. The coin page's own items are different: when your app opens the page's store for one of its items, the page is the seller and you are paid nothing, so that sale does not depend on the addendum. You get a notice when it is published, and again 7 days and 1 day before the 30 days end, and the Paid tab asks you to sign the updated addendum by that date. During the 30 days the Paid tab works as before, prices and payouts included. After them, until you sign, you can still pause selling and archive items; changing prices and payouts needs the current version signed. The Developer Beta Program Agreement works the same way: when it changes, you keep the portal for 30 days and sign the new version from the notice at the top of it.

Pausing. You can stop your app selling at any time, and start it again, whether or not you have signed the current addendum: Pause selling in the app's Paid tab, or PUT /api/v2/developer/apps/{appId}/paid/selling with {"paused": true}. A pause changes no terms, so page owners accept nothing again when you resume.

Set up your app ​

On the app's Paid tab:

SettingWhat it is
EVM payout walletWhere your share is paid on EVM chains
Solana payout walletWhere your share is paid on Solana
Install priceOptional. A one-time price in dollars, paid in USDC. See Install price
Business or private sellerWhether you sell the install licence as a business or as a private person. The page owner sees which when they buy it
ItemsWhat your app sells. See Items

A page on a chain where you have no payout wallet cannot sell your items. A payout wallet you change applies to new orders.

Changes need your wallet's signature ​

Changing a payout wallet, the install price, or an item's price, currency, type, your share or how long a pass lasts, and adding a new item, is being moved behind a signature from your developer wallet, on top of your sign-in or API key. So a leaked API key cannot send your sales to someone else. Until it is switched on, these changes save without one, and a client that handles the refusal below works before and after.

  • In the portal, your wallet asks you to sign when you save. Connect the wallet that owns the app: another wallet is not asked.
  • From the API, the first try answers 403 WALLET_SIGNATURE_REQUIRED with the exact message under signing. Sign that message as it is and send the same change again with walletSignature.
  • A signed message works once, for 10 minutes, and only for the values it names. If the app changed in between, the answer is a new message to sign.
  • Archiving an item, pausing selling, an item's name or image, and a dry run never need a signature. You can always stop selling.
bash
# 1. Send the change. With no signature the API says what to sign.
curl -X PUT "https://api.chaindaddy.io/api/v2/developer/apps/$APP_ID/paid" \
  -H "Authorization: Bearer $CD_API_KEY" -H "Content-Type: application/json" \
  -d '{"payoutAddressEvm":"0xNew…","payoutAddressSolana":"","installPriceUsdMicros":null}'
#   → 403 {"error":"…","code":"WALLET_SIGNATURE_REQUIRED","signing":{
#        "signer":"0xYourDeveloperWallet…",
#        "message":"Chain Daddy: change where a paid app is paid or what it charges.\n\nApp: …\nDeveloper: 0x…\nChange: payoutAddressEvm: 0xOld… -> 0xNew…\nNonce: 3f9c…\nIssued At: 2026-10-11T12:00:00Z",
#        "nonce":"3f9c…","issuedAt":"2026-10-11T12:00:00Z"}}

# 2. Sign signing.message with the signer wallet (a personal message, EIP-191).
chaindaddy signer sign --message "$MESSAGE" --signer walletconnect

# 3. Send the same change again, with the signature and the nonce and issuedAt you were given.
curl -X PUT "https://api.chaindaddy.io/api/v2/developer/apps/$APP_ID/paid" \
  -H "Authorization: Bearer $CD_API_KEY" -H "Content-Type: application/json" \
  -d '{"payoutAddressEvm":"0xNew…","payoutAddressSolana":"","installPriceUsdMicros":null,
       "walletSignature":{"signature":"0x…","nonce":"3f9c…","issuedAt":"2026-10-11T12:00:00Z"}}'

An item's PATCH takes walletSignature the same way.

Every payout wallet change is sent to you in your notifications and by email, and every change is kept in the app's history (changes in GET …/paid). If you get a notice for a change you did not make, set the wallet back, revoke your API keys, and write to support@chaindaddy.io.

A Safe as your developer wallet ​

A Safe cannot sign in the portal's wallet prompt. Its owners sign the same message from the command line, and the change goes through the API with chainId, the chain the Safe is deployed on:

bash
printf '%s' "$MESSAGE" > change.txt   # signing.message exactly, with no newline added at the end
chaindaddy launchpad sign-message --address <Safe> --chain 8453 --text-file change.txt --out change-typed-data.json
chaindaddy signer sign --typed-data change-typed-data.json --address <owner> --signer ledger   # each signing owner
chaindaddy launchpad sign-message --finish --out change-typed-data.json --sig <sig1> --sig <sig2>
# then step 3 above, with "walletSignature":{"signature":"<the combined signature>","nonce":"…","issuedAt":"…","chainId":8453}

The owners have the message's 10 minutes to sign. The commands are in the CLI reference.

A Safe as your payout wallet ​

A Safe exists only on the chains it was deployed to. Once signed changes are on, setting one as your payout wallet records the chains it exists on then, and a page on any other chain cannot sell your items (409 APP_NOT_SELLING, payout_contract_missing) rather than pay an address nobody controls there. The chains are read when the payout wallet changes, so after deploying the Safe somewhere new, set another payout wallet and then this one again.

Items ​

Each item has a price in US dollars and the share of each sale that is yours.

FieldWhat it is
itemKeyYour key for the item: lowercase letters, digits, _ and -, up to 48 characters, starting with a letter or digit
typenon_consumable (owned once) or timed (a pass, from 1 second to 10 years)
name, description, imageUrl, metadataWhat buyers see, and any JSON your app needs
priceUsdMicrosThe price in millionths of a dollar ($5 is 5000000), at most the per-purchase limit
currencyusdc (exactly the dollar price) or token, the page's own token at its live rate. Never the chain's coin
durationSecondsFor a timed item, how long one pass lasts
maxPerWalletOptional. The most one wallet may hold
developerBpsYour share, in basis points of what is left after the fee: 0 to 9999 (99.99%). The page always keeps a part
sellOutsideAppOptional, false unless you set it. true lets a coin that installed your app sell this item from its own website too: Selling on a coin's own website
json
{
  "itemKey": "season-pass",
  "type": "timed",
  "name": "Season pass",
  "description": "Every track for 30 days.",
  "imageUrl": "https://app.example/items/season-pass.png",
  "priceUsdMicros": 10000000,
  "currency": "usdc",
  "durationSeconds": 2592000,
  "developerBps": 3000
}

On a page whose coin launched elsewhere, a $10 sale of this pass pays $0.25 in fees, $2.925 to you (30% of $9.75) and $6.825 to the page. On a page whose coin launched in a Chain Daddy launchpad pool there is no fee: $3.00 to you and $7.00 to the page.

When you change an item ​

You changeWhat happens on pages that installed your app
Name, description, image, metadata or the most one wallet may holdUpdates on every page as you save it. Nobody has to accept it
Price, currency, type, duration or your shareThat item pauses on every page until the page's owner accepts the new terms. Your other items keep selling
A new itemReaches a page when its owner accepts your terms again
The install priceNothing pauses, and a page that holds a licence keeps it. Each owner is asked to review the new terms
Archive an itemIt stops selling everywhere. Buyers keep what they hold
Whether a coin's own website may sell it (sellOutsideApp)Applies at once. Nothing pauses and nobody has to accept it

How a page's owner accepts. The owner sees the app under Apps in their page manager, with a Review button. The review shows each change against what they accepted before (the old price and your old share), any new item, and any item you dropped. Accepting puts the new terms on the page at once: the app stays installed and the item sells again. Owners are also told once a day, in their notifications and by email, about apps with new terms.

Try a change first. Add ?dryRun=1 to the item PATCH to see what it would do without doing it:

bash
curl -X PATCH "https://api.chaindaddy.io/api/v2/developer/apps/$APP_ID/paid/items/season-pass?dryRun=1" \
  -H "Authorization: Bearer $CD_API_KEY" -H "Content-Type: application/json" \
  -d '{"priceUsdMicros": 12000000}'
#   → {"dryRun":true,"termsChanged":true,"pagesPaused":14,"pagesAlreadyPaused":2,"pagesUpdated":0,"stopsSelling":false,"item":{…}}
  • pagesPaused: pages selling the item now that would stop until their owners accept.
  • pagesAlreadyPaused: pages still waiting on an earlier change.
  • pagesUpdated: pages that take a name, image or limit change as it is saved.

A dry run writes nothing and needs no wallet signature.

See who is waiting. GET /api/v2/developer/apps/{appId}/installs lists the pages your app is installed on, the terms version each owner accepted, and each item's state there: selling, paused or new.

The page owner's acceptance ​

The owner of the coin page that installs your app is the seller of record of your items on that page. Adding your app shows the owner every item, its price, your share, Chain Daddy's fee and any install price, and the owner accepts those terms, with the Seller Terms signed, before the app goes on the page.

  • The page's store. Accepting opens a store on the page if it has none, on any plan, Free included. A store opened this way sells installed apps' items only.
  • Your share is locked on that page. No manager, and no store key, can change or remove your items there.
  • Uninstalling stops your app's sales on that page.

Install price ​

An install price is a one-time licence for one coin page, and here you are the seller. The page's owner pays it in USDC, and your payout wallet receives it less the fee. The licence stays with the page: uninstalling and installing again needs no new licence, and you may not revoke a licence. A page that has not bought one cannot install your app; the server refuses it.

A licence is paid in USDC, so it cannot be bought on a chain without a dollar stablecoin (Gnosis, Robinhood Chain's testnet). A coin page with no token contract cannot host an app that sells.

Selling in your app ​

Declare iap:purchase in your manifest and send iap-purchase, as any app selling from a page's store does. Your items are in the page's catalog, GET /api/v2/iap/public/stores?chainKey=…&crownId=…, each with appId (your app) and appItemKey (your itemKey). Buy one by its sku:

typescript
const store = await onAction({ type: 'api-call', method: 'GET', endpoint: `/api/v2/iap/public/stores?chainKey=${chainKey}&crownId=${crownId}` });
const pass = store.data.skus.find((s) => s.appItemKey === 'season-pass');
const res = await onAction({ type: 'iap-purchase', sku: pass.sku });
// res.data: { status: 'confirmed' | 'paid' | 'cancelled' | 'failed', orderId?, receipt? }
  • The page names your app, not you. The page records which app asked for each purchase; an appId your app sends is ignored. An app can buy only its own items, or the page's own.
  • The page's own items. Your app can also sell the items the page's owner sells. Those sales are attributed to your app and pay you no share.
  • Receipts. A receipt for an order made through an app adds appId, appItem (your itemKey, on your own items) and kind (item, licence or payment). They are absent on other receipts. Verifying receipts

The buyer sees Chain Daddy's purchase sheet, with your share of the price after the fee, and ticks that the sale is final before their wallet opens.

Selling from your app on a coin's site ​

A coin can put your app on its own verified site. Your app sells there with the same code: the same iap-purchase, the same store reads.

The switch. In the developer portal, open your app's Builds tab and turn on Sell from the app on coins' own sites. It is off until you turn it on, and your app also needs "embed": true.

  • The visitor pays in a Chain Daddy window. It names the site, the coin, your app and you, the item and your share, and asks the visitor to tick that the sale is final. When it is paid, your app hears confirmed (or paid) as on the coin's page.
  • Your share and limits do not change. The sale pays the same wallets as on the coin's page, at the price and share the coin accepted.
  • What does not work there: pay, iap-consume and paid files. An app that holds iap:consume or iap:pay, or ships paid files, does not run on other sites.
  • Turning it off stops new purchases at once, also a window already open: it says the checkout was stopped and nothing was charged.
  • Seeing these sales. They are in your sales and your webhook with surface embed and the site they were made on.

Selling on a coin's own website ​

A coin that installed your app can take payments on its own website with a checkout session: its server opens a session for one item, and the buyer pays on chaindaddy.io. Your items stay out of those sessions until you allow them, one item at a time.

The switch. In the developer portal, open your app's Paid tab, edit the item and tick Sell on coins' own websites. Or send it in the item PATCH:

bash
curl -X PATCH "https://api.chaindaddy.io/api/v2/developer/apps/$APP_ID/paid/items/season-pass" \
  -H "Authorization: Bearer $CD_API_KEY" -H "Content-Type: application/json" \
  -d '{"sellOutsideApp": true}'
#   → {"itemKey":"season-pass","sellOutsideApp":true,"termsVersion":1,…}
  • Off until you turn it on. Every item starts with sellOutsideApp false, and a session for it is refused with 409 APP_ITEM_NOT_SOLD_HERE.
  • What it allows. The owner of a page that has your app installed, and has accepted the item's current terms, can sell the item from the coin's own verified site. Nobody else can, and no other item of yours is affected.
  • Your share does not change. The sale pays the same wallets as a sale inside your app: the page, the fee, and your share at the price and share that page accepted. The fee is the one the page accepted. Your limits apply, and the buyer agrees on the checkout page that the sale is final.
  • Whatever stops your app selling stops this too. Your pause, an archived item, terms an owner has not accepted yet, an uninstall, or anything under When your app sells: the session is refused, and so is the order for a session opened earlier.
  • It is not a change of terms. Turning it on or off pauses nothing, asks no owner to accept anything and needs no wallet signature.
  • Turning it off. Untick it, or send {"sellOutsideApp": false}. New sessions and new orders stop at once. An order a buyer already started can still be paid until it expires, a few minutes later.
  • Seeing these sales. They are in your sales and your webhook like any other, with surface checkout_session and the site they were made on.

Paying people from your app ​

All value an app moves goes through the Chain Daddy checkout. To pay wallets (one player paying another, a tip, a payment to you), declare iap:pay and send the pay action. One checkout payment pays up to 3 wallets, in USDC or the page's token, and the fee comes out of each amount.

An app's transaction and sign-typed-data requests cannot move value: no coin, no token transfers, no approvals or permits (revoking one is allowed), and no signature that grants access to tokens.

Fees ​

The page that installed your appChain Daddy's fee
Its token launched in a Chain Daddy launchpad pool0%
Any other token2.5% of the gross

The fee applies to every sale an app makes, its items and install licences alike, and to every amount an app moves through the checkout with pay. It is the same rule as a creator's own store, keyed on the page that installed the app, and rounded down.

Two things pay no fee: buying and selling the page's token through Chain Daddy's trade sheet (quote), which is trading, and the built-in Tip app. A tip a third-party app sends goes through pay and pays the fee.

A page keeps the fee it accepted. The fee rate is part of the terms a page's owner accepts. A sale of your item, or of your install licence, on that page is charged the lower of that rate and today's rate. If the fee is raised later, your share and the page's share of sales there do not change until the owner accepts your terms again; if it is lowered, the lower rate applies everywhere at once. Amounts moved with pay are charged today's rate.

The fee and every share are paid on chain in the buyer's own transaction, straight to each wallet.

Limits ​

Chain Daddy may change any of these at any time, without notice. GET /api/v2/iap/config carries the current values in paidApps.

LimitValue
One purchaseAt most $250. An item priced above it cannot be saved
One buyer wallet, through one appAt most $1,000 in any 24 hours
A second confirmationAbove $50, the buyer presses and holds on Chain Daddy's purchase sheet
Units in one orderAt most 10
OrdersAt most 5 a minute per buyer wallet, per app
Token approvalsFor the exact order total, never unlimited

Chain Daddy can stop any app selling at once.

All sales are final ​

All sales are final, except where the law gives the buyer a right that cannot be waived. The purchase sheet says "Digital item, delivered immediately. All sales are final." and the buyer ticks it before their wallet opens. Chain Daddy never refunds. Paid apps have no refund flow, and you may not revoke an install licence.

What you can't sell ​

  • Anything with a chance-based outcome when it costs anything: loot boxes, mystery boxes, raffles, lotteries (Terms).
  • Anything presented as an investment, a return, a share of revenue, or an allocation, airdrop or presale of a token.

Items are items: they can't be transferred or exchanged for tokens, and they never pay anything back.

Your sales ​

Your app's Sales tab in the Developer Portal lists every sale made through it, newest first: the page, the kind (an item, a licence or a payment), the amount, the fee and your share.

Your share is recorded on each order when the order is made. It is the amount that order pays your payout wallet, in the currency the buyer paid in:

  • an item of yours on someone's page: your percentage of what is left after the fee;
  • an item of yours on a page whose payout wallet is your own: the whole payout;
  • a licence: the payout;
  • a payment: whatever part of it went to your payout wallet;
  • 0 when the order paid you nothing: an item at 0%, a payment to other people, or a page's own item bought through your app.

Changing your payout wallet later does not rewrite an old sale. Each sale keeps the wallet it paid, as developerAddress.

A sale made before shares were recorded on orders (October 2026) can show See transaction in place of a share. Its order did not record your share, and the order alone cannot tell it apart from the page's. Open the transaction to read what your wallet received.

You can read your sales, and your app's paid settings, even if you have not signed the current addendum or your developer access is suspended. Selling and changing anything still need both.

Totals and CSV ​

GET /api/v2/developer/apps/{appId}/sales/summary adds your sales up by day (UTC), chain, currency, coin page, item and where the buyer paid (surface: page, or checkout_session for a sale on a coin's own website).

bash
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.chaindaddy.io/api/v2/developer/apps/$APP_ID/sales/summary?from=2026-10-01&to=2026-10-31"
  • from and to are UTC days, both included. With neither, you get the last 30 days. One request covers at most 366 days.
  • Amounts are whole base units of each row's currency, never dollars. Divide by 10 to the power of currencyDecimals.
  • developerAmount is the sum of your recorded shares. ordersWithoutDeveloperAmount counts sales that did not record one.
  • refundedOrders counts sales the seller later recorded as refunded. They stay in the totals: the buyer's payment still reached your wallet.
  • Add format=csv for a download. Its columns are fixed, and new ones are only added at the end: date, chain, chain_id, crown_id, symbol, kind, item, surface, currency, currency_symbol, currency_decimals, orders, quantity, amount, fee_amount, developer_amount, orders_without_developer_amount, refunded_orders.

Check a sale against the chain ​

Every sale is paid by the buyer's own transaction, straight to each wallet. To confirm one yourself:

  1. Read the sale from GET /api/v2/developer/apps/{appId}/sales. It carries txHash, checkout (the contract that took the payment), logIndex, blockNumber, developerAddress, developerAmount and developerPayeeIndex.
  2. Open the transaction's receipt and find the OrderPaid log at logIndex. Accept it only if the log's address is checkout and its orderId is the sale's orderId.
  3. In that log, payees[developerPayeeIndex] is developerAddress and amounts[developerPayeeIndex] is your share. For a payment that paid your wallet more than once, add up every leg to your address; the total is developerAmount.

The payees run in a fixed order: the payout, the fee when there is one, then the rest. Verify a payment has the contract calls (hashOrder, paidBy) and the Solana steps. A share that is too small to be one whole unit of the currency is left off the order, and that sale reports 0.

Webhooks ​

To hear of each sale as it happens, add the event type app.order.confirmed to a webhook made with the wallet that owns the app. It is sent once for every order made through your app when the order is confirmed: an item, an install licence or a payment, on every page your app is installed on.

bash
curl -X POST https://api.chaindaddy.io/api/v2/webhooks \
  -H "X-API-Key: $CHAINDADDY_API_KEY" -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/hooks/sales","events":["app.order.confirmed"]}'
json
{
  "id": "app_evt_41",
  "type": "app.order.confirmed",
  "created_at": "2026-10-11T08:00:01Z",
  "data": {
    "eventId": 41,
    "kind": "item",
    "appId": "race-game",
    "itemKey": "pass",
    "sku": "app.0f0f0f0f.pass",
    "quantity": 1,
    "orderId": "0x9e1f…",
    "storeId": "11111111-2222-3333-4444-555555555555",
    "chainId": "eip155:8453",
    "chainKey": "base",
    "crownId": 8,
    "symbol": "FLUXGP",
    "buyer": "0x00000000000000000000000000000000000000b1",
    "amount": "1000000",
    "currency": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
    "currencySymbol": "USDC",
    "currencyDecimals": 6,
    "feeAmount": "25000",
    "usdMicros": 1000000,
    "developer": { "address": "0x00000000000000000000000000000000000000d1", "amount": "292500" },
    "surface": "page",
    "txHash": "0xabc…",
    "confirmedAt": "2026-10-11T08:00:00Z",
    "receipt": "eyJhbGciOiJFZERTQSIs…",
    "livemode": true
  }
}
FieldWhat it is
kinditem, licence or payment
appId, itemKeyYour app's id, and your item's key on an item of your own. itemKey is left out on a licence, a payment, and a page's own item sold through your app
chainId, chainKey, crownId, symbolThe page the order was made on
amount, currency, feeAmountWhat the buyer paid, in the currency's base units, and the fee taken from it
developerYour share: the wallet it was paid to and the amount, in base units. On an item it is your split; on a licence, the payout; on a payment, what was paid to one of your app's payout wallets. amount is "0" when the order paid you nothing
surfaceWhere the order was made: page (the coin's page), embed (your app on the coin's own site) or checkout_session (the coin's own site's server), which also carries checkoutSessionId. More values can be added
siteThe origin of the coin's own site the order was made on, such as https://shop.example.com; absent when surface is page
receiptThe order's signed receipt, or null when the order has none
idThe same on every retry and redelivery of one sale. Skip an id you have already handled
  • The webhook is yours, not the page's: the page's owner is never sent it, and you are sent only orders made through your app.
  • Check each delivery's signature as for any webhook: Check the signature.
  • A failed delivery is retried; a past one can be sent again. The Sales tab and GET …/sales stay the complete record.
  • A webhook's filter narrows it to some pages (crown_ids) or chains.
  • Webhooks need a plan that includes them (Webhooks). Orders on a test store are not sent.

API ​

Developer routes take your wallet session or a cd_live_ key. Changing anything needs program membership and the signed addendum. Reading (GET …/paid, …/sales and …/sales/summary) needs only that the app is yours.

RouteWhat it does
GET / PUT /api/v2/developer/apps/{appId}/paidPayout wallets and install price: {payoutAddressEvm, payoutAddressSolana, installPriceUsdMicros, walletSignature} (signed changes). GET also returns changes, the latest changes and who signed each
POST /api/v2/developer/apps/{appId}/paid/itemsAdd an item (the fields under Items)
PATCH / DELETE /api/v2/developer/apps/{appId}/paid/items/{itemKey}Change an item (a change to its price, currency or share takes walletSignature) / archive it. PATCH …?dryRun=1 says what a change would do and writes nothing (When you change an item)
GET /api/v2/developer/apps/{appId}/paid/sellingWhether the app sells now and, when it does not, why (reason), with your pause and where you stand on the addendum. Needs no signed addendum
PUT /api/v2/developer/apps/{appId}/paid/selling{"paused": true} stops the app selling everywhere; false resumes it. Needs no signed addendum
GET /api/v2/developer/apps/{appId}/installsThe pages your app is installed on, the terms each accepted, and each item's state there
GET /api/v2/developer/apps/{appId}/sales?cursor=Your sales: page, kind (item, licence or payment), amount, fee, your share, and where each settled (Your sales)
GET /api/v2/developer/apps/{appId}/sales/summary?from=&to=&format=Your sales added up by day, chain, currency, page, item and surface, as JSON or CSV (Totals and CSV)
GET /api/v2/developer/paid-apps-addendumThe addendum's text. /message gives the message to sign, /status whether you signed, and POST …/accept {version, issued_at, signature} records it

The page owner's side, which Chain Daddy's install sheet drives:

RouteWhat it does
GET /api/v2/apps/{slug}/install-terms?chainKey=…&crownId=…The terms a page sees: items, prices, shares, the fee, the install price, and whether the page accepted and holds a licence
POST /api/v2/apps/{slug}/install-terms/acceptThe owner accepts them, at install or again after you change them
GET /api/v2/paid-apps/pending-terms?chainKey=…&crownId=…The installed apps on a page whose terms changed since its owner accepted
POST /api/v2/apps/{slug}/licence-orders {chainKey, crownId}The owner buys the licence: an order like any other, paid the same way
AnswerWhen
403 PAID_APPS_ADDENDUM_REQUIREDYou have not signed the Paid Apps Addendum
403 WALLET_SIGNATURE_REQUIREDA money change without your wallet's signature. signing has {signer, message, nonce, issuedAt}: sign message, then send walletSignature: {signature, nonce, issuedAt, chainId?}
403 WALLET_SIGNATURE_INVALIDAnother wallet signed, the message expired, or it no longer matches the app. signing has a fresh message
403 WALLET_SIGNATURE_REPLAYEDThat signed message was already used. Send the change without walletSignature to get a new one
400 PRICE_ABOVE_LIMITAn item or install price above the per-purchase limit
409 APP_TERMS_REQUIREDInstalling an app that sells before its terms are accepted on that page
402 APP_LICENCE_REQUIREDInstalling an app with an install price before the page holds its licence
409 APP_TERMS_CHANGEDBuying an item whose terms changed and that page's owner has not accepted yet
403 APP_ITEM_NOT_YOURSAn app asking for another app's item
409 APP_NOT_INSTALLED / APP_NOT_SELLINGThe app is not on that page, or it is not selling there. APP_NOT_SELLING carries a reason: see When your app sells
400 FINAL_SALE_ACK_REQUIREDAn order through an app without the final-sale acknowledgement
409 APP_ITEM_NOT_SOLD_HEREA checkout session, or the order for one, for an item that cannot be sold from the coin's own site now. reason says why: not_allowed_outside_app (you have not turned it on), app_not_installed, terms_changed, item_not_for_sale, or an APP_NOT_SELLING reason. See Selling on a coin's own website
409 APP_ORDER_LIMIT / APP_DAILY_LIMIT, 429 APP_RATE_LIMITEDOver a limit