Renew the certificate

A schedule fires and forgets. But some things aren't a moment — they're an obligation that has to get done, and stay tracked even if the agent that took it on is long gone. A TLS certificate expires on March 14 and must not lapse. That's a deadline: a due date, an escalation policy that nags with growing urgency, and — crucially — a way for a completely fresh agent instance to rediscover the commitment months later. This rung introduces the second primitive and its cross-session payoff.

The story

While provisioning infrastructure, an agent notices a certificate that expires on March 14. It won't be running then, and neither will the instance that comes after it. So it remembers the deadline: warn the operating agent at 30, 7, and 1 days out via webhook, email the ops humans on the due date, and keep nagging daily if it goes overdue. Weeks later a different instance asks "what's due soon?" and finds it waiting.

Design the escalation

An escalation policy is a list of steps, each an offset relative to due_at (ISO-8601 duration; negative is before the due time, positive is after) and the channels it fires on — webhook, email, or both. One step may carry "repeat": "daily" to keep nagging. A referenced channel must have a destination: any webhook step requires a webhook_url, any email step requires notify_emails.

For the certificate: three early nudges to the agent over webhook, a day-of email to the humans, and a daily email while overdue.

{
  "steps": [
    {"offset": "-P30D", "channels": ["webhook"]},
    {"offset": "-P7D",  "channels": ["webhook"]},
    {"offset": "-P1D",  "channels": ["webhook"]},
    {"offset": "P0D",   "channels": ["email"]},
    {"offset": "P1D",   "channels": ["email"], "repeat": "daily"}
  ]
}

You can dry-run it with POST /v1/deadlines/escalation-preview/ — it lists the exact reminders the policy would fire, creating nothing.

Solve it

Go to Deadlines → New deadline. Set the summary and the due_at date, add the destinations (a webhook_url and the notify_emails list), and build the escalation steps above. The detail page then shows the materialised reminder schedule so you can confirm the nags land where you expect.

POST /v1/deadlines/ with summary, due_at, the destinations, and the escalation_policy.

curl https://aigears.example.com/v1/deadlines/ \
  -H "Authorization: Bearer aigears_live_..." \
  -H "Idempotency-Key: renew-tls-2026-03-14" \
  -H "Content-Type: application/json" \
  -d '{
    "summary": "Renew the TLS certificate",
    "due_at": "2026-03-14T00:00:00Z",
    "webhook_url": "https://hooks.example.com/aigears",
    "notify_emails": ["[email protected]"],
    "tags": ["ops", "security"],
    "escalation_policy": {"steps": [
      {"offset": "-P30D", "channels": ["webhook"]},
      {"offset": "-P7D",  "channels": ["webhook"]},
      {"offset": "-P1D",  "channels": ["webhook"]},
      {"offset": "P0D",   "channels": ["email"]},
      {"offset": "P1D",   "channels": ["email"], "repeat": "daily"}
    ]}
  }'

The runnable version — preview the policy, remember the deadline, then complete it — is examples/python/deadlines_agent.py and examples/typescript/deadlinesAgent.ts:

deadline = remember_deadline(
    client,
    summary="Renew the TLS certificate",
    due_at=due_at,
    webhook_url=webhook_url,
    escalation_policy=_ESCALATION_POLICY,
    tags=["ops", "security"],
)

"Remember to renew the cert by March 14. Warn me at 30, 7 and 1 days, and email ops daily if it goes overdue."

deadline_remember(
  summary="Renew the TLS certificate",
  due_at="2026-03-14T00:00:00Z",
  webhook_url="https://hooks.example.com/aigears",
  notify_emails=["[email protected]"],
  escalation_policy={"steps": [
    {"offset": "-P30D", "channels": ["webhook"]},
    {"offset": "-P7D",  "channels": ["webhook"]},
    {"offset": "-P1D",  "channels": ["webhook"]},
    {"offset": "P0D",   "channels": ["email"]},
    {"offset": "P1D",   "channels": ["email"], "repeat": "daily"}]},
)
  → { "id": "01J9Z8XKQR...", "status": "open",
      "due_at": "2026-03-14T00:00:00Z" }

A new session picks it up

This is the payoff a schedule can't give you. Weeks later a different agent instance — with none of the original context — asks what's on its plate:

deadline_query(window="P30D")
  → [{ "id": "01J9Z8XKQR...", "summary": "Renew the TLS certificate",
       "due_at": "2026-03-14T00:00:00Z", "status": "open" }]

deadline_query (HTTP: POST /v1/deadlines/query/, with a forward window such as P30D) is how past-me hands work to future-me. The commitment survives the context reset; the fresh instance rediscovers it and acts, long before the day-of email would ever have to fire.

Close the loop

When the certificate is renewed, mark it done with a resolution note — deadline_complete(deadline_id=..., resolution_note="certificate renewed") — and the escalation stops. If the renewal is merely delayed rather than done, deadline_snooze pushes an overdue deadline back to open with a new due date instead. The escalation reminders arrive as deadline.escalation webhooks; for how to receive and verify them see Receiving webhooks, and for the full deadline lifecycle see the Deadlines guide.

Next rung

Ask before sending money — when the agent needs a human to say yes before it proceeds.