← Fee Stack
API
Tokens

Run Fee Stack from your own code

Both metered lanes are available over HTTP and each returns one JSON object. The division of labour: the page ranks the merchant-of-record posture, the fee instruments, the waivers and the payout cadence, computes the sale-to-bank days and the per-developer economics, and audits the tax split and the enforcement rules, then hands it all to the run as facts. The run writes the monetization design or the developer fee page; the page then holds it to its own facts (fsreply.js).

Base URL and the response shape

Every endpoint lives under https://api.skillsafe.ai/v1/app-api, and every response has one shape:

{ "ok": true,  "data":  { ... } }
{ "ok": false, "error": { "code": "...", "message": "..." } }

The token is minted for this app (the guest call takes {"slug":"fee-stack"}), so no slug header is needed afterwards. Send it as Authorization: Bearer YOUR_TOKEN. The run body is the input object, sent bare.

StatusCodeMeaning
400validation_errorThe body is not a JSON object, or a required key (task, marketplace, numbers, facts) is missing. The page always sends all five of task, marketplace, numbers, carry, facts; carry is an empty string for design.
401unauthorizedNo token, or a stale one. Mint a guest token or sign in again.
402insufficient_creditsThe balance is under min_credits. Price with /estimate first.
403forbiddenA guest token tried to run: both lanes are metered and need a personal sign-in.
404not_foundUnknown job id.
429rate_limitedBack off and retry.
5xxserver_errorTransient. Retry with the same Idempotency-Key so a retry never double-bills.

The task field comes first

Two lanes, chosen by task, in the order the work runs - the design the platform team implements, then the page developers read:

A missing or unknown task is answered as design. Both lanes send the same five fields. The facts are the page's checks, one row per line, and a line starting "must:" is a rule the reply has to hold. The page's handoff carries the design's decisions into carry for the page lane.

The input

FieldRequiredWhat
taskyesdesign or page. If it is missing or neither, do design and set "task": "design".
marketplaceyesthe marketplace, its take rate, the interview's answers and what it does today; "not given" means not given.
numbersyesthe pricing models against the rails, the payout days, the per-developer economics, the tax rows as jurisdiction | tax | owner | registered, and the page's issues in fix order.
carrysend it (empty for design)page task only: the design's decisions, when the design task ran first; may be empty.
factsyesthe page's checks, one line each as area | id | status | evidence, and the ranked menus. A line starting "must:" applies to your reply.
retry_notenooptional; if present, your previous reply was unusable - follow it.

The rules the model applies

From the source skill, @samber/app-marketplace-monetization-model - the only standard the run applies:

House rules

The replies

design

Write the monetization design the platform team implements, in the skill's order.

  1. summary - one sentence, at most 40 words: the posture, how the cut is collected, and the first thing to change.
  2. posture - rung (marketplace, developer or configurable, exactly as the facts rank it), tax, chargebacks, payouts (one sentence each: who owns it under this posture, naming the platform or developers).
  3. rails - one sentence: the account bundle (marketplace-shaped or SaaS-shaped) and what it means for the charge, the losses and the developer's dashboard.
  4. instruments - one object per instrument the facts list, in their order: instrument (share, program, processing or audited), collection (one sentence: how it is collected), enforcement (one sentence: what stops it being avoided). An empty list at zero take.
  5. pricing - one object per model in the input: model (flat, seat, usage, onetime or freemium), offered (yes only when developers want it and the rails support it, else no), note (one sentence).
  6. waivers - one object per waiver shape the facts list, in their order: shape (exemption, behavior or migration), rule (one sentence: the threshold or the choice it pays for, and automatic enrollment).
  7. payout - cadence (monthly, consolidated, rolling or none as the facts rank it), hold (one sentence), timeline (one sentence stating the longest sale-to-bank days exactly as the facts give them; when the cadence is none, say developers are paid by their own customers).
  8. tax - one object per tax row in the "must:" line, in its order: jurisdiction, tax, owner (platform or developer, exactly as the must line gives it).
  9. enforcement - circumvention (one sentence naming the delisting path), notice (one sentence: at least six months, unfavorable changes deferred). At zero take, say what changes when a rate is first charged.
  10. caveats - at most 4 short strings, always including that the tax split goes through counsel when there are tax rows; [] otherwise.
{
  "task": "design",
  "summary": "one sentence",
  "posture": { "rung": "marketplace", "tax": "one sentence", "chargebacks": "one sentence", "payouts": "one sentence" },
  "rails": "one sentence",
  "instruments": [ { "instrument": "share", "collection": "one sentence", "enforcement": "one sentence" } ],
  "pricing": [ { "model": "flat", "offered": "yes", "note": "one sentence" } ],
  "waivers": [ { "shape": "exemption", "rule": "one sentence" } ],
  "payout": { "cadence": "monthly", "hold": "one sentence", "timeline": "one sentence" },
  "tax": [ { "jurisdiction": "United States", "tax": "sales tax", "owner": "platform" } ],
  "enforcement": { "circumvention": "one sentence", "notice": "one sentence" },
  "caveats": [ ]
}

