Skip to content

Start a Function API

A live API that sells answers, each priced per call by who works it out: a model in seconds, an agent in minutes.

You need Node 20 and a GitHub account. The sample answers on summaries.apis.dev; your first deploy answers at once on a free Host, and your own domain is one line.

  1. Start the folder

    Terminal
    $ npx apis.dev init function-api
    ✓ wrote definition.ts: a Function API
      next: npx apis.dev dev

    init writes a Function API that publishes as it is. This track builds a shorter one, with two Verbs.

  2. Write the file

    definition.ts
    16 lines
    import { define, generative, agentic } from 'apis.dev'
    
    /** Answers about any company by its domain: what it sells in seconds, its head of sales in minutes. */
    export default define({
      name: 'summaries', domain: 'summaries.apis.dev',
      Company: {                                    // Noun: the Noun it acts on
        domain:    'url!#',
        summarize: generative('Two sentences on what {domain} sells',
          { returns: { summary: 'string' } }),      // Verb: a model writes it
        research:  agentic('Find the head of sales at {domain}',
          { returns: { headOfSales: 'string' } }),  // Verb: an agent finds it
      },
      offer: {                                      // Offer: a price per call, by kind
        'Company.summarize': 0.02, 'Company.research': 0.5,
      },
    })

    Each Verb names its Function kind, and the kind sets how long it takes. returns types the answer on every Interface.

  3. Try it locally

    Terminal
    $ npx apis.dev dev
    ✓ every Interface on http://localhost:8787, against your Test twin
      reloads on every save

    Call each Verb on localhost before anyone pays for one. A model or an agent run in your Test twin spends your allowance, never a Customer's credits.

  4. Publish it

    Terminal
    $ npx apis.dev deploy
    ✓ signed in with GitHub
    ✓ definition.ts: summaries on summaries.apis.dev
    ✓ Stripe connected: each Customer pays into your own account
    ✓ 1 Noun, 2 Verbs, 2 prices
        Company  summarize, research
        Company.summarize  0.02 a call
        Company.research   0.5 a call
    ✓ published v1 to https://summaries.apis.dev: 11 Interfaces
        REST              /companies
        CLI               npx summaries
        MCP               /mcp
        SDK               npm i summaries, pip install summaries
        Docs              /docs
        OpenAPI           /openapi.json
        llms.txt          /llms.txt
        agents.json       /.well-known/agents.json
        Pricing           /pricing
        Landing site      /
        Developer portal  /dashboard
    ✓ Test key: summaries_test_t3EzMtZA2rs3DRNtaj3rv3JBPtcp4r647d42

    Deploy prints each Verb with its price. The first run signs you in with GitHub and connects Stripe to your own account.

  5. Read the price list

    /pricing
    9 lines
    {
      "currency": "USD",
      "rates": [
        { "name": "Company.summarize",
          "price": 0.02, "unit": "call" },
        { "name": "Company.research",
          "price": 0.5, "unit": "call" }
      ]
    }

    Your Customers and their agents read this before the first call, on /pricing and on the offer card.

  6. Call it with no credits

    POST summaries.apis.dev/companies/acme.com/summarize
    Request
    curl -X POST https://summaries.apis.dev/companies/acme.com/summarize \
      -H "Authorization: Bearer $SUMMARIES_KEY" \
      -H "Prefer: code=402"
    Response
    HTTP/1.1 402 Payment Required
    Content-Type: application/problem+json
    X-Cost: price=0, currency="USD"
    X-Request-Id: req_e01eab0d5cdfbb1619d4
    
    {
      "type": "https://summaries.apis.dev/docs/errors#payment_required",
      "title": "Payment Required",
      "status": 402,
      "detail": "The credit balance is 0; Company.summarize draws 0.02 from it.",
      "code": "payment_required",
      "instance": "req_e01eab0d5cdfbb1619d4",
      "offers": [
        {
          "kind": "credits",
          "price": 10,
          "checkout": "https://summaries.apis.dev/checkout/credits-10"
        },
        {
          "kind": "credits",
          "price": 50,
          "checkout": "https://summaries.apis.dev/checkout/credits-50"
        },
        {
          "kind": "credits",
          "price": 200,
          "checkout": "https://summaries.apis.dev/checkout/credits-200"
        }
      ]
    }

    A new Customer's first call answers 402 at price 0. Its offers are credit packs, each a Stripe Checkout link.

  7. Buy credits and call again

    POST summaries.apis.dev/companies/acme.com/summarize
    Request
    curl -X POST https://summaries.apis.dev/companies/acme.com/summarize \
      -H "Authorization: Bearer $SUMMARIES_KEY"
    Response
    HTTP/1.1 200 OK
    X-Cost: price=0.02, currency="USD"
    X-Request-Id: req_fa5075382229d67f1ce9
    
    {
      "id": "act_1",
      "verb": "Company.summarize",
      "status": "done",
      "output": { "summary": "Acme sells pipeline software to B2B sales teams." }
    }

    After Checkout, the same call answers with the summary, and X-Cost draws $0.02 from the credits.

  8. Ask for research

    Request
    curl -X POST https://summaries.apis.dev/companies/acme.com/research \
      -H "Authorization: Bearer $SUMMARIES_KEY"
    Response
    HTTP/1.1 202 Accepted
    Location: /actions/act_2
    Retry-After: 60
    X-Cost: price=0.5, currency="USD"
    X-Request-Id: req_0a6b1dbf299819cd7076
    
    {
      "id": "act_2",
      "verb": "Company.research",
      "status": "pending",
      "reason": "Running",
      "poll": "/actions/act_2"
    }

    An agent takes minutes, so the call answers 202 at once with an Action to poll. Its answer arrives stamped Inferred, and a failed Action costs nothing.

  9. Get paid

    Stripe receipt · October 2026 · USD
    Company.summarize 1,800 × 0.02    36.00
    Company.research     40 × 0.5     20.00
    ───────────────────────────────────────
    Total                             56.00
    Paid from 200.00 of credits       56.00
    Balance                          144.00

    Each Live call lands on your Customer's Stripe receipt, a line per Verb, and the money lands in your own Stripe account. This is one Customer's month.

Result

Your API answers on https://summaries.apis.dev: 2 Verbs, a model's answer at once for $0.02 and an agent's as an Action for $0.50.

Each is typed on every Interface. A call with no credits answers 402 with packs on Stripe Checkout, and a failed Action costs nothing. You wrote no prompt pipeline, no job queue and no metering.

Next steps

  • Start an Agent API → sell a worker instead of an answer, billed by what each run consumes.
  • Function API: the four kinds, one Verb behind several, and pricing by kind.
  • Runtime: the gate every call passes, and the Action every Verb answers.