---
title: "Deadlines"
url: https://services.dev/docs/service/within
captured: [api-quote.txt, ask.txt, grow-ask.txt, legal-walk.txt, service-check.txt, tax-check.txt, within-at-risk.txt, within-late.txt]
---
# Deadlines

URL: https://services.dev/docs/service/within

> within is the job's deadline, 48 hours unless you set it, or a span before a date the world sets, stated in the price sentence. It counts only while the work is the brand's. At three quarters the job is at risk, at the end it is late, and price.late takes a share off the charge.

`within` answers one question: how long may the work take, and what happens when it runs long?

## Smallest form

```ts title="services/rush-translation.ts"
import { Service } from 'services.dev'

// The same work in a day: within sets the deadline the price sentence states.
export default Service({
  name: 'Rush Translation',
  input: { document: 'file', to: 'language: a BCP 47 tag, such as fr-CA' },
  output: { document: 'file' },
  price: { usd: 79, within: '24h' },
})
```

```bash
npx services.dev check
```

```txt title="captured/service-check.txt · magic values: none"
services/rush-translation.ts · 4 lines · $79 per job, within 24 hours, charged on delivery.
```

## Every form

**On the price**

| Key | Written | Left out | Does |
|---|---|---|---|
| `price.within` | `Within \| '${number}d before ${clock}'` | `'48h'` | The job's deadline, stated in the price sentence: hours or days from the order, or a span before one of the job's clocks, which it follows as the clock moves. |
| `price.late` | `Pct \| number` | none: a late job charges its price | What a late job costs you: a share of the price, `'20%'`, or dollars, taken off the charge at release. The price sentence states it. |

**On a step**

| Key | Written | Left out | Does |
|---|---|---|---|
| `within` | `Within` | none | This step's own deadline, and the due date on its Task. |

A span is elapsed time: `'3d'` is 72 hours, counted while the work is the brand's. A clock's rungs count civil days on the calendar instead.

## What pauses it

| While the job | Its deadline |
|---|---|
| works: AI, your code, a person at a step, an outside system | counts |
| waits on a party's ask | pauses: `waiting` carries `"clock": "paused"`, and the record prints how long |
| is delivered | stops: the job is final 7 days later, unless the buyer accepts or sends it back first |