The page holds it to its own facts (check() in fsreply.js; any warning makes the reply flagged): the reply answers the task it was sent; no URL; no backticks; a summary of at most 40 words; no percentage the input never gives; no single tax toggle; the ranked posture with tax, chargebacks and payouts each owned; the instruments, waivers and payout cadence exactly as ranked and in order; every pricing model listed, none offered that the rails cannot bill; the longest sale-to-bank days in the timeline; every tax row with the owner law and posture require; a delisting path and at least six months' notice when a rate is charged; a caveat sending the tax split to counsel.

page

Write the developer-facing fees and payouts page the marketplace publishes - plain, specific, in the second person ("you").

  1. summary - one sentence, at most 40 words: what the page commits to.
  2. title - a short page title.
  3. intro - two sentences: who bills your customers and how you get paid.
  4. fees - objects: fee (a short name), amount (only an amount the input gives - the take rate as a percentage, the processing percentage - else "to be set"), when (one sentence: when it is charged or deducted). Include the revenue share when the take rate is above zero, one row per tier the input states; never at zero take.
  5. payouts - two or three sentences: the cadence, the hold, the minimum payout when the input gives one, and the honest longest sale-to-bank days exactly as the facts give them; or, when developers bill their own customers, that you are paid by them directly.
  6. tax - one object per tax row in the "must:" line, in its order: jurisdiction, tax, who (platform or developer, exactly as the must line gives it).
  7. waiver - one or two sentences: the threshold and that eligible developers are enrolled automatically; "None" when there is no waiver.
  8. notice - one sentence: fee changes come with the notice the facts give in months, in writing.
  9. caveats - at most 4 short strings for the platform team (not shown to developers), including that the tax split goes through counsel; [] when there is nothing to say.
{
  "task": "page",
  "summary": "one sentence",
  "title": "Fees and payouts",
  "intro": "two sentences",
  "fees": [ { "fee": "Revenue share", "amount": "15%", "when": "one sentence" } ],
  "payouts": "two or three sentences",
  "tax": [ { "jurisdiction": "United States", "tax": "sales tax", "who": "platform" } ],
  "waiver": "one or two sentences",
  "notice": "one sentence",
  "caveats": [ ]
}

The page requires: the reply answers the task it was sent; the same text rules; a revenue-share fee at the take rate (none at zero take); every amount one the input gives, else to be set; the longest sale-to-bank days, or that developers are paid by their own customers; every tax row with its required owner; the notice in months; the waiver's threshold with automatic enrollment; a caveat sending the tax split to counsel.

Worked examples

Three runs from the page's free samples (invented marketplaces): the design for a marketplace charging 20% while developers still bill, the developer page for the same marketplace carrying that design, and the design for on-invoice billing with a tax hole. Each input is exactly what the page sends; each reply is the saved reply the sample replays, shipped unedited - but the facts and long strings are shortened in this display only, and every cut is listed under the example. The last line is the page's own check of the full reply.

design - A 20% cut developers still collect themselves

The page read it as: money leaks or obligations nobody holds; 20% take; posture marketplace; longest sale to bank 80 days; 1 of 5 gates; failing checks: posture, timeline, taxsplit, facilitator, circumvention, notice, ownership, instrumentsGate, publishedGate, taxsafeGate.

Input (numbers is 1463 characters; the first 1391 are shown; facts is 3813 characters; the first 1396 are shown):

