Skip to content

Connector Manifest

A connector is one named integration. A Workfile calls it as connector.action, and reaches it through a connection. A connector’s manifest is the document that declares it: its authentication, the parameters of a connection, its actions, and its triggers. A catalog publishes and versions manifests. Filter packages have manifests of their own. A schema overlay is one connection’s refinement of a manifest, and is not itself a manifest. Elsewhere in this specification, “the manifest” means the connector manifest of the action or trigger under discussion.

A conforming implementation MUST validate Workfiles against manifests in this format. The manifest key reference indexes the same keys in a table. Where it and this page disagree, this page governs.

Every name that a manifest or an overlay declares — a connector, an action, a trigger, a connection parameter, an input field, an output field, or a schema — MUST match ^[a-z][a-z0-9_]*$. A vendor field whose name is outside that shape is mapped by the executor, or is reached by indexing with a string literal.

manifest: 1
connector: helpdesk
version: 2.1.0
auth:
type: oauth2
scopes: [profile.read] # baseline: required by every action and trigger
connection:
subdomain:
type: "string"
required: true
in: host # contributes to the address
pattern: "^[a-z0-9-]+$"
source: user # user | auth
prompt: "Your helpdesk subdomain"
actions:
new_ticket:
scopes: [tickets.write] # required by this action alone
input:
queue: { type: "enum[tier1, tier2, billing]", required: true }
subject: { type: "string", max_length: 255, required: true }
body: { type: "string" }
files: { type: "list[file]" }
output:
id: { type: "string" }
url: { type: "string" }
idempotent: true
idempotency_param: external_id
deterministic: false
validated_output: true
rate_limit: { rps: 10, burst: 20 }
retry: { attempts: 3, backoff: exponential, initial: 1s, max: 60s }
errors:
"429": { class: retryable }
"409": { class: fatal, message: "A ticket already exists for this external_id" }
"5xx": { class: retryable }
sample: fixtures/new_ticket.json
triggers:
ticket_updated:
kind: webhook # webhook | poll | schedule | manual
scopes: [tickets.read]
binds: ticket # default binding name; `as` overrides
correlate_on: [external_id] # fields a suspended run must match
output: { $ref: "#/schemas/ticket" }
sample: fixtures/ticket_updated.json

Field declarations. A field declaration describes one typed value. The same form declares an action’s input and output fields, a trigger’s output fields, a connection parameter, a Workfile’s inputs, a state’s accepts, an agent step’s returns, and an overlay’s fields. Its keys are a closed set.

Key Meaning
type REQUIRED unless $ref is present. A type expression.
$ref REQUIRED unless type is present. A local pointer to a named schema.
required Boolean. The default is false.
default A literal of the declared type, supplied when no value is given.
pattern An RE2 pattern that a string value MUST satisfy.
max_length A positive integer bounding the length of a string or a list.

Implementations MUST reject an unknown key in a field declaration. Implementations MUST reject a field that declares both type and $ref, a field that declares neither, and a field that declares both required: true and default.

A connection parameter takes three further keys, defined below: source, prompt, and in.

Scopes. auth.scopes is the baseline: the scopes that every action and trigger of the connector requires. An action or a trigger declares in its own scopes the further scopes that it alone requires. An entry that declares no scopes requires the baseline alone. The set that a Workfile requires is therefore the baseline plus the scopes of the actions and triggers that the file names, and nothing more. Scope strings are opaque to this standard, and the connector’s auth.type gives them meaning.

An implementation that can read a connection’s granted scopes MUST verify the required set before any action executes. It MUST reject a file that names an action or a trigger whose scopes the connection does not grant. The diagnostic MUST name the step and the missing scope.

Note: the required set is computable from a Workfile and its manifests alone, so a tool can request exactly that set when it authorizes a connection.

Connection parameters. connection declares the values that one connection supplies beyond its credentials: a subdomain in the host, an account identifier in the path, a regional endpoint. They are configuration rather than secrets, and they differ per connection. A parameter declaration is a field declaration with three further keys.

