---
title: "Objects"
url: https://services.dev/docs/reference/objects
---
# Objects

URL: https://services.dev/docs/reference/objects

> Every prefixed id a brand hands out, what it names and the fields it carries, then each live object as a real run served it.

16 objects. Every id a brand hands out starts with its object's prefix. Every object carries the same envelope, and a yes marks each envelope field it carries.

| Prefix | Object | What it is | `id` | `object` | `livemode` | `metadata` | Explained in |
|---|---|---|---|---|---|---|---|
| `job_` | [`job`](https://services.dev/docs/reference/objects.md#job) | a job | yes | yes | yes | yes | — |
| `stp_` | [`step`](https://services.dev/docs/reference/objects.md#step) | a step run on a job | yes | yes | — | — | — |
| `tsk_` | [`task`](https://services.dev/docs/reference/objects.md#task) | a Task: a role step a Pool fills, at a fee fixed at post, open, held, claimed and done | yes | yes | yes | — | [Tasks: offered, never assigned](https://services.dev/docs/people/pool/tasks.md), [The packet](https://services.dev/docs/people/pool/packet.md) |
| `ask_` | [`ask`](https://services.dev/docs/reference/objects.md#ask) | an ask: a party acts through its hosted, single-use link | yes | yes | yes | — | [Ask the buyer](https://services.dev/docs/grow/ask.md), ['Asks: a ceremony without an account'](https://services.dev/docs/service/ask.md) |
| `sbj_` | [`subject`](https://services.dev/docs/reference/objects.md#subject) | a subject: what outlives the job, keyed by an input or a receipt, with its jobs, its history, its kept facts, its periods and who is of record | yes | yes | yes | — | [Subjects](https://services.dev/docs/service/subject.md), [Of record](https://services.dev/docs/people/of-record.md) |
| `clk_` | [`clock`](https://services.dev/docs/reference/objects.md#clock) | a clock: a date the world sets on a job or its subject, who answers for it, its rungs, what moves it and the owner's choice at the end. Its owner acknowledges it, satisfies it on evidence and chooses at its date | yes | yes | yes | — | [Clocks](https://services.dev/docs/service/clocks.md) |
| `msg_` | `message` | a message in a job's thread: who said it, what it answers, its status (sent, held, adopted, declined), and its words, which the client reads | yes | yes | yes | — | — |
| `sbn_` | [`subscription`](https://services.dev/docs/reference/objects.md#subscription) | a subscription: standing work charged once per cycle, its schedule and events minting jobs that share its subject and policy, and its allowances used and included, reset at renewal. `sbn_`, not `sub_`, so it never reads as a subject (`sbj_`) | yes | yes | yes | yes | [Subscriptions](https://services.dev/docs/money/subscriptions.md), [Schedules and triggers](https://services.dev/docs/service/subscriptions.md) |
| `evt_` | [`event`](https://services.dev/docs/reference/objects.md#event) | an event: one record fact in the brand's ordered feed, with its seq, as its audience sees it | yes | yes | yes | yes | — |
| `wh_` | [`watch`](https://services.dev/docs/reference/objects.md#watch) | a watch: a webhook endpoint, with its whsec_ secret, its events and its deliveries | yes | yes | yes | — | — |
| `mbr_` | [`member`](https://services.dev/docs/reference/objects.md#member) | a member: a person in a Pool, their application, what the verifier wrote and their availability; never their ledger | yes | yes | yes | yes | — |
| `po_` | `payout` | a payout: a member's pay leaving for their account on the Pool's schedule | yes | yes | yes | yes | — |
| `ch_` | `charge` | a charge: the buyer's payment for a job, held until its release fact, then captured | yes | yes | yes | yes | — |
| `rcp_` | [`receipt`](https://services.dev/docs/reference/objects.md#receipt) | an outside receipt: a submission's status, codes, number and file | yes | yes | yes | — | [File it somewhere](https://services.dev/docs/grow/submit.md), [Sending to outside systems](https://services.dev/docs/service/submit.md) |
| `dlg_` | `delegated_key` | a delegated key: a party's grant to an agent, scoped by Service and time | yes | yes | yes | — | — |
| `tc_` | [`test_clock`](https://services.dev/docs/reference/objects.md#test_clock) | a test clock: the time every job on it reads, frozen until advanced, only ever forward | yes | yes | yes | — | [On a test clock](https://services.dev/docs/service/timers.md#on-a-test-clock) |
| `tmr_` | `timer` | a timer: one kind of time, owed once, with its key, its state, owed and fired times, attempt, wakes and the version it was armed under | yes | yes | yes | — | [Every timer is on the record](https://services.dev/docs/service/timers.md#every-timer-is-on-the-record) |

## Each object, its fields and as served

Each object: its fields, then the object as a brand serves it. A field marked `?` can be left out.

### The envelope

What these fields mean, on every object that carries them:

| Field | Says |
|---|---|
| `id` | Its id, starting with its object’s prefix. |
| `object` | The object’s name, such as `clock`: what an agent dispatches on. |
| `livemode` | `true` for an object a live key made, `false` for a test key's. |
| `created` | When it was made, an ISO 8601 instant. |
| `simulated` | `true`: every answer in the sandbox says so. |

### `job`

The canonical job, mid-flight and as a buyer reads it: waiting, on signature, its payment held. Each of its 4 `steps` is a `step` object.

| Field | Type | Says |
|---|---|---|
| `id` | `JobId` | — |
| `object` | `'job'` | — |
| `created` | `string` | When it was ordered. |
| `livemode` | `boolean` | False on localhost and with a test key: no real money moves. |
| `simulated` | `true` | Every answer in the sandbox says so. |
| `service` | `string` | — |
| `input` | `Record<string, unknown>` | — |
| `metadata` | `Record<string, unknown>` | The buyer's own keys, echoed as ordered. |
| `price` | `JobPrice` | — |
| `payment` | `Payment` | Where the buyer's money stands now. |
| `human` | `string` | The human sentence. |
| `stage` | `string \| null` | The stage buyers see: the `stage`, or the name, of the step that last committed. |
| `policy?` | `Record<string, unknown>` | The order's policy, every default filled, when the Service has one. |
| `from?` | `JobId \| SubId` | The ended job this one was ordered again from, or the subscription that minted it. |
| `test_clock?` | `TcId` | The test clock it runs on, when the order attached one. |
| `rules?` | `string` | The rules version the job was ordered under, when its Service pins a table. Every attestation on it carries the same one. |
| `posture?` | `'full' \| 'self'` | Its posture, when the Service takes one: 'full', or 'self' when the client performs the acts the rules allow. |
| `subject?` | `SbjId` | The subject it joined, once its key is known: sbj_…. |
| `reservations?` | `{ step: string; member: string; path: string; sha256: Hash }[]` | Each qualified attestation's reservation: part of the deliverable, by its file and hash. |
| `steps` | `StepRun[]` | — |
| `asks?` | `Ask[]` | Its asks, once a step has asked a party to act. |
| `grants?` | `Grant[]` | Its grants, once a party has given one: each one's scope, when it was given, until when, and whether it is live, expired or revoked. |
| `receipts?` | `Receipt[]` | Its receipts, once a submit step has sent something outside. |
| `clocks?` | `ClockObject[]` | The clocks it reads, once a due date is known: its own, and its subject's. |
| `record` | `JobEvent[]` | The whole record: the owner's evidence, AI decisions, proposals, refusals and findings included. Only the owner reads it (GET /owner/jobs/:id, the export); a buyer's surfaces strip it, and a buyer reads `timeline` instead, with expand[]=timeline. |
| `timeline?` | `Event[]` | The events of this job a buyer may read, oldest first: only with expand[]=timeline. |
| `next` | `Next[]` | — |

The `status` narrows the rest: `waiting` adds `on` and `waiting`, `delivered` and `accepted` add `output` and `final_at`, `canceled` adds `reason`, and `ended` adds `end` and `output`. A buyer never reads `record`: their surfaces strip it, and `expand[]=timeline` adds `timeline`.


```txt
$ curl http://localhost:8787/jobs/job_7Hq3   # input, price and next left out; a buyer never reads the record
{
  "id": "job_7Hq3",
  "object": "job",
  "created": "2026-10-25T14:02:11.000Z",
  "livemode": false,
  "service": "certified-translation",
  "status": "waiting",
  "on": "signature",
  "waiting": {
    "on": "signature",
    "since_at": "2026-10-25T14:02:11.000Z"
  },
  "stage": "review",
  "payment": {
    "status": "held",
    "amount_usd": 189
  },
  "metadata": {
    "docket": "ACME-17"
  },
  "steps": [
    {
      "id": "stp_1",
      "object": "step",
      "step": "translate",
      "by": "service",
      "status": "committed",
      "hash": "sha256:9f8b9e2d7105702e9ad4e23a6a3480b908bf95c4126db2cf2da2925b9a932c09"
    },
    {
      "id": "stp_2",
      "object": "step",
      "step": "review",
      "by": "ai",
      "review": "adversarial",
      "verdict": "pass",
      "status": "committed",
      "hash": "sha256:7872030adc5ce4f6451657cad35f9270ecd255bb13c720b66287e8aa6f990c5f"
    },
    {
      "id": "stp_3",
      "object": "step",
      "step": "sign",
      "by": "sworn translator",
      "status": "waiting"
    },
    {
      "id": "stp_4",
      "object": "step",
      "step": "certify",
      "by": "ai",
      "status": "pending"
    }
  ]
}
```

### `step`

A step run on a job.

| Field | Type | Says |
|---|---|---|
| `id` | ``stp_${number}`` | — |
| `object` | `'step'` | — |
| `step` | `string` | — |
| `by` | `string` | `ai`, `code`, `url`, `service`, or a person's role. |
| `review?` | `Review` | — |
| `lenses?` | `number` | — |
| `status` | `'pending' \| 'working' \| 'waiting' \| 'committed' \| 'skipped'` | — |
| `submit?` | `string` | A submit step's outside system. |
| `stage?` | `string` | — |
| `hash?` | `Hash` | — |
| `verdict?` | `'pass' \| 'flagged'` | — |
| `ask?` | `AskId` | An ask step's latest ask. |
| `task?` | `TskId` | A role step's Task. |


### `task`

A Task: a role step a Pool fills, at a fee fixed at post, open, held, claimed and done.

| Field | Type | Says |
|---|---|---|
| `id` | `TskId` | — |
| `object` | `'task'` | — |
| `livemode` | `false` | — |
| `pool` | `string` | — |
| `role` | `string` | — |
| `status` | `TaskStatus` | — |
| `fields` | `Record<string, unknown>` | The fields the Pool's `sees.teaser` chose: Task facts only (act, region, fee_usd, signals, kind, service, step, role). |
| `est?` | `Est` | Minutes of work, and where the estimate comes from; absent when neither the step nor its history gives one. |
| `hourly_usd?` | `number` | The fee per estimated hour, in dollars: only with an estimate. |
| `due` | `string` | — |
| `held_until?` | `string` | A claimed Task's hold: theirs until then. |
| `refused?` | `{ code: string; reason: string; at: string }` | — |
| `outcome?` | `Outcome` | — |
| `simulated` | `true` | — |

A member reads a Task as its teaser until it is theirs: `fields` holds only what the Pool’s `sees.teaser` names, never a party. The sheet, the packet and the owner’s read are the same Task with more: [The packet](#packet) below, and `GET /owner/tasks/:id`.


```txt
→ GET /reviews/tsk_7Hq2   # as mbr_eligible: the teaser
{
  "id": "tsk_7Hq2",
  "object": "task",
  "livemode": false,
  "pool": "attorneys",
  "role": "practitioner",
  "status": "open",
  "fields": {
    "act": "sign",
    "region": "*",
    "fee_usd": 150,
    "signals": []
  },
  "est": {
    "minutes": 60,
    "from": "step"
  },
  "hourly_usd": 150,
  "due": "2026-10-30T14:02:11.000Z",
  "simulated": true
}
```

### `ask`

An ask: a party acts through its hosted, single-use link.

| Field | Type | Says |
|---|---|---|
| `id` | `AskId` | — |
| `object` | `'ask'` | — |
| `job` | `JobId` | — |
| `step` | `string` | — |
| `to` | `AskAct` | — |
| `party` | `Asked` | — |
| `what_hash` | `Hash \| null` | — |
| `status` | `AskStatus` | — |
| `expires_at` | `string` | — |
| `url` | `string \| null` | — |
| `livemode` | `false` | — |
| `simulated` | `true` | — |
| `items?` | `(AskItem & { status: ItemStatus })[]` | — |
| `choices?` | `readonly string[]` | — |
| `how?` | `string` | — |
| `capacity?` | `string \| readonly string[]` | — |
| `decided?` | `string` | — |
| `declined?` | `true` | — |
| `names?` | `string` | For `direct`: the role whose member the party names. On a declined job, the declining member's memo, for the client alone. |
| `memo?` | `string` | — |
| `question?` | `string` | A member's question to the party, in their words, and its message in the job's thread. |
| `message?` | ``msg_${string}`` | — |
| `scope?` | `GrantScope` | For `grant`: what it permits and for how long, as written. |
| `grant?` | `Grant` | For `grant`, once given: its state now, read off the record. |
| `prior?` | `Prior` | The subject's prior period its request list was derived from. |


```txt
$ curl http://localhost:8787/asks/ask_7Hq2
{
  "id": "ask_7Hq2",
  "object": "ask",
  "job": "job_7Hq2",
  "step": "glossary",
  "to": "answer",
  "party": "buyer",
  "what_hash": null,
  "status": "open",
  "expires_at": "2026-11-01T14:02:11.000Z",
  "url": "http://localhost:8787/a/ask_7Hq2?t=8FaWT5EoCj4h-uMyjlXp3_",
  "livemode": false,
  "simulated": true,
  "items": [
    {
      "id": "terms",
      "label": "Which terms stay in English?",
      "status": "open"
    }
  ]
}
```

### `subject`

A subject: what outlives the job, keyed by an input or a receipt, with its jobs, its history, its kept facts, its periods and who is of record.

| Field | Type | Says |
|---|---|---|
| `id` | `SbjId` | — |
| `object` | `'subject'` | — |
| `livemode` | `false` | — |
| `kind` | `string` | What it is, in the Service's words: its `subject.kind`, such as `'taxpayer'`. |
| `key` | `{ field: string; value: string }` | The input or receipt field that names it, and its value: `{ field: 'ein', value: '12-3456789' }`. |
| `created` | `string` | — |
| `jobs` | `JobId[]` | Every job that joined it, oldest first. |
| `of_record` | `(OfRecord & { status: 'of_record' \| 'withdrawing' \| 'vacant' \| 'open'; covered_by?: string; why?: string }) \| null` | Who is of record on it (the seat without its custodian ladder), and the seat's status: `of_record`, `withdrawing`, `vacant` with who covers it, or `open` until a member is named. Null when its Service names no `of_record`. |
| `history` | `SubjectEvent[]` | Insert-only, oldest first: it opened, each job joined, and each change of who is of record. |
| `facts` | `Record<string, { latest: FactValue; periods: Record<string, FactValue>; history: FactValue[] }>` | Each kept fact: its latest value, its value for each period a job wrote it in, and every value it has held, oldest first. |
| `periods` | `{ period: string; service: string; job: JobId; status: string }[]` | Each period a job claimed, oldest first: the period, the Service, the job and where it stands. |
| `clocks?` | `ClockObject[]` | Its clocks, which outlive the jobs, once one is running. |
| `simulated` | `true` | — |


```txt
→ GET /subjects/sbj_7Hq2
{
  "id": "sbj_7Hq2",
  "object": "subject",
  "livemode": false,
  "kind": "account",
  "key": {
    "field": "account",
    "value": "acme"
  },
  "created": "2026-10-25T14:02:11.000Z",
  "jobs": [
    "job_7Hq2",
    "job_7Hq3"
  ],
  "of_record": null,
  "history": [
    {
      "at": "2026-10-25T14:02:11.000Z",
      "type": "opened",
      "job": "job_7Hq2"
    },
    {
      "at": "2026-10-25T14:02:11.000Z",
      "type": "joined",
      "job": "job_7Hq3"
    }
  ],
  "facts": {
    "glossary": {
      "latest": {
        "value": [
          "Lessee",
          "Lessor",
          "Premises"
        ],
        "job": "job_7Hq3",
        "step": "draft",
        "at": "2026-10-25T14:02:11.000Z",
        "period": "2026"
      },
      "periods": {
        "2025": {
          "value": [
            "Lessee",
            "Lessor"
          ],
          "job": "job_7Hq2",
          "step": "draft",
          "at": "2026-10-25T14:02:11.000Z",
          "period": "2025"
        },
        "2026": {
          "value": [
            "Lessee",
            "Lessor",
            "Premises"
          ],
          "job": "job_7Hq3",
          "step": "draft",
          "at": "2026-10-25T14:02:11.000Z",
          "period": "2026"
        }
      },
      "history": [
        {
          "value": [
            "Lessee",
            "Lessor"
          ],
          "job": "job_7Hq2",
          "step": "draft",
          "at": "2026-10-25T14:02:11.000Z",
          "period": "2025"
        },
        {
          "value": [
            "Lessee",
            "Lessor",
            "Premises"
          ],
          "job": "job_7Hq3",
          "step": "draft",
          "at": "2026-10-25T14:02:11.000Z",
          "period": "2026"
        }
      ]
    }
  },
  "periods": [
    {
      "period": "2025",
      "service": "glossary",
      "job": "job_7Hq2",
      "status": "accepted"
    },
    {
      "period": "2026",
      "service": "glossary",
      "job": "job_7Hq3",
      "status": "accepted"
    }
  ],
  "simulated": true
}
```

### `clock`

A clock: a date the world sets on a job or its subject, who answers for it, its rungs, what moves it and the owner's choice at the end. Its owner acknowledges it, satisfies it on evidence and chooses at its date.

| Field | Type | Says |
|---|---|---|
| `id` | `ClkId` | — |
| `object` | `'clock'` | — |
| `livemode` | `false` | — |
| `name` | `string` | Its key under the Service's `clocks`, such as `file`. |
| `service` | `string` | The id of the Service whose `clocks` declare it. |
| `job` | `JobId` | The job that opened it, or the last one to move or satisfy it. |
| `subject` | `SbjId \| null` | The job's subject, `sbj_…`, or null when the job has none yet. |
| `lives_on` | `'job' \| 'subject'` | `'subject'` outlives the job; `'job'` ends with it. |
| `status` | `ClockStatus` | `open` until its date; `due` at its date unsatisfied, waiting on the owner's choice; `satisfied` on evidence; `chosen` once the owner chose. A recurring clock is `open` again at its next occurrence. |
| `due_at` | `string` | The instant it is due: the minute it closes, in its zone, on `due_on`. |
| `due_on` | `string` | The civil date it is due, in `zone`, after any roll. |
| `zone` | `string` | The IANA zone its date is kept in: the Service's calendar, else the brand's, else `UTC`. |
| `rolled_from?` | `string` | The date it fell on before the calendar rolled it past a weekend or a closed day. |
| `original_due_at` | `string` | The instant it opened due at, before any move. |
| `moves` | `ClockMove[]` | Each move of its date, oldest first: from, to, the step whose commit moved it, and when. |
| `occurrence` | `number` | Which occurrence of a recurring clock this is, from 0. |
| `owner` | `Owner \| null` | Who answers for it, or null: no one does yet, and the owner console alarms. |
| `rungs` | `{ rung: string; rings_at: string; fired: boolean }[]` | Each rung, and when it rings for this date. A daily acknowledgement's is its first day's. |
| `lapse` | `string[]` | What the owner chooses at the end, and the choice once it is open. |
| `choice` | `{ options: string[]; opened_at: string } \| null` | At its date, unsatisfied: the options the owner chooses from and when they opened; else null. |
| `chosen?` | `string` | The option the owner chose at the date. |
| `satisfied_by` | `string[]` | The steps whose commit satisfies it. |
| `acknowledged_at?` | `string` | When the client acknowledged, through their own link, that they own the date. |
| `ack_window?` | `{ opened_at: string; closes_at: string }` | While an `ack daily` day is open and unacknowledged: when it opened and when it is missed. |
| `held?` | `{ step: string; why: string; retry_at: string }` | A run rung the gate held, or that couldn't send: its step, why, and when it proposes again. |
| `every?` | `Every` | A recurring clock's cycle: once satisfied, its next occurrence comes this far on, counted from the first. |
| `created` | `string` | — |
| `simulated` | `true` | — |


```txt
$ npx services.dev clocks get clk_7Hq2 --json
{
  "id": "clk_7Hq2",
  "object": "clock",
  "livemode": false,
  "name": "file",
  "service": "translation",
  "job": "job_7Hq2",
  "subject": null,
  "lives_on": "job",
  "status": "open",
  "due_at": "2026-11-04T23:59:00.000Z",
  "due_on": "2026-11-04",
  "zone": "UTC",
  "original_due_at": "2026-11-04T23:59:00.000Z",
  "moves": [],
  "occurrence": 0,
  "owner": {
    "type": "buyer",
    "member": null
  },
  "rungs": [
    {
      "rung": "run extend 3d",
      "rings_at": "2026-11-01T00:00:00.000Z",
      "fired": false
    }
  ],
  "lapse": [
    "file",
    "withdraw, in writing"
  ],
  "choice": null,
  "satisfied_by": [
    "file"
  ],
  "created": "2026-10-25T14:02:11.000Z",
  "simulated": true
}
```

### `subscription`

A subscription: standing work charged once per cycle, its schedule and events minting jobs that share its subject and policy, and its allowances used and included, reset at renewal.

| Field | Type | Says |
|---|---|---|
| `id` | `SubId` | — |
| `object` | `'subscription'` | — |
| `livemode` | `false` | — |
| `service` | `string` | The id of the Service ordered, whose price has `every`. |
| `status` | `SubscriptionStatus` | `active`; `canceling` once canceled, minting until its paid cycle ends; then `canceled`. |
| `subject` | `SbjId \| null` | The subject every minted job shares, `sbj_…`, or null. |
| `policy` | `Record<string, unknown>` | The order's policy, which every minted job shares. |
| `price` | `{ usd: number; every: Every }` | What each cycle charges, and how often. |
| `cycle` | `{ number: number; start: string; end: string }` | The cycle running now, from 1: its start and end. Each renewal starts where the last ended, counted from the first so it never drifts. |
| `allowances` | `Record<string, { used: number; included: number }>` | Each allowance this cycle: how many jobs used it, of how many included. |
| `schedule` | `{ name: string; service: string; next: string \| null }[]` | Each schedule date and the Service it mints, with when it next does; null once nothing will. |
| `events` | `{ event: string; service: string }[]` | Each event it listens for, and the Service it mints. |
| `charges` | `{ cycle: number; usd: number; at: string }[]` | Each cycle's charge: the cycle, its dollars and when. |
| `minted` | `Minted[]` | Every trigger's outcome, oldest first: a job minted, an extra job offered, or a refusal recorded. |
| `jobs` | `JobId[]` | Every job it minted, oldest first. |
| `ends_at?` | `string` | Canceled: when it ends, at its cycle's end. |
| `metadata` | `Record<string, unknown>` | The order's metadata, returned as sent. |
| `test_clock?` | `TcId` | The test clock it runs on, when the order named one. |
| `created` | `string` | — |
| `simulated` | `true` | — |


```txt
$ curl http://localhost:8787/subscriptions/sbn_7Hq2
{
  "id": "sbn_7Hq2",
  "object": "subscription",
  "livemode": false,
  "service": "plan",
  "status": "active",
  "subject": "sbj_7Hq2",
  "policy": {},
  "price": {
    "usd": 2400,
    "every": "year"
  },
  "cycle": {
    "number": 1,
    "start": "2026-10-25T14:02:11.000Z",
    "end": "2027-10-25T14:02:11.000Z"
  },
  "allowances": {
    "annual-return": {
      "used": 1,
      "included": 1
    },
    "estimate": {
      "used": 1,
      "included": 4
    },
    "question": {
      "used": 1,
      "included": 2
    },
    "notice-response": {
      "used": 0,
      "included": 1
    }
  },
  "schedule": [
    {
      "name": "annual",
      "service": "annual-return",
      "next": "2028-02-01T00:00:00.000Z"
    },
    {
      "name": "estimate",
      "service": "estimate",
      "next": "2027-04-05T00:00:00.000Z"
    }
  ],
  "events": [
    {
      "event": "question.asked",
      "service": "question"
    },
    {
      "event": "notice.received",
      "service": "notice-response"
    }
  ],
  "charges": [
    {
      "cycle": 1,
      "usd": 2400,
      "at": "2026-10-25T14:02:11.000Z"
    }
  ],
  "minted": [
    {
      "id": "trg_4nx9noIgqH",
      "key": "sbn_7Hq2:schedule estimate:2026-12-05T00:00:00.000Z",
      "at": "2026-12-05T00:00:00.000Z",
      "scheduled_for": "2026-12-05T00:00:00.000Z",
      "trigger": "schedule estimate",
      "on": "2026-12-05",
      "service": "estimate",
      "outcome": "minted",
      "usd": 0,
      "job": "job_7Hq2"
    },
    {
      "id": "trg_4lTorI2BGt",
      "key": "sbn_7Hq2:schedule annual:2027-02-01T00:00:00.000Z",
      "at": "2027-02-01T00:00:00.000Z",
      "scheduled_for": "2027-02-01T00:00:00.000Z",
      "trigger": "schedule annual",
      "on": "2027-02-01",
      "service": "annual-return",
      "outcome": "minted",
      "usd": 0,
      "job": "job_7Hq3",
      "period": "2026"
    },
    {
      "id": "trg_LE7XME3M9k",
      "key": "sbn_7Hq2:event question.asked:question-1",
      "at": "2027-02-02T00:00:00.000Z",
      "trigger": "event question.asked",
      "on": "question.asked",
      "service": "question",
      "outcome": "minted",
      "usd": 0,
      "job": "job_7Hq4"
    }
  ],
  "jobs": [
    "job_7Hq2",
    "job_7Hq3",
    "job_7Hq4"
  ],
  "metadata": {},
  "created": "2026-10-25T14:02:11.000Z",
  "simulated": true
}
```

### `event`

An event: one record fact in the brand's ordered feed, with its seq, as its audience sees it.

| Field | Type | Says |
|---|---|---|
| `id` | `EvtId` | — |
| `object` | `'event'` | — |
| `seq` | `number` | Its place in the brand's feed: every event has a higher seq than the one before. |
| `type` | `T` | — |
| `created` | `string` | — |
| `job` | `JobId \| null` | — |
| `service` | `string \| null` | — |
| `data` | `Record<string, unknown>` | The record's fact, as this audience may read it. |
| `metadata?` | `Record<string, unknown>` | The buyer's own keys, echoed from the order. |
| `test_clock?` | `TcId` | — |
| `synthetic?` | `true` | Fired by `events send`, not by a job. |
| `request` | `{ id: string; idempotency_key: string \| null } \| null` | The API request that caused it, with its Idempotency-Key; null when the work or the clock did. |
| `livemode` | `false` | — |
| `simulated` | `true` | — |


```txt
$ npx services.dev events list after=0 limit=2
{
  "type": "OK",
  "object": "list",
  "data": [
    {
      "id": "evt_5gX1X2B5swzY61",
      "object": "event",
      "seq": 1,
      "type": "job.ordered",
      "created": "2026-10-25T14:02:11.000Z",
      "job": "job_7Hq2",
      "service": "translation",
      "data": {
        "by": "buyer",
        "amount_usd": 49
      },
      "request": {
        "id": "req_WppKI6",
        "idempotency_key": null
      },
      "livemode": false,
      "simulated": true
    },
    {
      "id": "evt_88cLb4PC0MfpT4",
      "object": "event",
      "seq": 2,
      "type": "charge.held",
      "created": "2026-10-25T14:02:11.000Z",
      "job": "job_7Hq2",
      "service": "translation",
      "data": {
        "amount_usd": 49
      },
      "request": {
        "id": "req_WppKI6",
        "idempotency_key": null
      },
      "livemode": false,
      "simulated": true
    }
  ],
  "has_more": true,
  "url": "/events",
  "next_seq": 11
}
```

### `watch`

A watch: a webhook endpoint, with its whsec_ secret, its events and its deliveries.

| Field | Type | Says |
|---|---|---|
| `id` | `WhId` | — |
| `object` | `'watch'` | — |
| `url` | `string` | — |
| `events` | `readonly string[]` | Event names, or `*` for every one the buyer receives. |
| `status` | `'enabled'` | — |
| `secret?` | `Secret` | — |
| `created` | `string` | — |
| `deliveries` | `{ delivered: number; failing: number; gave_up: number }` | — |
| `livemode` | `false` | — |
| `simulated` | `true` | — |


```txt
$ npx services.dev watches create https://hooks.example.test/lingua events=job.delivered
{
  "id": "wh_1rKV5VS8V3",
  "object": "watch",
  "url": "https://hooks.example.test/lingua",
  "events": [
    "job.delivered"
  ],
  "status": "enabled",
  "created": "2026-10-25T14:02:11.000Z",
  "livemode": false,
  "simulated": true,
  "deliveries": {
    "delivered": 0,
    "failing": 0,
    "gave_up": 0
  },
  "secret": "whsec_88PiGzGqWulKhuHAUGldLH9GSl5J8tTF"
}
```

### `member`

A member: a person in a Pool, their application, what the verifier wrote and their availability; never their ledger.

| Field | Type | Says |
|---|---|---|
| `id` | `MbrId` | — |
| `object` | `'member'` | — |
| `livemode` | `false` | — |
| `pool` | `string` | — |
| `email` | `string` | — |
| `join` | `{ step: number; of: number; next: string[]; done: boolean }` | The /join funnel: the step reached, of how many, the fields the next one asks, and whether it's done. |
| `application` | `Record<string, unknown>` | — |
| `verified` | `(Facts & { fresh_until: string; fresh: boolean }) \| null` | null until the verifier writes; `fresh` is read against the clock now. |
| `availability` | `Availability` | — |
| `metadata` | `Record<string, never>` | — |
| `simulated` | `true` | Every member on localhost: the fixture verifier stands in for the Pool's. |

`verified` is the verifier’s latest write, read against the clock now: each write replaces the last, and `fresh` turns false past the Pool’s `fresh`. [Verify a member](https://services.dev/docs/people/pool/verify.md) walks it.


```txt
→ POST /attorneys/join {"email":"grace@hopper.example","answers":{"name":"Grace Hopper","credential":"patent agent","number":"71,234","regions":["US-CA"],"areas":["patents"],"hours":10,"turnaround":"24h","min_fee":120}}   # the applicant, in one call
{
  "id": "mbr_7Hq2",
  "object": "member",
  "livemode": false,
  "pool": "attorneys",
  "email": "grace@hopper.example",
  "join": {
    "step": 3,
    "of": 3,
    "next": [],
    "done": true
  },
  "application": {
    "name": "Grace Hopper",
    "credential": "patent agent",
    "number": "71,234",
    "regions": [
      "US-CA"
    ],
    "areas": [
      "patents"
    ],
    "hours": 10,
    "turnaround": "24h",
    "min_fee": 120
  },
  "verified": {
    "credentials": {
      "patent agent": [
        "US-CA"
      ]
    },
    "coverage": {
      "per_act": 1000000,
      "until": "2027-10-25T14:02:11.000Z"
    },
    "at": "2026-10-25T14:02:11.000Z",
    "by": "fixture",
    "fresh_until": "2026-11-24T14:02:11.000Z",
    "fresh": true
  },
  "availability": "on",
  "metadata": {},
  "simulated": true,
  "login": "http://localhost:8787/attorneys/login?t=ms_bU0qS0IkbnMxlMCPdfIc9j"
}
```

### `receipt`

An outside receipt: a submission's status, codes, number and file.

| Field | Type | Says |
|---|---|---|
| `id` | `RcpId` | — |
| `object` | `'receipt'` | — |
| `job` | `JobId` | — |
| `step` | `string` | — |
| `to` | `string` | The outside system, by the name the step gives it. |
| `at` | `string` | When it's filed. A repair resubmitted inside `perfect` keeps the first submission's time. |
| `sent_at?` | `string` | When it was actually sent, where that differs from `at`. |
| `status` | `ReceiptStatus` | — |
| `codes?` | `string[]` | Why it was rejected, or the alerts it was accepted with. |
| `ref?` | `string` | The outside system's own number for it. |
| `file?` | `FileRef` | — |
| `fee_usd?` | `number` | — |
| `element?` | `number` | With `each`: which element of the list, the element itself when it is a word or a number, and the lead's receipt the others are linked to. |
| `for?` | `string` | — |
| `lead?` | `RcpId` | — |
| `livemode` | `false` | — |
| `simulated?` | `true` | On the wire in the sandbox. The record keeps the receipt without it. |


```txt
$ curl -s http://localhost:8787/jobs/job_7Hq2 | jq '.receipts[0]'
{
  "id": "rcp_7Hq2",
  "object": "receipt",
  "job": "job_7Hq2",
  "step": "file",
  "to": "the registry",
  "at": "2026-10-25T14:02:11.000Z",
  "status": "accepted",
  "livemode": false,
  "file": {
    "url": "http://localhost:8787/jobs/job_7Hq2/files/82d85d1a577fa13c7b2b5949e8b1aea6e5f307e492ad3a279c7618ab8cbb6956",
    "name": "rcp_7Hq2.txt"
  },
  "simulated": true
}
```

### `test_clock`

A test clock: the time every job on it reads, frozen until advanced, only ever forward. Moving one backward answers 409 `test_clock_backward`, and deleting one voids every job on it.

| Field | Type | Says |
|---|---|---|
| `id` | `TcId` | — |
| `object` | `'test_clock'` | — |
| `frozen_at` | `string` | The time the clock reads. |
| `status` | `'ready' \| 'advancing'` | `advancing` while an advance runs, `ready` once every timer owed by then has fired, with `test_clock.ready` on the feed. A second advance waits for it to finish, answered 409 clock_advancing. |
| `advancing_to?` | `string` | Where a running advance is going. |
| `default?` | `true` | The dev server's own clock: it follows the wall clock, ahead by its advances. Every job not on another clock is on it. |
| `jobs` | `number` | How many jobs are on it. |
| `created` | `string` | — |
| `livemode` | `false` | — |
| `simulated` | `true` | — |


## Inside the answers

Objects a call answers with that carry no id of their own: what a member reads and signs, what the gate freezes, what a buyer is offered, and where a refusal’s rule sits.

### `packet`

What a member reads once they claimed and cleared a Task, and what their attestation binds: the AI’s artifacts with their versions and what changed, the review reports, the client’s answers, the checklist, the record, the signals, the clock and the hash.

| Field | Type |
|---|---|
| `object` | string |
| `task` | string |
| `job` | string |
| `service` | string |
| `step` | string |
| `act` | string |
| `summary` | string |
| `input` | object |
| `sheet` | object |
| `artifacts` | list |
| `reviews` | list |
| `answers` | list |
| `checklist` | list |
| `stamps` | boolean |
| `record` | string |
| `signals` | list |
| `clock` | object |
| `hash` | string |
| `simulated` | boolean |


```txt
→ GET /reviews/tsk_7Hq2/packet   # as mbr_eligible: the packet
{
  "object": "packet",
  "task": "tsk_7Hq2",
  "job": "job_7Hq2",
  "service": "provisional-patent",
  "step": "sign",
  "act": "sign",
  "summary": "Provisional Patent Application: A provisional application, drafted, examined, filed. Done so far: consent, questions, draft, examine. Yours: sign.",
  "input": {
    "invention": [
      {
        "url": "data:text/plain,The%20invention.txt.",
        "name": "invention.txt"
      }
    ],
    "applicant": {
      "name": "Ada Lovelace"
    },
    "inventors": [
      {
        "name": "Ada Lovelace"
      }
    ],
    "entity_size": "micro"
  },
  "sheet": {
    "parties": [
      {
        "as": "applicant",
        "name": "Ada Lovelace"
      },
      {
        "as": "inventors",
        "name": "Ada Lovelace"
      }
    ],
    "kind": "Provisional Patent Application"
  },
  "artifacts": [
    {
      "path": "draft/application.txt",
      "sha256": "sha256:bf3b849629a4666142bccd9481a6d1048aa03f455313f713f8321984a0a57a2b",
      "versions": 1,
      "url": "http://localhost:8787/matters/job_7Hq2/files/bf3b849629a4666142bccd9481a6d1048aa03f455313f713f8321984a0a57a2b"
    },
    {
      "path": "draft/exam.txt",
      "sha256": "sha256:190897a68763a61887a14ab3697e3d7f854268b7fed07c6a0c9b1a51e8c503ad",
      "versions": 1,
      "url": "http://localhost:8787/matters/job_7Hq2/files/190897a68763a61887a14ab3697e3d7f854268b7fed07c6a0c9b1a51e8c503ad"
    }
  ],
  "reviews": [
    {
      "step": "examine",
      "verdict": "pass",
      "report": {
        "step": "examine",
        "of": "draft",
        "kind": "adversarial",
        "round": 0,
        "lenses": [
          "eligibility",
          "novelty",
          "obviousness",
          "written description"
        ],
        "findings": [],
        "signals": {
          "eligibility": false,
          "novelty": false,
          "obviousness": false,
          "written description": false
        },
        "verdict": "pass"
      }
    }
  ],
  "answers": [
    {
      "step": "questions",
      "answer": "Simulated answer."
    }
  ],
  "checklist": [
    "the claims read on the disclosure",
    "every inventor is named",
    "a reasonable inquiry was made"
  ],
  "stamps": true,
  "record": "consent · applicant · consent | questions · applicant · answer | draft · ai | examine · ai · adversarial · 4 lenses · pass",
  "signals": [],
  "clock": {
    "due": "2026-10-30T14:02:11.000Z",
    "hold_until": "2026-10-26T14:02:11.000Z",
    "extended": false
  },
  "hash": "sha256:27d7bdec3be22fd633af279053beef779c9c5080629816867bbfc4e4593a5b33",
  "simulated": true
}
```

Explained in [The packet](https://services.dev/docs/people/pool/packet.md), [What a person can do](https://services.dev/docs/people/acts.md).

### `attestation`

What the gate freezes on the record when a person attests: who, the credential the verifier holds for them, the region, the hash of what they signed, the rules version the job pinned, and the checklist they affirmed.

| Field | Type | Says |
|---|---|---|
| `member` | `string; credential: string; region: string \| null; hash: Hash; rules: string; fields?: readonly string[]; affirmed?: readonly string[]` | — |
| `reservation?` | `{ path: string; sha256: Hash }` | Attested, qualified: the reservation the member wrote, kept as its own file, which travels with the output. |


Explained in [What a person can do](https://services.dev/docs/people/acts.md), [Rules: how a Service meets licensing by design](https://services.dev/docs/people/rules.md).

### `offer`

A buyer’s answer when the price is over their max or their key’s cap: the price, its sentence and terms, and the exact next call.

| Field | Type | Says |
|---|---|---|
| `type` | `'OFFER'` | — |
| `object` | `'offer'` | — |
| `service` | `string` | — |
| `title` | `string` | — |
| `price` | `{ usd: number; approved_usd?: number; sentence: string }` | — |
| `eta` | `Within` | — |
| `terms` | `string` | — |
| `checkout_url?` | `string` | Over the buyer key's cap: a person raises it here. |
| `next` | `Next` | — |
| `simulated` | `true` | — |


```txt
$ curl -X POST http://localhost:8787/jobs -H 'content-type: application/json' -d '{"service":"certified-translation","document":{"url":"https://example.com/lease.pdf","name":"lease.pdf"},"to":"fr","country":"FR","max_usd":189,"key":"lease-fr-3"}'
← 402 · {
  "type": "OFFER",
  "object": "offer",
  "service": "certified-translation",
  "title": "Certified Translation",
  "price": {
    "usd": 189,
    "sentence": "$189 per job, within 3 days, charged on delivery."
  },
  "eta": "3d",
  "terms": "Charged on delivery. Cancel at $0 until it ships, except the work a person attested once the signature before certify is done. Send it back with a note and the AI redoes it, or you pay $0. Final 7 days after delivery.",
  "checkout_url": "http://localhost:8787/keys/sk_test_7Hq2",
  "next": {
    "do": "checkout",
    "url": "http://localhost:8787/keys/sk_test_7Hq2",
    "tool": null,
    "http": "GET http://localhost:8787/keys/sk_test_7Hq2",
    "then": {
      "do": "order",
      "service": "certified-translation",
      "arguments": {
        "document": {
          "url": "https://example.com/lease.pdf",
          "name": "lease.pdf"
        },
        "to": "fr",
        "country": "FR",
        "max_usd": 189,
        "key": "lease-fr-3",
        "service": "certified-translation"
      },
      "tool": "order_job",
      "http": "POST http://localhost:8787/jobs {\"service\":\"certified-translation\"}"
    }
  },
  "simulated": true
}
```

Explained in ['Answers: OK, EMPTY, OFFER, BLOCKED'](https://services.dev/docs/api/answers.md).

### `rule_ref`

Where a refusal’s rule sits: the rules table’s version, the row, the position counsel gives for it, and what the row cites.

| Field | Type |
|---|---|
| `version` | `string` |
| `at` | `string` |
| `position` | `string` |
| `cite?` | `readonly string[]` |


```txt
→ POST /matters {"service":"litigate","max_usd":500,"key":"sue-initech"}
{
  "type": "BLOCKED",
  "category": "blocked",
  "code": "act_refused",
  "reason": "litigate is never performed here: Litigation is retained directly, never ordered here.",
  "param": "service",
  "act": "litigate",
  "rule": {
    "version": "2026-10",
    "at": "shared.litigate",
    "position": "Litigation is retained directly, never ordered here."
  },
  "cure": {
    "route": "https://referrals.example.test/litigation"
  },
  "next": {
    "do": "hand_to_person",
    "url": "https://referrals.example.test/litigation",
    "arguments": {},
    "tool": null,
    "http": "GET https://referrals.example.test/litigation"
  },
  "doc_url": "https://api.lawyer/docs/errors/act_refused",
  "request_id": "req_cXmV9f",
  "simulated": true
}
```

Explained in [Rules: how a Service meets licensing by design](https://services.dev/docs/people/rules.md), [Refusals and cures](https://services.dev/docs/people/refusals.md).

---

- Up: [Your first paid job](https://services.dev/docs.md)
- Previous: [Operations](https://services.dev/docs/reference/operations.md)
- Next: [Every key](https://services.dev/docs/reference/keys.md)