{
 "task": "design",
 "marketplace": "Marketplace: Kestrova\nWhat it sells and to whom: A field-service management platform; partners sell scheduling, parts and invoicing apps to contractor businesses.\nTake rate: 20%; tiers: 20% on all paid-app revenue; decided: yes\nBills these customers on a recurring cycle already: no; billing engineering: A managed payment-rails provider; buyers: US and the EU; consumer buyers: no; losses carried by: the platform; developer-billed apps that cannot migrate in one cycle: no\nToday: Developers bill their own customers; payouts Monthly cycle plus a hold window; processing shown separately: no; anti-circumvention rule: no; delisting path: no; notice for fee changes: 3 months\nWaiver today: annual threshold $500k, enrollment manual; a choice to steer developers toward: no; off-marketplace revenue to migrate: no; small developers bound by cash flow: no; competing for supply with faster payers: no\nDeadline: no; a compounding asset; effort ceiling: medium",
 "numbers": "Pricing models (model | developers want it | rails support it):\n- Flat subscription | yes | yes\n- Per-seat | yes | yes\n- Usage-based | no | NO\n- One-time | yes | yes\nPayout days: cycle 30, hold 45, bank 5 - sale to bank 50 to 80 days; published 30 days; minimum payout $100\nPer active developer a month: sales $4,200, cut $840, rails fees $2.25 (account $2.00 + 1 payouts x $0.25), net $838 across 180 developers: $151k; processing 2.9%\nTax split (jurisdiction | tax | owner | registered):\n- United States | sales tax | DEVELOPER | NO\n- EU | VAT | UNASSIGNED | not given\n- United Kingdom | VAT | DEVELOPER | yes\nIssues in fix order: posture - developers bill their own customers while the marketplace charges 20% - promote to marketplace-billed and collect at source; circumvention - no rule against routing billing around the marketplace - circumvention pressure rises with the rate; notice - 3 months of notice - the sourced pattern is six, with unfavorable changes deferred; processing - processing cost sits inside the share - the share reads as a higher take than it is; optin - eligible developers must enroll - a qualifying developer who misses the paperwork silently pays the full rate; default them in; timeline - you publish 30 days; a sale can take 80 (cycle 30 + hold 45 + bank 5); taxsplit - EU VAT - nobody named; facilitator - United States sales tax - marketplace-facilitator\n\n[... 72 more characters cut from this display ...]",
 "carry": "",
 "facts": "The page's checks (10 fail, 2 warn, 3 pass, 3 n/a); verdict: money leaks or obligations nobody holds:\n- The four menus | strategy | pass | 20% - 20% on all paid-app revenue\n- The four menus | posture | fail | Marketplace-billed (platform as merchant of record) - charging 20% - collect at source; only the marketplace-billed posture does not depend on developers reporting their own revenue; no legacy population - the configurable posture leaves the discussion; today: developers bill their own customers while the marketplace charges 20% - promote to marketplace-billed and collect at source\n- The four menus | instruments | na | Revenue share netted at source > Flat program fees (registration, review, listing) > Processing pass-through, a separate labeled line - marketplace-billed - the audited self-reported share is deleted\n- The four menus | waivers | warn | Revenue-exemption tier > Behavior-based discount - no back-book to migrate - the migration incentive is deleted; a $500k threshold - the sourced programs cluster at $1M; eligible developers must enroll - a qualifying developer who misses the paperwork silently pays the full rate; default them in\n- The four menus | cadence | na | Monthly cycle plus a hold window > Rolling payouts with reserves - no existing invoice cycle - consolidation is deleted\n- The four menus | menu | pass | Flat subscription, Per-seat, One-time - each\n\n[... 2417 more characters cut from this display ...]"
}

Reply (long strings shortened for display - see the cuts below):