source declares where the value comes from. user means that the account holder supplies the value when the connection is created. auth means that the authorization flow returns the value, as an instance URL arrives with an access token. The default is user. An account holder cannot supply a source: auth value, so a manifest that declares one states a fact about the authorization flow.

prompt is the text that a tool shows when it asks for a source: user value.

in declares that the parameter contributes to the address that the implementation contacts. The defined values are host and path. An absent in means that the parameter contributes to neither. This standard defines no address for any connector, so in declares the security-relevant fact alone.

A connection is complete when it holds a value for every required parameter. Implementations MUST reject a run whose resolved connection is incomplete. Implementations MUST validate every parameter value against its declared type, and against its pattern where the manifest declares one.

A parameter with in: host MUST declare a pattern, and implementations MUST reject a manifest that omits it. The pattern bounds the addresses toward which a connection can direct the connector. A connector whose address the operator chooses declares self_hosted: true at the top level of its manifest:

manifest: 1
connector: ticketing
version: 1.0.0
self_hosted: true
connection:
base_url: { type: "string", required: true, in: host, source: user }

Such a connector MAY declare a host parameter with no pattern. Implementations MUST apply a deployment-configured host policy to a self-hosted connection. By default, that policy SHOULD exclude addresses that resolve to private, loopback, or link-local ranges.

Connection parameters are not in scope for expressions. A Workfile names a connection in its triggers and steps, and never reads that connection’s configuration, so a file stays portable across the connections of its connectors.

Triggers. binds is REQUIRED on every trigger, and MUST match ^[a-z][a-z0-9_]*$. It is what allows as to be omitted.

input declares the configuration keys that an on entry supplies, as field declarations. Implementations validate the on entry against it. A trigger that declares no input takes no configuration.

correlate_on names the payload fields by which an event is matched to a suspended run.

kind is one of webhook, poll, schedule, and manual. A poll trigger owns its cursor: the position from which the next poll resumes is trigger state that the implementation holds. That state is not visible to a Workfile, and a Workfile cannot change it.

Errors. errors makes retry behavior a property of the dependency rather than a guess by the author. Each key is an error code that the connector produces. A key of the form <digit>xx matches any three-character code that begins with that digit. An exact key takes precedence over a pattern key. Each value is a map with a required class and an optional message.

class Meaning
retryable Re-issuing the action can succeed.
fatal Re-issuing the action cannot succeed.
unknown The outcome is ambiguous, and on_unknown applies.

An error code that the table does not name is classified unknown.

Retry. retry declares the action’s default policy. attempts is a positive integer, and counts the first attempt. backoff is one of none, fixed, and exponential. initial and max are durations. Implementations MAY apply jitter, and MUST record the delay that they applied. A step’s retry modifier overrides this policy.

rate_limit declares the vendor’s published limit. Implementations SHOULD respect it. It does not affect the result of a run.

sample names a recorded example of an action’s output or a trigger’s payload. Tools and the conformance suite use it. It is not a schema.

Promises. Manifest booleans are promises. The absence of a promise is the safe default: not idempotent, not deterministic, not validated. Every promise has a defined operational consequence.

idempotent and idempotency_param gate the checks in undo and on_unknown. Declared together, they promise idempotency per key: re-issuing the action with one key produces one effect. idempotent: true with no idempotency_param promises natural idempotency: re-issuing the action with identical arguments produces the effect of one issue. A read, a plain overwrite, and an HTTP GET are of this kind.

deterministic: true promises that the action returns the same result for identical arguments. The default is false, and a generative model, a random identifier, and a time-dependent lookup all keep it. The promise gates caching only. Implementations MAY cache or deduplicate a deterministic action’s results under an explicitly declared cache key. They MUST NOT cache the results of any other action. Recording for replay applies to every action regardless.

validated_output: true promises that the action’s result satisfies the declared output schema. Implementations MUST validate such an action’s result against the schema before they bind it. A violation is an error on that step, classified by the manifest’s errors table. Only an action with this flag MAY be the subject of an exhaustively-checked route.