Every job carries its deadline as timer state, [held](https://services.dev/docs/service/timers.md#states) on each pause with the time it had left and re-armed on each resume:

```json title="GET /jobs/job_7Hq2 · deadline"
"deadline": { "within": "24h", "used": "6h 40m", "remaining": "17h 20m", "at_risk_at": null, "late_at": null, "paused_since": "2026-11-24T14:02:11Z" }
```

```txt
→ POST /translation {"document":"lease.pdf","to":"fr-CA","key":"grow","max_usd":49}
```

```txt title="captured/grow-ask.txt · magic values: none"
← job_7Hq2 · waiting · on party · $49.00 held
  waiting {"on":"party","since_at":"2026-10-25T14:02:11.000Z","step":"glossary","clock":"paused"}
```

```bash
curl http://localhost:8787/jobs/job_7Hq2?wait=50
```

```txt title="captured/ask.txt · magic values: none"
  record  glossary.terms · answered | glossary · buyer · answer · clock paused 2h 5min | translate · ai | review · ai · pass
```

## A deadline that follows a date

Work due before a date the world sets states its deadline against that date. `within: '5d before file'` ends five days before the job's `file` clock and moves when the clock moves, at risk at three quarters of the span from the order. apis.tax's annual return writes `within: '5d before file', late: '20%'`, and its price sentence reads "$1,800, filed 5 days before your deadline, 20% off if not". When the extension moves the date to file, the deadline moves with it. While the job waits on a party, its `late_at` never moves: only its at-risk timer is held. A clock with [`each`](https://services.dev/docs/service/clocks.md#a-date-for-each-item) gives the lead item's date.

## In the manifest, and the quote that serves it

| Key | Holds |
|---|---|
| `price.within` | the deadline, every default written: `'48h'` unless you set it |
| `price.late` | what a late job is charged less, when you set it |
| `price.final_after` | how long after delivery the job is final: `'7d'` |
| `price.sentence` | the price sentence every surface prints, deadline included |

```bash
curl http://localhost:8787/translation.json
```

```json title="captured/api-quote.txt · 200 · request-id: req_cgqaTN · services-version: 2026-10-25 · magic values: none"
{
  "type": "OK",
  "id": "translation",
  "name": "Translation",
  "price": {
    "per": "job",
    "cents": 4900,
    "within": "48h",
    "ai_cap": "20%",
    "final_after": "7d",
    "charged": "on delivery",
    "sentence": "$49 per job, within 48 hours, charged on delivery."
  },
  "surfaces": {
    "route": "POST /jobs {\"service\":\"translation\"}",
    "tool": "order_translation"
  }
}
```

## Escalate before it's late

A deadline you state is one you keep. [`escalate`](https://services.dev/docs/service/deliver.md#escalate-to-a-person) with `when: 'at_risk'` hands a step to a person the moment the job turns at risk with that step still open. Here the model is unavailable, and AI retries the translation on its backoff while the deadline runs:

```bash
cat services/rush-translation.ts
```

```txt title="captured/within-late.txt · magic values: metadata.sandbox.ai = down"
import { Service } from 'services.dev'

// The same work in a day, and the deadline backed: a job delivered late is charged 20% less. If the job is at risk
// while AI is still on the translation, a reviewer on your staff takes the step.
export default Service({
  name: 'Rush Translation',
  input: { document: 'file', to: 'language: a BCP 47 tag, such as fr-CA' },
  output: { document: 'file' },
  roles: { reviewer: {} },
  deliver: { translate: { by: 'ai', escalate: { to: 'reviewer', when: 'at_risk' } }, harden: { review: 'adversarial' } },
  price: { usd: 79, within: '24h', late: '20%' },
})
```

`check` reads the deadline back, with what each moment does and what a late job leaves you:

```bash
npx services.dev check services/rush-translation.ts
```

```txt title="captured/within-late.txt · magic values: metadata.sandbox.ai = down"
services/rush-translation.ts · 6 lines · $79 per job, within 24 hours, 20% off if late, charged on delivery.
  who     AI delivers every job. A reviewer on your staff takes translate when the job is at risk.
  steps   translate · ai · to reviewer at risk → harden · ai · adversarial
  time    at risk at 18h of 24h: translate goes to reviewer · late at 24h: the charge falls to $63.20
  ledger  +$79.00 · AI $0.84 (example) · you $78.16 · late: +$63.20 · AI $0.84 (example) · you $62.36
  apps    customer portal · owner console
```

At 18 of 24 hours the step is your reviewer's, waiting in the owner console's inbox with the time it has left:

```bash
npx services.dev tick 18h --test-clock tc_7Hq5
```

```txt title="magic values: metadata.sandbox.ai = down"
tc_7Hq5 · 2026-11-27 15:00:00 → 2026-11-28 09:00:00 · 1 fired
  2026-11-28 09:00:00  job_7Hq8  job.at_risk · 18h of 24h, counted only while the work is the brand's · translate escalates to reviewer
```

```bash
curl http://localhost:8787/owner/jobs/job_7Hq8
```

```txt title="captured/within-late.txt · magic values: metadata.sandbox.ai = down"
← job_7Hq8 · waiting · on person · at risk · $79.00 held · due 2026-11-28 15:00
  record  translate · ai · the model is unavailable, 41 attempts | at_risk · 18h of 24h | translate · escalated · reviewer · at risk
  inbox   translate · reviewer · at risk · 6h left
  next    npx services.dev approve job_7Hq8 document=…
```

A step a member of a Pool holds escalates through the Pool instead: its Task's due date is the step's `within`, and the [fill ladder](https://services.dev/docs/people/pool/fill.md) raises it before then.

## Late

`price.late` is what a late job costs you. At 24 hours the charge falls by its share, and the buyer hears it with the new amount:

```bash
npx services.dev tick 6h --test-clock tc_7Hq5
```

```txt title="magic values: metadata.sandbox.ai = down"
tc_7Hq5 · 2026-11-28 09:00:00 → 2026-11-28 15:00:00 · 1 fired
  2026-11-28 15:00:00  job_7Hq8  job.late · 24h of 24h · 20% off if late: the charge falls to $63.20
```

The reviewer delivers it 40 minutes later, at the lower charge:

```txt
→ POST /owner/jobs/job_7Hq8/approve {"document":"contract.fr-CA.pdf"}
```

```txt title="magic values: metadata.sandbox.ai = down"
← job_7Hq8 · delivered · contract.fr-CA.pdf · $63.20 charged · late by 40m
  record  translate · ai · the model is unavailable, 41 attempts | at_risk · 18h of 24h | translate · escalated · reviewer · at risk | late · 24h of 24h · 20% off | translate · person · reviewer | harden · ai · adversarial · pass
  ledger  +$79.00 · late −$15.80 · AI $0.84 (example) · you $62.36
```

The credit comes off your line. AI, a member's pay and pass-through fees stay whole, and services.dev's take is on what the buyer is charged. A job that is late and never delivered charges nothing: the buyer can cancel it at $0, as any job before delivery.

## What happens on its own

| Event | Fires when | Then |
|---|---|---|
| `job.at_risk` | three quarters of `within` has gone while the work was the brand's | an open step with `escalate.when: 'at_risk'` goes to its role, and the owner console lists the job |
| `job.late` | all of `within` has gone while the work was the brand's | the charge falls by `price.late`, and an open step with `when: 'late'` goes to its role |
| `clock.moved` | the clock a `'5d before file'` deadline follows moves | the deadline moves with it, and its at-risk and late timers re-arm |
| a clock's rungs | a date the world sets comes near | [Clocks](https://services.dev/docs/service/clocks.md) |

```bash
cat services/staged.ts
```

```txt title="captured/within-at-risk.txt · magic values: client.email = silent@example.test"
import { Service } from 'services.dev'

// Ten hours to deliver, counted only while the work is the brand's: the staff check it, the client confirms, and
// the staff finish it. The client's time on their ask never counts.
export default Service({
  name: 'Staged Review',
  input: { client: 'party' },
  output: { draft: 'text', confirmed: 'text', final: 'text' },
  deliver: { draft: 'ai', check: 'person', confirm: { ask: 'client', to: 'answer' }, finish: 'person' },
  price: { usd: 60, within: '10h' },
})
```

```bash
npx services.dev tick 4h
```

```txt title="captured/within-at-risk.txt · magic values: client.email = silent@example.test"
tc_7Hq2 · 2026-10-28 19:00:00 → 2026-10-28 23:00:00 · 2 fired
  2026-10-28 19:30:00  job_7Hq2  job.at_risk · 7.5h of 10h, counted only while the work is the brand's
  2026-10-28 22:00:00  job_7Hq2  job.late · 10h of 10h, counted only while the work is the brand's
```

```bash
npx services.dev get job_7Hq2
```

```txt title="captured/within-at-risk.txt · magic values: client.email = silent@example.test"
job_7Hq2 · waiting · on person · $60.00 held
  record  draft · ai | check · person | confirm · client · answer · clock paused 3d
  next    npx services.dev approve job_7Hq2
```

## In the apps

| App | Shows | Acts |
|---|---|---|
| [Customer portal](https://services.dev/docs/app/buyers.md) | each job's due time, paused while it waits on them, then at risk and late, with what a late job is charged | cancel before delivery, at $0 |
| [Delivery portal](https://services.dev/docs/app/members.md) | the step's deadline as its Task's due date, beside its hold | extend the hold once, never past the due date |
| [Owner console](https://services.dev/docs/operate/dates.md) | jobs at risk, then late, and each escalated step waiting in the inbox with its time left | your staff take the step, in their own session |

`job.at_risk` and `job.late` reach the buyer on the [events](https://services.dev/docs/reference/events.md) feed and its webhooks.

## Money and plan

A late job's credit comes off your line, as [Late](#late) shows, and a late job never delivered charges nothing. A deadline and a late price run on every plan. Every kind of time, by plan: [Keeping time](https://services.dev/docs/service/time.md#plans).

## Seven surfaces

| Op | API | CLI | MCP | SDK | Site | Docs | App |
|---|---|---|---|---|---|---|---|
| `service.quote` | `GET /:service.json` |  |  |  | `/<service>`: the price sentence | 1 error page |  |

[Operations](https://services.dev/docs/reference/operations.md) has every column of every row.

## Refusals

None of its own.

## In the example brands

The lines that use it in the example brands, as their files write them, and what `check` read aloud for each file.

```ts title="legal · services/demand-letter.ts · 26 lines"
    reply: { by: 'ai', within: '30d' },
```

```txt title="npx services.dev check · captured/legal-walk.txt"
services/demand-letter.ts · 26 lines · $149 per job, within 48 hours, charged on send's receipt.
  steps   consent · client · consent → draft · ai → attack · ai · adversarial · 3 lenses → sign · attorney · client · stamped · 2-item checklist → send · the recipient → courier · a courier · routed → reply · ai → settle · client · decide
```

[The legal example](https://services.dev/docs/examples/legal.md) runs every one of its files, captured.

```ts title="tax · services/amended-return.ts · 22 lines"
  price: { usd: 900, within: '30d', release: ['file.accepted', 'aar.accepted'] },
```

```txt title="npx services.dev check · captured/tax-check.txt"
services/amended-return.ts · 22 lines · $900 per job, within 30 days, charged when file or aar is accepted.
  steps   compute · code · cites depreciation and carryforward schedules → draft · ai · cites the workpapers and the records the organizer took → check · ai · adversarial · 2 lenses → prepare · preparer · * · 1-item checklist → sign · signer · * · stamped in the paid-preparer block → authorize · owner · sign → file · IRS and states, unless a partnership → aar · IRS · Form 8082, for a partnership · emits k1.adjusted
```

[A missed date](https://services.dev/docs/examples/tax/missed.md) prices a late return in apis.tax.

---

- Up: [Service()](https://services.dev/docs/service.md)
- Previous: [Timers and replay](https://services.dev/docs/service/timers.md)
- Next: [Clocks](https://services.dev/docs/service/clocks.md)