{
 "task": "design",
 "summary": "Move Kestrova to marketplace-billed so the platform is merchant of record and nets the 20% share at source; first, take billing off developers, who bill their own customers today while the marketplace charges 20%.",
 "posture": {
  "rung": "marketplace",
  "tax": "The platform owns collection and remittance where the law puts it on the marketplace, including US sales tax and EU VAT, while developers keep United Kingdom VAT.",
  "chargebacks": "The platform owns chargebacks and disputes as merchant of record, which matches the losses it already carries today.",
  "payouts": "The platform pays developers their net earnings after the share and processing are deducted, instead of developers collecting from their own customers."
 },
 "rails": "Use a marketplace-shaped account bundle on the managed payment-rails provider, so the platform charges the contractor business, carries refunds and disputes, and each developer sees sales, deductions and pending payouts in a [... 81 more characters cut from this display]",
 "instruments": [
  {
   "instrument": "share",
   "collection": "The 20% revenue share on all paid-app revenue is deducted from each sale before the payout is calculated, so nothing depends on developers reporting their own revenue.",
   "enforcement": "A written anti-circumvention rule forbids routing billing for a listed app around the marketplace, with warning, suspension and delisting as the path for repeat breaches."
  },
  {
   "instrument": "program",
   "collection": "Any registration, review or listing fee, amount to be set, is charged only where it prices a real review cost or filters low-intent submissions, and is invoiced at submission.",
   "enforcement": "Listing review is gated on the fee being paid, so an unpaid submission never reaches the catalog."
  },
  {
   "instrument": "processing",
   "collection": "Processing at 2.9% is deducted as its own labeled line on every payout statement, taken out of the share so the share reads as the true 20% take.",
   "enforcement": "Because it is netted at source alongside the share, it falls under the same anti-circumvention rule and delisting path."
  }
 ],
 "pricing": [
  {
   "model": "flat",
   "offered": "yes",
   "note": "Developers want flat subscriptions and the rails support them, so offer them at launch."
  },
  {
   "model": "seat",
   "offered": "yes",
   "note": "Per-seat pricing fits contractor teams and the rails support it, so offer it at launch."
  },
  {
   "model": "usage",
   "offered": "no",
   "note": "The rails do not support usage-based billing and developers have not asked for it, so leave it off the menu."
  },
  {
   "model": "onetime",
   "offered": "yes",
   "note": "One-time purchases are wanted and supported, so offer them for apps sold without a subscription."
  }
 ],
 "waivers": [
  {
   "shape": "exemption",
   "rule": "Raise the revenue-exemption threshold from $500k toward the $1M the sourced programs cluster at, keep the annual reset, and enroll every eligible developer automatically instead of requiring them to apply."
  },
  {
   "shape": "behavior",
   "rule": "Hold a behavior-based discount, rate to be set, for a named choice the platform wants to steer developers toward; none is named today, so it stays unused until one is chosen, and qualifying developers are enrolled automatically."
  }
 ],
 "payout": {
  "cadence": "monthly",
  "hold": "Keep the monthly cycle with an explicit 45-day hold window, and treat the hold as the lever to shorten if developers push back, not the $100 minimum payout.",
  "timeline": "Publish the honest timeline: a sale can take up to 80 days to reach the developer's bank (cycle 30 + hold 45 + bank 5), not the 30 days published today."
 },
 "tax": [
  {
   "jurisdiction": "United States",
   "tax": "sales tax",
   "owner": "platform"
  },
  {
   "jurisdiction": "EU",
   "tax": "VAT",
   "owner": "platform"
  },
  {
   "jurisdiction": "United Kingdom",
   "tax": "VAT",
   "owner": "developer"
  }
 ],
 "enforcement": {
  "circumvention": "Add a rule that a listed app may not move billing for marketplace customers off the marketplace, backed by a written delisting path of warning, suspension and removal from the catalog.",
  "notice": "Raise fee-change notice from 3 months to at least six months in writing, with unfavorable changes deferred to the end of the notice and favorable ones applied early."
 },
 "caveats": [
  "The jurisdiction-by-jurisdiction tax split goes through qualified counsel before it ships; it is not tax advice.",
  "US sales tax registration is not in place today; register before collecting, since calculation without registration collects nothing.",
  "Developers who bill their own customers today need a migration plan to marketplace billing.",
  "Program fee and behavior discount amounts are to be set."
 ]
}

Cut from this display only (the saved reply and the check use the full text): rails (305 characters, 224 shown).

What step 5 prints for it: share | program | processing | marketplace

The page's check: kept - nothing to flag

page - A 20% cut developers still collect themselves

The input carries the saved design (R.laneForm fills carry from the design reply), as the page's handoff does. The issues in fix order: posture, circumvention, notice, processing, optin, timeline, taxsplit, facilitator.

Input (numbers is 1463 characters; the first 1391 are shown; facts is 3748 characters; the first 1396 are shown; carry is 2214 characters; the first 1399 are shown):

