---
title: "Function API"
url: /patterns/function-api
---

# Function API

> Sell an answer, priced per call.

**One Verb, three kinds: `Company.classify`.**

- A call is quoted at $0.04 and tries code first.
- When code's answer fails the check, a model tries; when the model's fails, a person does.
- Whichever kind passes answers the one [Action](/workflow.md#the-lifecycle), and $0.04 is charged.
- A person's task unclaimed in 24 hours fails the Action at no charge.

A Function API sells an answer computed when asked. Each Verb names its [Function](/reference/platform.md#function) kind, which sets how long the answer takes and what it costs you. The caller sees one Verb, one price and one [Action](/reference/platform.md#action), whichever kind does the work.

```ts title="definition.ts"
import { define, code, generative, agentic, human, escalate } from 'apis.dev'
import { sectorFromTable } from './sectors'

/** Answers about any company by its domain, from a score in milliseconds to a person's check in hours. */
export default define({
  name: 'summaries', domain: 'summaries.apis.dev',
  Company: {
    domain:    'url!#',
    score:     code((c) => ({ score: c.domain.endsWith('.ai') ? 80 : 50 })),     // computes
    summarize: generative('Two sentences on what {domain} sells',                 // writes
      { returns: { summary: 'string' } }),
    research:  agentic('Find the head of sales at {domain}',                      // researches
      { returns: { headOfSales: 'string' } }),
    verify:    human('Call and confirm the head of sales',                        // decides
      { role: 'researcher', within: '24h', returns: { confirmed: 'boolean' } }),
    classify:  escalate([                                                         // one Verb, three kinds
      code(sectorFromTable),
      generative('The sector {domain} sells into, from the list'),
      human('Read the site and pick the sector', { role: 'researcher', within: '24h' }),
    ], { returns: { sector: 'string' }, check: (out) => out.sector !== 'unknown' }),
  },
  Text: {                                                                         // on no stored Noun
    translate: generative('Translate {text} into {to}',
      { input: { text: 'string', to: 'string' }, returns: { text: 'string' } }),
  },
  offer: {
    'Company.score': 0.001, 'Company.summarize': 0.02,
    'Company.research': 0.5, 'Company.verify': 5,
    'Company.classify': 0.04,                    // one price, whichever kind answers
    'Text.translate': 0.01,
  },
})
```

## The four kinds
| Kind | What it does | How long | What runs it | In `summaries` | [Price](/reference/platform.md#price) |
| --- | --- | --- | --- | --- | --- |
| Code | computes | milliseconds | your function, isolated per call | `Company.score` | $0.001 |
| Generative | writes | seconds | a prompt through the model router | `Company.summarize` | $0.02 |
| Agentic | researches, with tools | minutes | an agent whose every tool call passes the gate | `Company.research` | $0.5 |
| Human | decides | hours or days | a task in a [Role](/reference/platform.md#role)'s queue | `Company.verify` | $5 |

`returns` types the output on every [Interface](/every-product.md): the Action, the MCP `outputSchema`, OpenAPI and the SDK. A generative or agentic answer is stamped Inferred, and a person's answer Stated, so the caller knows the basis of every value.

| Thing | States | What moves it |
| --- | --- | --- |
| An Action | `pending` with its reason, then `done`, `failed` or `cancelled`; `refused` never starts | The kind's work, a cancel, or a check at the gate |
| A rung of a ladder | `tried`, then `passed` or `failed`, and a failed rung hands on to the next | The Verb's `check` on the rung's output |
| A person's task | `open`, `claimed`, `done`; or `expired` | A worker in the Role claims and answers it; `within` lapses it, and the Action fails at no charge |
| A model call | `routed`, then `answered`, or `fell_back` to the next model | The model router; the caller sees one answer and one price |

## Escalation
`escalate` puts several kinds behind one Verb, cheapest first. Each rung runs only when the one before fails the Verb's `check`, so a person sees only the hard calls. The rungs are private: the caller sees the Action, its reason while it waits, and the [Provenance](/patterns/dataset-api.md#how-a-field-is-filled) of the answer.

A domain the table and the model both miss reaches a researcher. The call answers at once, and the Action waits on the person.

```sh title="Request"
curl -X POST https://summaries.apis.dev/companies/obscure.io/classify \
  -H "Authorization: Bearer $SUMMARIES_KEY" \
  -H "Max-Cost: 0.10"
```

```http title="Response"
HTTP/1.1 202 Accepted
Location: /actions/act_4
Retry-After: 3600
X-Cost: price=0.04, currency="USD"
X-Request-Id: req_3e81c0d47a9b52f61e07

{
  "id": "act_4",
  "verb": "Company.classify",
  "status": "pending",
  "reason": "AwaitingWorker",
  "until": "2026-10-28T09:00:00Z",
  "poll": "/actions/act_4"
}
```

When the researcher answers, the Action is `done` with `"provenance": "Stated"`, and its receipt names the [Version](/reference/platform.md#version) and the price. Unclaimed by `until`, it fails and the reserved price is released.

## Pricing by kind
Each Verb has its own price per call. A failed or cancelled Action costs nothing, and a call above its `Max-Cost` is refused before it runs.

An escalating Verb has one price. When a call climbs to a dearer rung, you carry the difference, and the caller pays the same $0.04.

Deploy prints your margin at the rate each rung was reached over the last 10,000 calls, or at the [Test twin](/reference/platform.md#test-twin)'s estimate at first. A price below that cost is refused with [`below_cost`](/reference/platform.md#below_cost).

```sh title="Terminal"
$ npx apis.dev deploy
✓ Company.classify  0.04  · code 100% · generative 30% · human 1% · cost 0.0213 · margin 47%
✓ published v4 to https://summaries.apis.dev
```

The print is yours alone. As the model takes more hard calls, the human rate falls and your margin rises at the same price.

## Contracts and the platform's part
A Verb needs only its kind and `returns` to be served, typed, metered and priced on every Interface. A prompt runs through the model router, which falls back on a failure and can use a Customer's own model key. An agentic Verb's tools are your Verbs and [Sources](/patterns/dataset-api.md#how-a-field-is-filled), each call through the gate.

A human Verb raises a task in its Role's queue, routed by skill and credential and lapsed at `within`.

A Function API draws on every subsystem:

- **Definition and compile** checks the kind per Verb and the ladder at deploy.
- **Identity, access and policy** gives [Keys](/reference/platform.md#key), mandates for agent callers, and the Role and credential a human Verb needs.
- **Model and records** gives the Noun a Function acts on, and fills fields from a Verb's latest output.
- **Data and Sources** supplies what a prompt or an agent reads, at each Source's `cost`.
- **Runtime** runs the four kinds, the model router, the gate and the Action.
- **Work** gives the human kind its tasks, queues and leases.
- **Commerce** reserves the price at the gate, captures it on `done`, releases it on a failure, and refunds by rule.
- **Interfaces and distribution** gives one MCP tool and one SDK method per Verb, and `quote` on the offer card.
- **Trust and operations** runs evals per kind, judges success and latency from outside, and traces every rung.

## What Customers and their agents meet
A person sees each price on `/pricing` before calling, and pays nothing for a failed or lapsed Action. An agent buys the same answer with no UI:

1. It reads the offer card: price per Verb, success rate and median time, judged from outside.
2. It calls `classifyCompany` over MCP with `Max-Cost`, under its mandate.
3. It subscribes to the Action and resumes on `done`, with no polling.
4. It keeps the signed receipt, and disputes with it when the answer misses the terms.

| Pattern | Noun: the shape you promise | Verb: what can be done to it | Source: where its data comes from | Trigger: what reacts to a change | Offer: the price |
| --- | --- | --- | --- | --- | --- |
| [Function API](/patterns/function-api.md): Sell an answer, priced per call. A Function writes it. | the Noun it acts on | a Function: code, a model, an agent or a person | — | — | a price per call, by kind; a failure is free |