---
title: "Agent calls, streams and bulk jobs"
url: /interfaces/invocation
---

# Agent calls, streams and bulk jobs

> The shapes a call takes past one request: agent-to-agent calls as Actions, output streamed as it is written, bulk jobs, large files and SDK releases.

A call takes more shapes than one request and reply: another agent's call, a stream, a job over millions of inputs, a large file.

**Every shape is one Action.** A call in any shape.

1. Accepted: an Action id. Or refused: with a cure.
2. Working (the gate passes): Running. Or input needed: with a reason.
3. Streaming (stream: true): output as written.
4. Done (the run ends): output kept whole.
5. Artifacts (attached): files and records.

An agent-to-agent call, a stream and a bulk job each answer one Action, priced and kept like any call.

## Shapes past one request
Each shape below answers one [Action](/workflow.md#the-lifecycle), so its states, its price and its record are the ones every call has.

| Family | What it does |
| --- | --- |
| Agent-to-agent calls | Another agent sends work over the agent-to-agent protocol at `/a2a`; each call runs as an Action, and the [agent card](/patterns/agent-api.md) names the Verbs it accepts |
| The agent card and the offer card | The agent card carries the offer card whole, with the skills, input schemas and the rung each Verb accepts, so the two never disagree |
| Streamed output | A generative or agentic Verb with `stream: true` sends its output as it is written: server-sent events over HTTP, progress over MCP, an iterator in the SDK |
| Resume | A cut stream resumes from its last event id; the output is kept whole on the Action once the run ends |
| Bulk jobs | One Verb over a file of inputs, up to the limit [the envelope](/runtime/envelope.md#families) sets: progress, partial results as a file, and a cancel |
| Bulk prices | Each input priced as one call, `Max-Cost` caps the whole job, and a miss or a refused row costs nothing |
| Large files | Resumable uploads, piece by piece, links that expire for downloads, and ranges, on any `file` field |
| The SDK | Generated in each language `sdk.languages` names, published under your own registry name with each deploy, typed from the file |
| SDK releases | Semantic versions: the major is the API's [Version](/reference/platform.md#version), a minor each additive deploy, a patch a docs or type fix, each with its changelog |

| Agent-to-agent state | The Action it is |
| --- | --- |
| `submitted`, `working` | `pending`, `Running` |
| `input-required` | `pending`, with the reason `AwaitingInput` and what it needs |
| `auth-required` | `pending`, `AwaitingApproval`, or a 401 that names the missing rung |
| `completed` | `done`, with its output; each artifact is an output field or a file |
| `canceled` | `cancelled`, by `Action.cancel` on any [Interface](/every-product.md) |
| `failed`, `rejected` | `failed`, or refused with its [Problem](/reference.md#errors) |

### Example
Summaries stream as they are written, and the SDK ships in three languages under the seller's own name.

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

/** Two sentences on what any company sells, written as you watch. */
export default define({
  name: 'summaries', domain: 'summaries.apis.dev',
  Company: {
    domain: 'url!#',
    summarize: generative('Two sentences on what {domain} sells',
      { returns: { summary: 'string' }, stream: true }),
  },
  offer: { 'Company.summarize': 0.02 },
  sdk: { languages: ['typescript', 'python', 'go'], scope: '@summaries' },
})
```

The reply streams the summary as the model writes it, then the done Action.

```http title="Response"
HTTP/1.1 200 OK
Content-Type: text/event-stream
X-Cost: price=0.02, currency="USD"
X-Action-Id: act_5
X-Request-Id: req_1c6e0a94d3b28f75e4a2

id: 1
event: output
data: {"summary": "Acme sells industrial sensors"}

id: 2
event: output
data: {"summary": " and the software that reads them."}

id: 3
event: done
data: {"id": "act_5", "status": "done"}
```

That is `POST /companies/acme.com/summarize` with `Accept: text/event-stream`, `summarizeCompany` over MCP with progress, and an iterator in the SDK.

## Calls, jobs and releases, state by state
Each is a Thing the caller reads by Verb, and each move writes its Event.

| Thing | States | What moves it |
| --- | --- | --- |
| An agent-to-agent call | The Action's: `pending`, then `done`, `failed` or `cancelled` | The run; the calling agent sends input or cancels by the same protocol |
| A stream | `open`, `sending`, then `done`; or `cut`, then `resumed` | The run, and the client's connection; the Action holds the whole output either way |
| A bulk job | `uploaded`, `checking`, `running`, then `done`, `partial` or `cancelled` | Each row is checked, then run; a partial job lists every failed row with its Problem |
| An upload | `started`, `uploading`, then `stored` or `expired` | Each part; an upload left unfinished expires after a day |
| An SDK release | `built`, `published`, `deprecated` | Each deploy builds and publishes it; it is deprecated with its Version's sunset, and stays installable |

## What callers, agents and developers meet
- **Another agent.** It reads the agent card, sends work by its own protocol, gets input requests and artifacts back, and cancels like any caller.
- **A person watching.** Text that appears as it is written, and the same text kept on the Action.
- **A data team.** One job for millions of inputs, its progress, its partial results and one price per row.
- **A developer.** The SDK in its own language, under the seller's name, with a version that says what changed.

---

Every shape a call takes is one Action with one price, so an agent's call, a stream and a job are kept and proved alike.