{
 "task": "page",
 "marketplace": "Marketplace: Kestrova\nWhat it sells and to whom: A field-service management platform; partners sell scheduling, parts and invoicing apps to contractor businesses.\nTake rate: 20%; tiers: 20% on all paid-app revenue; decided: yes\nBills these customers on a recurring cycle already: no; billing engineering: A managed payment-rails provider; buyers: US and the EU; consumer buyers: no; losses carried by: the platform; developer-billed apps that cannot migrate in one cycle: no\nToday: Developers bill their own customers; payouts Monthly cycle plus a hold window; processing shown separately: no; anti-circumvention rule: no; delisting path: no; notice for fee changes: 3 months\nWaiver today: annual threshold $500k, enrollment manual; a choice to steer developers toward: no; off-marketplace revenue to migrate: no; small developers bound by cash flow: no; competing for supply with faster payers: no\nDeadline: no; a compounding asset; effort ceiling: medium",
 "numbers": "Pricing models (model | developers want it | rails support it):\n- Flat subscription | yes | yes\n- Per-seat | yes | yes\n- Usage-based | no | NO\n- One-time | yes | yes\nPayout days: cycle 30, hold 45, bank 5 - sale to bank 50 to 80 days; published 30 days; minimum payout $100\nPer active developer a month: sales $4,200, cut $840, rails fees $2.25 (account $2.00 + 1 payouts x $0.25), net $838 across 180 developers: $151k; processing 2.9%\nTax split (jurisdiction | tax | owner | registered):\n- United States | sales tax | DEVELOPER | NO\n- EU | VAT | UNASSIGNED | not given\n- United Kingdom | VAT | DEVELOPER | yes\nIssues in fix order: posture - developers bill their own customers while the marketplace charges 20% - promote to marketplace-billed and collect at source; circumvention - no rule against routing billing around the marketplace - circumvention pressure rises with the rate; notice - 3 months of notice - the sourced pattern is six, with unfavorable changes deferred; processing - processing cost sits inside the share - the share reads as a higher take than it is; optin - eligible developers must enroll - a qualifying developer who misses the paperwork silently pays the full rate; default them in; timeline - you publish 30 days; a sale can take 80 (cycle 30 + hold 45 + bank 5); taxsplit - EU VAT - nobody named; facilitator - United States sales tax - marketplace-facilitator\n\n[... 72 more characters cut from this display ...]",
 "carry": "Posture: marketplace - tax: The platform owns collection and remittance where the law puts it on the marketplace, including US sales tax and EU VAT, while developers keep United Kingdom VAT. Chargebacks: The platform owns chargebacks and disputes as merchant of record, which matches the losses it already carries today. Payouts: The platform pays developers their net earnings after the share and processing are deducted, instead of developers collecting from their own customers.\nInstruments: share (The 20% revenue share on all paid-app revenue is deducted from each sale before the payout is calculated, so nothing depends on developers reporting their own revenue.); program (Any registration, review or listing fee, amount to be set, is charged only where it prices a real review cost or filters low-intent submissions, and is invoiced at submission.); processing (Processing at 2.9% is deducted as its own labeled line on every payout statement, taken out of the share so the share reads as the true 20% take.)\nPricing offered: flat, seat, onetime\nWaivers: exemption - Raise the revenue-exemption threshold from $500k toward the $1M the sourced programs cluster at, keep the annual reset, and enroll every eligible developer automatically instead of requiring them to apply.; behavior - Hold a behavior-based discount, rate to be set, for a named choice the platform wants to steer developers\n\n[... 815 more characters cut from this display ...]",
 "facts": "The page's checks (10 fail, 2 warn, 3 pass, 3 n/a); verdict: money leaks or obligations nobody holds:\n- The four menus | strategy | pass | 20% - 20% on all paid-app revenue\n- The four menus | posture | fail | Marketplace-billed (platform as merchant of record) - charging 20% - collect at source; only the marketplace-billed posture does not depend on developers reporting their own revenue; no legacy population - the configurable posture leaves the discussion; today: developers bill their own customers while the marketplace charges 20% - promote to marketplace-billed and collect at source\n- The four menus | instruments | na | Revenue share netted at source > Flat program fees (registration, review, listing) > Processing pass-through, a separate labeled line - marketplace-billed - the audited self-reported share is deleted\n- The four menus | waivers | warn | Revenue-exemption tier > Behavior-based discount - no back-book to migrate - the migration incentive is deleted; a $500k threshold - the sourced programs cluster at $1M; eligible developers must enroll - a qualifying developer who misses the paperwork silently pays the full rate; default them in\n- The four menus | cadence | na | Monthly cycle plus a hold window > Rolling payouts with reserves - no existing invoice cycle - consolidation is deleted\n- The four menus | menu | pass | Flat subscription, Per-seat, One-time - each\n\n[... 2352 more characters cut from this display ...]"
}

Reply:

{
 "task": "page",
 "summary": "Kestrova bills your customers, deducts a 20% revenue share and 2.9% processing as separate lines, pays you monthly after a 45-day hold within 80 days of a sale, and gives six months' written notice of fee changes.",
 "title": "Fees and payouts",
 "intro": "Kestrova bills the contractor businesses that buy your app, as merchant of record, and handles refunds and disputes. We deduct our fees from each sale and pay the rest into your bank account on a monthly cycle.",
 "fees": [
  {
   "fee": "Revenue share",
   "amount": "20%",
   "when": "Deducted from each paid-app sale before your payout is calculated."
  },
  {
   "fee": "Payment processing",
   "amount": "2.9%",
   "when": "Deducted from each sale and shown as its own line on your payout statement, separate from the revenue share."
  },
  {
   "fee": "Registration, review or listing fee",
   "amount": "to be set",
   "when": "Charged when you submit an app for review, if one applies."
  }
 ],
 "payouts": "We pay out once a month, after a 45-day hold window on each sale. Counting the 30-day cycle, the 45-day hold and up to 5 days for your bank, a sale can take up to 80 days to reach your account. The minimum payout is $100.",
 "tax": [
  {
   "jurisdiction": "United States",
   "tax": "sales tax",
   "who": "platform"
  },
  {
   "jurisdiction": "EU",
   "tax": "VAT",
   "who": "platform"
  },
  {
   "jurisdiction": "United Kingdom",
   "tax": "VAT",
   "who": "developer"
  }
 ],
 "waiver": "If your paid-app revenue stays under the $500k annual threshold, the revenue share is waived, and the threshold resets each year. You are enrolled automatically when you qualify; there is nothing to apply for.",
 "notice": "We give you at least 6 months' written notice before any fee change, and changes that cost you more take effect only after that notice.",
 "caveats": [
  "The tax split goes through qualified counsel before this page ships; it is not tax advice.",
  "Register for US sales tax before collecting, since it is not registered today.",
  "Decide whether to raise the $500k threshold toward $1M before publishing, and set or drop the program fee.",
  "Publish the anti-circumvention rule and its delisting path alongside this page."
 ]
}

