Triggers
Triggers define how a flow is initiated. Every flow has exactly one trigger method, decorated with @HttpTrigger, @ManualTrigger, @RecurrenceTrigger, or @ConnectorTrigger.
Trigger options can be passed either as an argument to the decorator, or returned as an object literal from the trigger method body — both forms are supported, and body values take precedence over decorator arguments if both are given:
// Decorator argument form
@RecurrenceTrigger({ frequency: 'Day', interval: 1 })
trigger() {}
// Return-statement form (equivalent)
@RecurrenceTrigger()
trigger() {
return { frequency: 'Day', interval: 1 };
}
The decorator argument is type-checked against the options listed below. The options in Settings for every trigger and a few trigger-specific ones are read by the compiler but are not part of the typed decorator options, so write them in the return-statement form, as generated DSL does.
HTTP Trigger
Starts the flow when an HTTP request is received.
@HttpTrigger({ method: 'POST' })
trigger() {}
Options (HttpTriggerOptions)
method?— HTTP method (GET,POST,PUT,DELETE,PATCH, ...); defaults to POST when omittedpath?— relative pathschema?— JSON schema for the request body:{ type, properties?, required? }
Also read from the return-statement form:
triggerKind?—'Http'(the default) or'VirtualAgent'for a flow called from Copilot Studio. A'VirtualAgent'response needs this trigger kind (DSL044).headersSchema?— JSON schema for the request headerstriggerAuthenticationType?— written to the trigger'sinputs.triggerAuthenticationTypein Logic Apps JSON
Manual Trigger
Starts the flow via a manual invocation — the "Button" trigger in Power Automate, a Power Apps call, or a parent flow's "Run a Child Flow".
@ManualTrigger()
trigger() {
return {
schema: {
type: 'object',
properties: {
text: { type: 'string', title: 'Input', 'x-ms-dynamically-added': true },
},
required: [],
},
};
}
Options (ManualTriggerOptions)
schema?— JSON schema for trigger inputs:{ type, properties?, required? }
Also read from the return-statement form:
triggerKind?—'Button'(the default) or'PowerAppV2'("When Power Apps calls a flow (V2)")headersSchema?,triggerAuthenticationType?— as for the HTTP trigger
A 'PowerApp' response (ctx.response(..., 'PowerApp')) belongs with this trigger (DSL044).
For inputs to appear in the Power Automate maker portal designer, every property under schema.properties must include "x-ms-dynamically-added": true. Without it, the designer silently hides the input (the flow still runs, but makers can't see/edit the parameter).
Recurrence Trigger
Starts the flow on a schedule.
@RecurrenceTrigger({
frequency: 'Day',
interval: 1,
timeZone: 'Eastern Standard Time',
schedule: { hours: [9], minutes: [0] },
})
trigger() {}
Options (RecurrenceTriggerOptions)
frequency—'Second' | 'Minute' | 'Hour' | 'Day' | 'Week' | 'Month' | 'Year'interval— number of frequency units between runstimeZone?— e.g.'Eastern Standard Time'startTime?— ISO 8601 start timeschedule?— fine-grained schedule:minutes?: number[]hours?: number[]weekDays?: ('Monday' | 'Tuesday' | 'Wednesday' | 'Thursday' | 'Friday' | 'Saturday' | 'Sunday')[]monthDays?: number[]
Rules Power Automate enforces on save
The editor checks these as you type (DSL045, DSL046; RECURRENCE / RECURRENCE_SCHEDULE on JSON):
intervalis a whole number, and the period is at most 500 days (for example at most 500 forDay, 71 forWeek, 16 forMonth, 1 forYear).- A
scheduleneedsfrequencyDay,WeekorMonth. weekDaysneedsfrequency: 'Week';monthDaysneedsfrequency: 'Month'.- A scheduled recurrence must next run within 18 months, and
startTimemay be at most 49 years ahead.
A flow with a recurrence trigger has no caller, so it cannot use ctx.response() (DSL038). The same applies to a polling connector trigger.
Connector Trigger
Starts the flow off a connector event, such as "when a SharePoint item is created" or "when a new email arrives."
/** @trigger When_an_item_is_created */
@ConnectorTrigger({
connector: 'sharepoint',
operation: 'GetOnNewItems',
params: {
dataset: 'https://contoso.sharepoint.com/sites/MySite',
table: '{list-guid}',
},
connectionReferenceName: 'shared_sharepointonline',
splitOn: '@triggerBody()?[\'value\']',
recurrence: { interval: 1, frequency: 'Minute' },
})
trigger() {}
Options (ConnectorTriggerOptions)
connector— connector name (e.g.'sharepoint','office365')operation— the connector's trigger operation ID (e.g.'GetOnNewItems','OnNewEmailV3')params— operation-specific parameters (connector/operation dependent)connectionReferenceName?— connection reference to usesplitOn?— property to split trigger results on, so the flow runs once per itemrecurrence?— polling interval:{ interval: number; frequency: string }. A trigger with a recurrence is treated as a polling trigger by the placement rules (noctx.response(),DSL038).
Also read from the return-statement form:
triggerType?— the Logic Apps trigger type:'OpenApiConnection','OpenApiConnectionWebhook'or'OpenApiConnectionNotification'(the default when omitted). Use the type the operation has in Power Automate; DSL generated from an existing flow keeps the original.authentication?— the authentication expression, usually"@parameters('$authentication')"retryPolicy?— the trigger's retry policy (same rules as@retryPolicy)
Use the /** @trigger Name */ JSDoc comment above the decorator to control the generated trigger's name (otherwise it defaults to the operation name). @trigger also works on @RecurrenceTrigger (default name Recurrence). HTTP and manual triggers are always named manual.
Connector triggers are compiled into the flow definition but do not fire locally: to run such a flow, pass the event's payload as the trigger body with --in.
Dataverse row events
The Dataverse "When a row is added, modified or deleted" trigger takes numeric codes. Write them with the built-in enums DataverseMessage, DataverseScope and DataverseRunAs (available in every .ff.ts file without an import); they compile to the numbers:
@ConnectorTrigger()
trigger() {
return {
connector: 'dataverse',
operation: 'SubscribeWebhookTrigger',
params: {
'subscriptionRequest/message': DataverseMessage.Added,
'subscriptionRequest/entityname': 'account',
'subscriptionRequest/scope': DataverseScope.Organization,
},
connectionReferenceName: 'shared_commondataserviceforapps',
triggerType: 'OpenApiConnectionWebhook',
};
}
| Enum | Members |
|---|---|
DataverseMessage (subscriptionRequest/message) | Added (1), Deleted (2), Modified (3), AddedOrModified (4), AddedOrDeleted (5), ModifiedOrDeleted (6), AddedModifiedOrDeleted (7) |
DataverseScope (subscriptionRequest/scope) | User (1), BusinessUnit (2), ParentChildBusinessUnit (3), Organization (4) |
DataverseRunAs (subscriptionRequest/runas) | ModifyingUser (1), RowOwner (2), FlowOwner (3) |
Settings for every trigger
All four trigger decorators also read these settings from the return-statement form:
conditions?— trigger conditions, as[{ expression: '@...' }]. The flow only starts when every condition is true.runtimeConfiguration?— for example{ concurrency: { runs: 1 } }to allow one run at a time (1–100,TRIGGER_CONCURRENCY)correlation?— the trigger's correlation settings, passed through to Logic Apps JSON
@ManualTrigger()
trigger() {
return {
triggerKind: 'PowerAppV2',
schema: {
type: 'object',
properties: {
text: { type: 'string', title: 'Input', 'x-ms-dynamically-added': true },
},
required: [],
},
conditions: [{ expression: "@not(empty(triggerBody()?['text']))" }],
runtimeConfiguration: { concurrency: { runs: 1 } },
};
}
A // comment or @description above the trigger method becomes the trigger's description.
Accessing Trigger Data
Use ctx.triggerBody() or ctx.triggerOutputs() to access trigger input data within actions.
@Action()
async processRequest(ctx: FlowContext) {
await ctx.compose('Order_id', ctx.triggerBody()?.['orderId']);
await ctx.compose('Caller', ctx.triggerOutputs()?.['headers']?.['x-ms-user-email']);
}
The trigger outputs are { headers, body }: ctx.triggerBody() is the body, and ctx.triggerOutputs() has both. In a local run, the payload you pass with --in is the body. See Cloud Semantics for the exact shape, how to pass request headers, and raw form or multipart bodies.