# Ship an API

URL: /products/api/ship-an-api · Id: `guide:ship-an-api`

> Say "sell renewal dates as an API" and get routes, keys, an SDK, a CLI, an MCP server, reference docs and metered billing on Stripe.

An API is an [Interface](/business/nouns/interface) on the [Verbs](/business/nouns/verb) you choose, sold through a metered [Offer](/business/nouns/offer).

Needs: [Offer](/business/nouns/offer)

**Before real money moves**

- Who says yes: You. Your agent shows you the run and waits for your [Approval](/business/nouns/approval).
- You leave the chat: Once, at Stripe: to confirm who you are and add the bank account payouts land in.
- First question at Idea: “Free keys first, or a price from the first call?”

## What you get
- 1 API at api.leaseline.app, one route per Verb (Interface)
- 1 OpenAPI document, SDK, CLI and MCP server under your name (Interface)
- 1 reference docs and changelog on your domain (Site)
- 1 key screen and request log in the customer Portal (Portal)
- 1 Meter that counts calls per customer (Meter)
- 1 plan priced per call, with what it includes (Offer)
- 1 per-call price set up on Stripe (Price)
- 1 usage reported each hour and billed each month (Meter)

## Your agent does
**For agents**

- Guide: `guide:ship-an-api`, status `beta`. Page: [/products/api/ship-an-api.md](/products/api/ship-an-api.md).
- Approval: ask the founder first. Show the run, then wait for their Approval; a refusal ends it.
- Leaves the chat: Once, at Stripe: to confirm who you are and add the bank account payouts land in.
- Needs first: [Offer](/business/nouns/offer).
- Run: call the steps in order, each through the API, SDK, CLI or MCP tab below; a later step passes the `$id` an earlier one returns. Each value marked example is the sample business’s: pass the founder’s own.

| Step | Verb | Inputs (type, required, this guide’s value) | Returns |
| --- | --- | --- | --- |
| 1 | [`Interface.create`](/business/nouns/interface/create) (`verb:Interface.create`) | `kind` string, required: example `"api"`; `path` string: example `"/v1"` | `interface` Interface |
| 2 | [`Offer.publish`](/business/nouns/offer/publish) (`verb:Offer.publish`) | `offer` Offer (an id), required: example `"offer_api_per_call"` | `offer` Offer |

Returns: the last call answers with `offer` and its `action`, whose `status` is `done`, `pending` (waiting on an Approval or a Worker), `failed`, `canceled` or `refused`:

```json
{
  "api": "https://api.sb/leaseline.app",
  "offer": {
    "$id": "https://api.sb/leaseline.app/offers/offer_api_per_call",
    "$type": "Offer"
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/action_1",
    "operation": "Offer.publish",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/leaseline.app/actions/action_1"
  }
}
```

Next: offer “Give every key 1,000 free calls a month”, or “Add a $49 plan with 10,000 calls included”.

Calls: `Interface.create` → `Offer.publish`

Ask:

```text
Sell renewal dates as an API, a cent per call.
Give developers keys to read their leases.
Let agents call my product.
```

API:

```bash
# 1. Interface.create
curl -X POST https://api.sb/leaseline.app/interfaces \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"kind":"api","path":"/v1"}'

# 2. Offer.publish
curl -X POST https://api.sb/leaseline.app/offers/offer_api_per_call/publish \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```

SDK:

```ts
import { $ } from 'startup-builder'

await $.Interface.create({ kind: 'api', path: '/v1' })
await $.Offer.publish({ offer: 'offer_api_per_call' })
```

CLI:

```bash
npx startup-builder do Interface.create --json '{"kind":"api","path":"/v1"}'
npx startup-builder do Offer.publish --json '{"offer":"offer_api_per_call"}'
```

MCP:

```json
{
  "name": "do",
  "arguments": {
    "code": "await $.Interface.create({ kind: 'api', path: '/v1' })\nreturn await $.Offer.publish({ offer: 'offer_api_per_call' })"
  }
}
```

## Change it
- Give every key 1,000 free calls a month.
- Add a $49 plan with 10,000 calls included.
- Rate-limit the free plan to 10 calls a second.

## Under the hood
- Systems: [Customer access](/systems/customer-access), [Billing](/systems/billing), [Changelog](/code/systems/changelog)
- Nouns: [Interface](/business/nouns/interface), [Offer](/business/nouns/offer), [Meter](/business/nouns/meter), [Entitlement](/business/nouns/entitlement)
- Events: `Interface.created`, [`Offer.published`](/business/events/Offer.published)
- Stripe objects: `Product`, `Price`, `Billing Meter`, `Meter Event`