What step 5 prints for it: Revenue share 20% | Payment processing 2.9% | Registration, review or listing fee to be set

The page's check: kept - nothing to flag

design - On-invoice billing with a tax hole

The page read it as: money leaks or obligations nobody holds; 15% take; posture marketplace; longest sale to bank 39 days; 4 of 5 gates; failing checks: menu, economics, silent, taxsafeGate.

Input (facts is 3758 characters; the first 1394 are shown):

{
 "task": "design",
 "marketplace": "Marketplace: Pixmoor\nWhat it sells and to whom: A design and creative-tools platform; developers sell plugins to studios and to individual creators on the platform's own monthly invoice.\nTake rate: 15%; tiers: 0% on the first $1M lifetime, 15% above; decided: yes\nBills these customers on a recurring cycle already: yes; billing engineering: A managed payment-rails provider; buyers: US, the EU and beyond; consumer buyers: yes; losses carried by: the platform; developer-billed apps that cannot migrate in one cycle: no\nToday: The marketplace bills; payouts Rolling payouts with reserves; processing shown separately: yes; anti-circumvention rule: yes; delisting path: yes; notice for fee changes: 6 months\nWaiver today: lifetime threshold $1M, enrollment auto; a choice to steer developers toward: yes; off-marketplace revenue to migrate: no; small developers bound by cash flow: yes; competing for supply with faster payers: yes\nDeadline: no; a compounding asset; effort ceiling: high",
 "numbers": "Pricing models (model | developers want it | rails support it):\n- Flat subscription | yes | yes\n- Usage-based | yes | NO\n- One-time | yes | yes\n- Free with paid tiers | yes | yes\nPayout days: cycle 7, hold 30, bank 2 - sale to bank 32 to 39 days; published 39 days; minimum payout $50.00\nPer active developer a month: sales $15.00, cut $2.25, rails fees $3.08 (account $2.00 + 4.33 payouts x $0.25), net -$0.83 across 2400 developers: -$1,998; processing 2.9%\nTax split (jurisdiction | tax | owner | registered):\n- United States | sales tax | PLATFORM | yes\n- EU | VAT (B2C) | PLATFORM | NO\n- United Kingdom | VAT | PLATFORM | yes\n- Australia | GST | DEVELOPER | not given\nIssues in fix order: economics - per active developer each month the cut is $2.25 and the rails' flat fees are $3.08 - below $20.55 of monthly sales a developer costs more than it pays; menu - Usage-based - wanted, but the rails cannot bill it; verify before publishing the menu; silent - EU VAT (B2C) - automatic calculation with no registration collects $0, raises no error and cannot be corrected later",
 "carry": "",
 "facts": "The page's checks (4 fail, 0 warn, 10 pass, 4 n/a); verdict: money leaks or obligations nobody holds:\n- The four menus | strategy | pass | 15% - 0% on the first $1M lifetime, 15% above\n- The four menus | posture | na | Marketplace-billed (platform as merchant of record) - charging 15% - collect at source; only the marketplace-billed posture does not depend on developers reporting their own revenue; no legacy population - the configurable posture leaves the discussion; you already bill these customers on a cycle - consolidate app charges onto that invoice\n- The four menus | instruments | na | Revenue share netted at source > Flat program fees (registration, review, listing) > Processing pass-through, a separate labeled line - marketplace-billed - the audited self-reported share is deleted\n- The four menus | waivers | na | Behavior-based discount > Revenue-exemption tier - a specific pricing or architecture choice to steer - a behavior-based discount moves up; no back-book to migrate - the migration incentive is deleted; a $1M threshold - on the sourced anchor\n- The four menus | cadence | na | Rolling payouts with reserves > Invoice-cycle consolidation > Monthly cycle plus a hold window (+ instant as an option) - an existing invoice cycle - payouts ride the settlement you already run; you compete for supply against faster-paying alternatives - rolling payouts with reserves;\n\n[... 2364 more characters cut from this display ...]"
}

