---
title: "A product's life"
url: /lifecycle
---

# A product's life

> A product from before its first Function to after its last call: pre-orders and the interest list, what it tells you, growth, sunset, transfer and export.

A product's life runs from before its first [Function](/patterns/function-api.md) to after its last call: prove demand, learn, grow, then close, transfer or leave.

**One product, start to end.** An Offer and a price.

1. Pre-orders: funds held. Or returned: window missed.
2. Delivered (work runs): by hand or code.
3. Learn (every call): what callers did.
4. Grow (the next move): plans and seats.
5. Sunset (you decide): notice first. Or transfer: to a workspace.
6. Closed (notice runs out): record kept.

Each stage is a state of the product, moved by a Verb and written as an Event.

## Before it exists
An Offer sells before any work runs: a pre-order is an outcome whose funds are held until delivery, and returned if it misses its window.

Until a Function runs the Verb, a person in your Role makes the delivering move by hand. Customers see the same Verb, price and receipt either way.

Every unmet call, pre-order and sign-up joins the interest list, in order. When a [Version](/reference/platform.md#version) that runs the Verb deploys, each entry is told and pre-orders are delivered first.

```ts title="definition.ts"
import { define } from 'apis.dev'

/** A researched lead list for any market, delivered within 30 days or refunded. */
export default define({
  name: 'leads', domain: 'leads.io.sb',
  roles: { analyst: {} },
  LeadList: {
    market: 'string', size: 'number',
    status: {
      order: [],
      deliver: { in: 'ordered', role: 'analyst' },   // by hand until a Function runs it
      accept: 'delivered', reject: 'delivered',
    },
  },
  offer: {
    'LeadList.order': { price: 49, when: 'accepted', accept: 'customer', acceptWithin: '7d',
                        remedy: 'refund', deliverWithin: '30d' },   // funds held until then
  },
})
```

## What your product tells you
Each signal is a projection or an Event rebuilt from the record. Deciding what to try next runs outside the product, on these.

| Signal | What it shows | Where it matters most |
| --- | --- | --- |
| Callers | Who calls, through which [Interface](/every-product.md) and agent client, and how often | Every pattern |
| Unmet asks | Misses, empty searches and Verbs asked for that the product lacks, by input | [Dataset API](/patterns/dataset-api.md), [Function API](/patterns/function-api.md) |
| The funnel | Visit, Try it, sign-up, first call and first payment, by day and by where each came from | Every pattern |
| Agents that passed | Each agent that read the offer card or met a 402 and stopped, with its reason class | Every pattern |
| Revenue | Revenue, margin and cost to serve by Verb, plan and Customer; recurring revenue and churn by cohort | [Headless SaaS](/patterns/headless-saas.md), Content |
| Work | First-time acceptance, redo rate, cycle time and cost per step | [Service API](/patterns/service-api.md), Marketplace |
| Runs | What each run consumed against its ceiling, and the brakes it tripped | [Agent API](/patterns/agent-api.md) |

The buy side reports each card it ranked and passed over, with its reason class: `price`, `proof`, `terms`, `mandate` or `refused`. It never names the buyer. [Model and records](/model/analytics.md#analytics) rebuilds every row above.

## Growth, one move at a time
Growth is a Customer or an agent taking the next move the Offer already sells, and each move writes an Event.

| Move | What it writes | What brings it |
| --- | --- | --- |
| First call to first payment | `Balance` enters `funded` | The 402's offers: a pack through Checkout, or a payment in the call |
| A pack to a plan | `Subscription` enters `trialing` or `active` | A plan whose `includes` covers the calls the Customer already makes |
| More seats | `Subscription.updated` | A member invited past the plan's seats, at its `seat` price |
| A commitment | An agreement enters `signed` | A [commitment](/commerce/agreements.md#commitments) with its ramps and true-up |
| An agent buying again | A receipt under a standing mandate | Clean receipts, a track record that clears the buyer's policy, and the same terms digest |

An agent buys again while its standing mandate names the seller and the card clears its policy. A changed terms digest sends that choice back to its person.

## The end: sunset, close and transfer
A Live product ends with a sunset and its notice, then closes. Or it moves whole to another workspace by transfer.

| Thing | States | What moves it |
| --- | --- | --- |
| A product | `test`, `live`, `sunsetting`, `closed`; or `archived`, `transferred` | `Environment.promote`; `Product.sunset`; `Product.close` once the notice has run; `Product.archive` for one never Live; an accepted transfer |
| A transfer | `offered`, then `accepted`, `declined` or `expired`; an accepted one ends `moved` | `Product.transfer`; `Transfer.accept` by the receiving [workspace](/trust/account.md)'s owner; the move on the agreed date |

| Part of a sunset | What happens |
| --- | --- |
| Notice | Every Customer and Watch is told at once, on the product's channels, at least `operate.sunset` before the close |
| Headers | Every reply carries `Deprecation` and `Sunset` for the product |
| Sign-ups | No new Customers, [Keys](/reference/platform.md#key) or pre-orders; current Customers keep calling |
| Money | Unspent credits are refunded at the close; held funds return unless their work is delivered |
| Open work | Cases, runs and orders already started run to their end |
| Directories | Every directory entry is withdrawn, and the offer card says `sunsetting` |
| Export | Each Customer exports its [Namespace](/reference/platform.md#namespace) until the close, and for 30 days after |
| The Domain | Released at the close; the free [Host](/reference/platform.md#host) answers with the notice |

A transfer keeps all a Customer sees: Host, Domains, Keys, prices, receipt keys and records. Customers get 30 days' notice, and both workspaces write an Event.

## Leaving APIs.Dev
A product leaves with everything it is: `Product.export` writes the file, every Version, every record and the sales record.

| What you take | How it keeps working |
| --- | --- |
| The file and every Version | `definition.ts` and each compiled [Definition](/reference/platform.md#definition), with OpenAPI, the SDK source and the docs as Markdown |
| Each Customer's records | One export per Namespace, with full history and files |
| The sales record | Every sale, refund, fee and tax line, matched to Stripe, where the money already is |
| Your Domains | Yours to point elsewhere; the free Host forwards for 90 days |
| Keys | Exported as digests, so whatever serves next checks every Key without holding one |
| Receipt keys | Still listed at `/.well-known/receipt-keys`, so every receipt keeps verifying |
| Package names | Published under your own names, which stay yours |

---

A product's life is a chain of states with a Verb for each move, from the first pre-order to the export after its close.