subscribes
The subscribes surface declares which events a machine listens for. When another machine publishes a matching event, this machine is invoked with the event payload as input. This is the consumer side of mashin’s event-driven architecture.
Overview
Subscriptions are reactive: the machine does not poll for events. When a matching event is published, the cell’s event bus routes the event payload to this machine, which runs through the full governance pipeline before executing. Subscriptions can match exact event names or use wildcard patterns.
Unlike webhook (which receives events from external services), subscribes receives events from other mashin machines within the same cell or across cells connected via Kortex.
Syntax
expresses subscribes order.created handler: "process_new_order" order.shipped handler: "send_tracking_email"A complete machine with a subscribes surface:
machine order_notifier
accepts order_id as text, is required customer_id as text, is required
responds with notification_sent as boolean
ensures permissions allowed to reason, http
implements ask compose, using: "anthropic:claude-haiku-4-5" with task "Compose a notification for order ${input.order_id}" returns subject as text body as text assuming subject: "Order confirmed" body: "Your order ORD-2847 has been confirmed."
ask send, from: "@mashin/actions/http/post" url: "https://api.internal.com/notifications" body: {to: input.customer_id, subject: steps.compose.subject, body: steps.compose.body} returns sent as boolean assuming sent: true
compute result {notification_sent: steps.send.sent}
expresses subscribes order.created handler: "main" order.shipped handler: "main"Configuration options
| Config | Required | Default | Description |
|---|---|---|---|
| Event pattern | Yes | - | Event name or wildcard pattern to subscribe to |
handler | No | "main" | Which chain in the machine handles this event |
Event patterns
Subscriptions support exact names and wildcard patterns:
| Pattern | Matches |
|---|---|
order.created | Exactly order.created |
order.* | order.created, order.shipped, order.cancelled, etc. |
billing.** | billing.invoice.paid, billing.subscription.cancelled, etc. (recursive) |
Single * matches one segment. Double ** matches one or more segments.
Handler
The handler field specifies which chain in the machine processes the event. For single-chain machines, this defaults to "main". For multi-chain machines, different events can route to different chains.
Payload mapping
The event payload is mapped to the machine’s accepts section. Field names in the event schema must match field names in accepts. Extra fields are ignored. Missing required fields cause a validation error recorded in the ledger.
Governance
Every event-triggered invocation is governed:
- The event is received from the event bus
- The payload is validated against the machine’s
acceptscontract - Governance permissions from
ensuresare checked - The machine executes
- A
SurfaceAccessevent is recorded with:subscribessurface in the behavioral ledger - The result is available to the event bus (for chaining)
A machine that subscribes to events but lacks the necessary permissions in ensures will have every invocation denied by governance. The denial is recorded, and the event is not re-delivered.
Example
Subscribing to wildcard patterns:
machine audit_logger
accepts event_name as text event_data as map
responds with logged as boolean
implements ask log, from: "@mashin/actions/http/post" url: "https://audit.internal.com/events" body: {event: input.event_name, data: input.event_data} returns logged as boolean assuming logged: true
expresses subscribes order.** handler: "main" payment.** handler: "main"This machine receives every event in the order and payment domains and logs them to an audit service.