Reply (long strings shortened for display - see the cuts below):

{
 "task": "design",
 "summary": "Pixmoor stays marketplace-billed and nets its 15% share at source on its own monthly invoice; first, register for EU VAT (B2C) before collecting it, then fix per-developer economics where flat rails fees exceed the cut.",
 "posture": {
  "rung": "marketplace",
  "tax": "The platform, as merchant of record, owns the sales tax and VAT it is liable for, while developers keep Australia GST under the published split.",
  "chargebacks": "The platform owns chargebacks and carries the losses, because it is the seller on every plugin charge.",
  "payouts": "The platform pays developers their net proceeds after the share, the processing line and any reserve are deducted."
 },
 "rails": "The managed payment-rails provider runs a marketplace-shaped bundle: the platform makes the charge on its invoice, carries the losses, and each developer gets a connected account and payout dashboard whose $2.00 monthly account fee and [... 97 more characters cut from this display]",
 "instruments": [
  {
   "instrument": "share",
   "collection": "The 15% revenue share is netted from each plugin sale on the platform invoice before the developer's payout is calculated, at 0% on a developer's first $1M lifetime.",
   "enforcement": "The terms forbid steering buyers to pay off-platform for a listed plugin, and a breach leads to delisting through the written path already in the terms."
  },
  {
   "instrument": "program",
   "collection": "Flat registration, review or listing fees, amount to be set, are charged only where they price the real cost of review and account upkeep or filter low-intent submissions.",
   "enforcement": "A plugin is not reviewed or listed until its program fee is paid, so the fee cannot be skipped."
  },
  {
   "instrument": "processing",
   "collection": "Processing at 2.9% is passed through as its own labeled line on each payout statement, never folded into the 15% share.",
   "enforcement": "It is deducted at source from every marketplace charge, so it cannot be avoided, and it shares the anti-circumvention rule and delisting path that protect the share."
  }
 ],
 "pricing": [
  {
   "model": "flat",
   "offered": "yes",
   "note": "Developers want flat subscriptions and the rails bill them on the platform's monthly invoice."
  },
  {
   "model": "usage",
   "offered": "no",
   "note": "Developers want usage-based pricing but the rails cannot bill it, so keep it off the published menu until that is verified."
  },
  {
   "model": "onetime",
   "offered": "yes",
   "note": "One-time purchases are wanted and supported by the rails."
  },
  {
   "model": "freemium",
   "offered": "yes",
   "note": "Free plugins with paid tiers are wanted and supported, with only the paid tier carrying the share."
  }
 ],
 "waivers": [
  {
   "shape": "behavior",
   "rule": "A discount on the share, amount to be set, pays developers for the specific pricing or architecture choice the platform wants to steer them toward, applied automatically to every plugin that makes it."
  },
  {
   "shape": "exemption",
   "rule": "The share is 0% on a developer's first $1M of lifetime sales and 15% above, with every eligible developer enrolled automatically and the lifetime basis stated explicitly."
  }
 ],
 "payout": {
  "cadence": "rolling",
  "hold": "Payouts roll on a 7-day cycle after a 30-day hold, with a reserve held back against chargebacks and refunds, and instant payout offered only as a paid option on top, fee to be set.",
  "timeline": "Publish the honest sale-to-bank timeline of 32 to 39 days, stated as 39 days at the longest, with the 30-day hold named as the main part of the wait."
 },
 "tax": [
  {
   "jurisdiction": "United States",
   "tax": "sales tax",
   "owner": "platform"
  },
  {
   "jurisdiction": "EU",
   "tax": "VAT (B2C)",
   "owner": "platform"
  },
  {
   "jurisdiction": "United Kingdom",
   "tax": "VAT",
   "owner": "platform"
  },
  {
   "jurisdiction": "Australia",
   "tax": "GST",
   "owner": "developer"
  }
 ],
 "enforcement": {
  "circumvention": "Keep the rule against moving listed plugin sales off the platform invoice, backed by the delisting path already written into the developer terms.",
  "notice": "Give at least six months of written notice for any fee change, defer unfavorable changes to the end of that window, and apply favorable ones early."
 },
 "caveats": [
  "The tax split is not tax advice and goes through qualified counsel before it ships.",
  "EU VAT (B2C) is owned by the platform but not registered, so automatic calculation collects nothing until registration is done.",
  "Below $20.55 of monthly sales a developer costs more in rails fees than the cut brings in.",
  "Usage-based pricing stays off the menu until the rails are verified to bill it."
 ]
}

Cut from this display only (the saved reply and the check use the full text): rails (332 characters, 235 shown).

What step 5 prints for it: share | program | processing | marketplace

