Adapter Schema
This is the complete field reference for adapter YAML files. For a narrative guide on how to use these fields, see Agent Adapters. For annotated production examples, see Example Adapters.
Adapters are validated against a JSON schema at agent startup. Typos and missing required fields fail immediately with precise error locations.
Top-level fields
Section titled “Top-level fields”| Field | Type | Required | Description |
|---|---|---|---|
id | string | No | Override for the adapter ID. Defaults to the filename stem (e.g. donetick.yaml -> donetick). Pattern: [a-z0-9][a-z0-9_-]*. Becomes the {webhook_id} segment of the serving URL. |
owner | string | Yes | TipOff user ID that owns this adapter. Becomes the {user_id} segment of the serving URL /webhooks/{user_id}/{webhook_id}. |
id_from | string[] | No | Dot-notation field paths used to generate stable notification IDs via SHA-256(field1 + "\x00" + field2 + ...). Produces gen_ prefixed IDs. |
webhook | object | Yes | Webhook endpoint configuration. See Webhook. |
actions | map[string, Action] | No | Map of action ID to action definition. See Action. |
errors | object | No | Adapter-level error notification handlers. See Error handlers. |
vars | map[string, any] | No | Static data exposed to every expression as vars.*. Use for base URLs, user mappings, feature flags. Secrets should use $\{VAR\} directly, not through vars. |
Webhook
Section titled “Webhook”The webhook endpoint configuration. Serving URL: /webhooks/{owner}/{adapter_id}/*.
| Field | Type | Required | Description |
|---|---|---|---|
auth | object | No | Composable authentication layers. See Auth. Zero layers = unsigned (logged as WARN). |
fetches | Fetch[] | No | Shared fetches run once per inbound event. Available to all notification entries as fetched.<name>. See Fetch. |
notifications | Notification[] | Yes | One or more notification entries. At least one required. See Notification. |
log_requests | string | No | When to include full request detail in structured logs. Enum: always, on_filter, on_error, never. Overrides the agent-wide TIPOFF_AGENT_LOG_REQUESTS default. |
Notification
Section titled “Notification”One entry in webhook.notifications[]. Two mutually exclusive modes:
- Body mode (
body+actionsrequired): creates or updates a visible notification - Signal mode (
signalrequired): sends a signal about an existing notification (e.g."clear")
| Field | Type | Required | Description |
|---|---|---|---|
if | string | No | Expr expression returning bool. Entry fires only when true. Absent = always fires. Context: payload, vars, now. |
id | string | Yes | Expr expression returning a stable, non-empty string. Used for upsert (body mode) or to identify the target (signal mode). Context: payload, vars, now. |
signal | string | Signal mode | Signal to send. Currently supported: "clear". Mutually exclusive with body/actions. |
actions | string[] | Body mode | Action IDs this notification exposes as buttons. Each must exist in the adapter’s actions map. Pattern per item: [a-z0-9][a-z0-9_]*. |
fetches | Fetch[] | No | Per-entry fetches. Run only when this entry matches. Results are merged with webhook-level fetches. See Fetch. |
let | LetBinding[] | No | Computed bindings evaluated after fetches, before body. See Let bindings. |
body | string | Body mode | Expr expression producing the notification object. Must NOT include category (injected by the agent). Context: payload, id, vars, fetched, now, plus any let bindings. |
Action
Section titled “Action”One entry in the actions map. Combines the button definition (title, traits, params) with the handler logic (fetches, let, request).
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | Button label displayed to the user. Never inherited via extends. |
extends | string | No | Action ID of the base action to inherit from (same adapter). Inherits fetches, request, traits, let, on_error. Target must not itself extend. Pattern: [a-z0-9][a-z0-9_]*. |
traits | string[] | No | Semantic traits for client rendering: confirm, destructive, auth_required, defer. Inherited via extends if not declared. |
params | map[string, any] | No | Static parameters available as action.* in the request expression. Never inherited via extends. |
fetches | Fetch[] | No | HTTP requests run before the request expression. Inherited via extends if not declared. See Fetch. |
let | LetBinding[] | No | Computed bindings evaluated after fetches, before request. Merged by name when inherited via extends. See Let bindings. |
request | string | Yes* | Expr expression producing {method, url, headers?, body?}. *Inherited via extends if not declared. Context: state, action, user, vars, fetched, now, plus any let bindings. |
on_error | object | No | Per-action error handler. Inherited via extends if not declared. See Error handlers. |
Extends inheritance rules
Section titled “Extends inheritance rules”titleandparams: never inherited — every action declares its ownfetches,request,traits,on_error: inherited if not declared on the extending action; declaring the field replaces the inherited value entirelylet: merged by name — matching names override in-place (same position in sequence), new names append at the end- Chains forbidden: the target must not itself use
extends - Same adapter: the target must exist in the same adapter file
Let bindings
Section titled “Let bindings”Ordered list of named computed values. Each binding is evaluated sequentially — later bindings can reference earlier ones. Bound names are available as bare identifiers in the body or request expression.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Binding name. Must be a valid identifier ([a-zA-Z_][a-zA-Z0-9_]*). Must not shadow built-in names. Must be unique within the block. |
expr | string | Yes | Expr expression whose result is bound to the name. |
Reserved names
Section titled “Reserved names”Names that cannot be used as let binding names:
| Context | Reserved |
|---|---|
| Notification | payload, id, vars, fetched, now |
| Action | state, action, user, vars, fetched, now |
Validation rules
Section titled “Validation rules”- Forward references rejected: a binding can only reference names defined above it in the sequence
- Duplicates rejected: each name must be unique within a single
letblock - Reserved names rejected: binding names matching built-in environment variables are rejected
- All validation happens at adapter load time (agent startup), not at webhook delivery time
HTTP request run before expression evaluation. Available at webhook level (shared), per-notification, and per-action.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Identifier for the result. Available as fetched.<name> in expressions. Pattern: [a-zA-Z_][a-zA-Z0-9_]*. |
method | string | Yes | HTTP method. Enum: GET, POST, PUT, PATCH, DELETE. |
url | string | Yes | URL with optional {{ expr }} interpolation. |
headers | map[string, string] | No | Header values with optional {{ expr }} interpolation. |
optional | boolean | No | Default: false. When true, a failed fetch binds fetched.<name> to nil and continues. When false, a failed fetch aborts the pipeline. |
Fetch result shape
Section titled “Fetch result shape”Each fetched.<name> entry has the following shape at runtime:
| Field | Type | Description |
|---|---|---|
status | int | HTTP status code |
headers | map[string, string] | Response headers |
data | any | Parsed JSON response body |
raw | string | Raw response body |
Composable webhook authentication. At least one auth layer is required. Three independently optional layers — all present layers must pass.
Unsigned
Section titled “Unsigned”If your webhook source cannot provide authentication, explicitly opt in with unsigned: true:
| Field | Type | Required | Description |
|---|---|---|---|
unsigned | boolean | No | Set to true to accept unsigned webhooks. Adapters without any auth layer will fail to load unless this is set. |
Bearer
Section titled “Bearer”Shared secret via header or URL path. Exactly one of header or path must be set.
| Field | Type | Required | Description |
|---|---|---|---|
header | string | XOR with path | HTTP header name containing the secret. |
path | boolean | XOR with header | When true, the trailing URL segment is the secret. |
secret | string | Yes | Expected secret value. Typically $\{VAR\}. |
Signature
Section titled “Signature”HMAC message integrity verification.
| Field | Type | Required | Description |
|---|---|---|---|
algorithm | string | Yes | Signing algorithm. Currently only hmac-sha256. |
header | string | Yes | Header containing the signature. |
secret | string | Yes | HMAC key. |
Replay
Section titled “Replay”Freshness check via timestamp.
| Field | Type | Required | Description |
|---|---|---|---|
mode | string | Yes | Currently only timestamp. |
header | string | Yes (when mode=timestamp) | Header containing the timestamp. |
tolerance | string | Yes (when mode=timestamp) | Go duration string (e.g. "300s", "5m"). |
Error handlers
Section titled “Error handlers”Optional error notification handlers defined at adapter level (errors.webhook, errors.action) or per-action (on_error). The agent injects category: agent_error automatically.
| Field | Type | Required | Description |
|---|---|---|---|
fetches | Fetch[] | No | Additional fetches to run on error. |
body | string | Yes | Expr expression producing the error notification object. |
Error context variables
Section titled “Error context variables”| Variable | Type | Description |
|---|---|---|
error.phase | string | Where the failure occurred: auth, parse, id, fetch, expr, schema, call |
error.message | string | Error message |
error.step | any | Phase-specific detail (e.g. HTTP status code for call) |
adapter | string | Adapter ID |
payload | map | Webhook payload (may be nil for action errors) |
state | map | Action state (may be nil for webhook errors) |
action | map | Action metadata (action errors only) |
user | string | TipOff user ID (action errors only) |
vars | map | Adapter vars |
fetched | map | Fetch results available at the point of failure |
now | Time | Current time |
Expression context summary
Section titled “Expression context summary”Quick reference for which variables are available in each expression context.
| Variable | if / id | body | request | Error handlers |
|---|---|---|---|---|
payload | yes | yes | - | yes (may be nil) |
id | - | yes | - | yes |
vars | yes | yes | yes | yes |
fetched | - | yes | yes | yes |
now | yes | yes | yes | yes |
state | - | - | yes | yes (may be nil) |
action | - | - | yes | yes (may be nil) |
user | - | - | yes | yes (action only) |
error | - | - | - | yes |
adapter | - | - | - | yes |
let bindings | - | yes | yes | - |