> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aion.to/llms.txt
> Use this file to discover all available pages before exploring further.

# Cron

> Cron origin and UTC firing and dispatch timestamps for scheduled A2A messages.

**Metadata**

| Field | Value |
| - | - |
| Canonical URI | `https://docs.aion.to/a2a/extensions/aion/cron/1.0.0` |
| Issuer | `aion` |
| Version | `1.0.0` |
| Activation | This extension will automatically activate if detected in request regardless of explicit activation. |
| Related Extensions | [Daemon](/a2a/extensions/aion/daemon/1.0.0) |

## Overview

The Cron extension identifies an A2A request as a scheduled invocation. It carries the intended firing time and the
producer's dispatch time in UTC. The configured message content stays in the ordinary message parts.

This is a metadata-only extension. It adds no RPC operation, Event-extension dependency, response destination, or
delivery guarantee. It does not expose schedule configuration, timezone names, or attachment/occurrence identifiers.

### Eligible Behaviors

Aion permits Cron Attachments only on Behaviors with exactly one enabled primary A2A endpoint using the
`a2a.daemon` capability. The receiver's agent card must advertise Cron support before an attachment can be added.
See [Daemon](/a2a/extensions/aion/daemon/1.0.0) for authenticated automation access.

Distributions, including A2A and Aion Chat distributions, cannot own Cron Attachments because they do not define a
destination for the scheduled response. Advertising this extension does not change that restriction.

## Agent Card Declaration

Declare support as optional so ordinary messages do not need Cron metadata:

```json theme={null}
{
  "capabilities": {
    "extensions": [
      {
        "uri": "https://docs.aion.to/a2a/extensions/aion/cron/1.0.0",
        "description": "Receive scheduled messages with cron provenance.",
        "required": false
      }
    ]
  }
}
```

The Aion Python SDK advertises this optional support through its built-in extension registry. Other receivers must
implement and advertise the contract themselves. Deploy updated receivers and refresh their discovered cards before
attaching Cron.

## Activation

Cron dispatch explicitly includes the canonical URI in the `A2A-Extensions` request header, alongside any other
requested extensions:

```http theme={null}
A2A-Extensions: https://docs.aion.to/a2a/extensions/aion/cron/1.0.0
```

The SDK also detects the request metadata key without an explicit activation header. It validates the payload before
confirming activation. A header alone does not supply the required payload. Missing or malformed Cron metadata on an
activating request fails validation with `InvalidParams`; it is not acknowledged as activated.

Advertising support does not activate ordinary messages. Aion adds Cron metadata and requests activation only for an
actual scheduled dispatch, not for a preview or ordinary self-A2A request.

## Payloads

### CronPayload

`CronPayload` describes the intended firing and actual dispatch of one scheduled invocation. The name identifies
the payload shape; it is not an additional JSON wrapper or discriminator.

Placement summary:

* `CronURI`: `https://docs.aion.to/a2a/extensions/aion/cron/1.0.0`
* Payload location: `SendMessageRequest.metadata[CronURI]`
* JSON-RPC location: `params.metadata[CronURI]`
* HTTP+JSON location: the request body's `metadata[CronURI]`
* Activation location: `A2A-Extensions`

Do not duplicate the payload in `message.metadata`. Both `SendMessage` and `SendStreamingMessage` use this shape.
Cron does not require a part-level `schema` reference or an Event payload.

#### Payload Shape

```json theme={null}
{
  "scheduledAt": "2026-09-28T16:00:00Z",
  "sentAt": "2026-09-28T16:00:03Z"
}
```

#### Fields

| Field | Type | Required | Description |
| - | - | - | - |
| `scheduledAt` | `String` | required | Intended firing instant in UTC, with a `Z` suffix. |
| `sentAt` | `String` | required | Producer dispatch handoff instant in UTC, with a `Z` suffix. |

Both fields are required. Invalid timestamps or timestamps without a UTC `Z` suffix are rejected. Receivers do not
need a timezone database or Cron expression parser. Both recurring and one-time schedules use the same wire shape.
The Python SDK represents this payload as `CronExtensionV1`, with fields `scheduled_at` and `sent_at`.

## Processing Rules

* Use the accepted occurrence's intended firing time for `scheduledAt`. A later schedule edit must not change it.
* Sample `sentAt` immediately before producer dispatch, after durable preparation, not when the firing is claimed.
  An overdue occurrence can have a substantially earlier `scheduledAt` than `sentAt`.
* Preserve existing request metadata, message content, and other extension declarations when adding Cron metadata.
* Keep normal authentication and Behavior response routing. Neither timestamp selects a response destination or
  proves remote receipt, execution, or completion.
* Let the receiving implementation decide whether to use the metadata in a prompt or copy it into a response.
  The extension requires neither automatic prompt injection nor a metadata echo.

### Response Acknowledgment

Return confirmed activation in the `A2A-Extensions` response header. Do not infer confirmation from agent-card support
or simply echo requested extensions. For streaming responses, confirm activation before sending headers, without
waiting for the first event. Empty streams can therefore acknowledge activation too.

Aion preserves this acknowledgment through its JSON-RPC and HTTP+JSON bindings. The Python SDK server exposes
JSON-RPC. Reading stored history does not count as a new Cron activation.

### Message Provenance

New agent messages produced by the invocation carry confirmed extension URIs in `Message.extensions`. Merge and
deduplicate these URIs without relabeling user messages or earlier history. For returned Task snapshots and resumed
tasks, Aion preserves receiver annotations rather than assuming every message belongs to the current invocation.
Stored history and resubscriptions retain the original message annotations.

A Task response without a new message does not need a synthetic message to carry the URI. Copying the Cron payload
into response metadata is separate and optional. The SDK initializes new Task metadata from request metadata, so
request metadata must not be assumed to be transient.

## Example: Cron SendMessage

This JSON-RPC example isolates the Cron fields sent to a receiver. The URL and token are placeholders. Include any
additional authentication and [Daemon context](/a2a/extensions/aion/daemon/1.0.0) required by your target; those fields
are omitted here, not bypassed by the extension.

```http theme={null}
POST /a2a HTTP/1.1
Host: agent.example.com
Content-Type: application/json
Authorization: Bearer <aion-token>
A2A-Extensions: https://docs.aion.to/a2a/extensions/aion/cron/1.0.0
```

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": "cron-example",
  "method": "SendMessage",
  "params": {
    "message": {
      "messageId": "40000000-0000-0000-0000-000000000004",
      "role": "ROLE_USER",
      "parts": [{ "text": "Run the daily report." }]
    },
    "metadata": {
      "https://docs.aion.to/a2a/extensions/aion/cron/1.0.0": {
        "scheduledAt": "2026-09-28T16:00:00Z",
        "sentAt": "2026-09-28T16:00:03Z"
      }
    }
  }
}
```

After the receiver validates the payload, its response includes the confirmed extension header:

```http theme={null}
A2A-Extensions: https://docs.aion.to/a2a/extensions/aion/cron/1.0.0
```

This confirms extension activation, not task completion. The response body still uses the normal A2A Message, Task,
or streaming event format.