The page's check: kept - nothing to flag

Build the input yourself

Load the engine in node (global.window = global; require("./fskit.js"); require("./fsreply.js")), then:

const K = FeeKit, R = FeeReply;
const f = K.form(Object.assign(K.blank(), { name: "Acme", take: "15", posture: "developer",
  tax: "United States | sales tax | developer | no" }));
// f.postureR, f.instrumentR, f.waiverR, f.cadenceR (the ranked menus), f.timeline, f.economics, f.taxRows, f.issues (in fix order), f.gate
// K.scheduleMd(f), K.taxCsv(f) - the fee schedule and the tax split
const b = K.buildInput(f, "design");                         // or "page" (R.laneForm(form, "page", design) fills carry)
const wire = K.toWire(b.input);                              // POST this to /estimate and /run
// then: const reply = R.normalize(R.parseReply(job.output.output), "design");
// R.check(reply, b)                                         // {status: kept or flagged, notes}

Get a token for the steps below from /tokens.html.

Step 1 — a tiny client helper

One function that sends JSON and unwraps the response. Paste a personal token from /tokens.html, or leave it empty and mint a guest token in step 2.

BASE="https://api.skillsafe.ai/v1/app-api"
TOKEN="YOUR_TOKEN"   # from https://fee-stack.skillsafe.ai/tokens.html
api() { # api METHOD PATH [JSON-BODY]
  curl -s -X "$1" "$BASE$2" -H "Content-Type: application/json" \
    ${TOKEN:+-H "Authorization: Bearer $TOKEN"} ${3:+--data "$3"}
}

Step 2 — a token

A guest token is enough for /me and /estimate. A run is metered, so it needs a personal token: sign in on /tokens.html and copy it from there.

# a guest token (enough for /me and /estimate); a run needs your personal token from /tokens.html
TOKEN=$(curl -s -X POST "$BASE/guest" -H "Content-Type: application/json" -d '{"slug":"fee-stack"}' | jq -r '.data.token')

Step 3 — GET /me

Who the token is (subject_type: user or guest) and the credit balance.

api GET /me | jq '.data | {subject_type, credits}' 

Step 4 — POST /estimate

Free. The body is the run input itself, the bare object (never wrapped in {"input": ...}). hold_credits is a reservation, not the price; min_credits is what the balance must cover; model_alias reads gpt-terra.

# input.json: the run input object - {"task": "design", "marketplace": "Marketplace: Kestrova
What it sells and to whom: ...", "numbers": "Pricing models (model | developers want it | rails support it):
- Flat subscription | yes | yes ...", "carry": "", "facts": "The page's checks (...); verdict: money leaks or obligations nobody holds:
- The four menus | strategy | pass | ..."}
# - see the input table
api POST /estimate "$(cat input.json)" | jq '.data | {hold_credits, min_credits, model, model_alias, markup_bps, warnings}' 

Step 5 — POST /run, then poll the job

Send an Idempotency-Key built from the lane and the input: a retry with the same key never bills twice. The page uses fee-stack:<task>:<inputHash>:a<attempt> - the lane is part of the key, retry_note is left out of the hash - and its one automatic reformat retry is a new attempt number, named in the page as one extra run. A design reply carries summary, posture, rails, instruments, pricing, waivers, payout, tax, enforcement and caveats; a page reply carries summary, title, intro, fees, payouts, tax, waiver, notice and caveats. The code below prints the gist of either: each fee instrument and how it is collected, or each fee and its amount.

KEY="fee-stack:$(jq -r .task input.json):$(shasum -a 256 input.json | cut -c1-16):a1"
JOB=$(curl -s -X POST "$BASE/run" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $KEY" --data @input.json | jq -r '.data.job_id')
while :; do
  J=$(api GET "/jobs/$JOB"); S=$(echo "$J" | jq -r '.data.status')
  case "$S" in succeeded|failed|cancelled) break;; esac; sleep 2
done
echo "$J" | jq -r '.data.output.output' > reply.json   # one JSON object, the reply contract
echo "$J" | jq '.data | {charged_credits, truncated}'
jq -r 'if .task == "page" then (.fees[] | "\(.fee): \(.amount)") 
       else (.instruments[] | "\(.instrument): \(.collection)") end' reply.json

Step 6 — POST /run-stream

The same run as Server-Sent Events, with the same input.json. Browsers receive progress ticks rather than text deltas; the final done event carries the reply.

# Server-Sent Events: tick/delta events while the job runs, then a final event with the job
curl -N -s -X POST "$BASE/run-stream" -H "Content-Type: application/json" -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: fee-stack:$(jq -r .task input.json):$(shasum -a 256 input.json | cut -c1-16):a1" --data @input.json