Project structure
FlowApps are located inIqraInfrastructure/Managers/FlowApp/Apps/:
Step 1: Create the main app class
Create a class that implementsIFlowApp:
IqraInfrastructure/Managers/FlowApp/Apps/CalCom/CalComApp.cs
The
AppKey must be unique across all FlowApps. Use lowercase snake_case by convention.Constructor dependencies
You can inject any registered service:IHttpClientFactory- For making HTTP requestsILogger<T>- For logging- Custom services from your DI container
Step 2: Define an action
Actions perform the actual work. Create a partial class implementingIFlowAction:
IqraInfrastructure/Managers/FlowApp/Apps/CalCom/Actions/BookMeetingAction.cs
Output ports
Output ports define the possible execution paths:IqraInfrastructure/Managers/FlowApp/Apps/CalCom/Actions/BookMeetingAction.cs:24-32
- success: API call succeeded
- conflict: Specific error case (slot unavailable)
- error: Generic failure (handled automatically by
ActionExecutionResult.Failure)
Step 3: Create the JSON schema
Create a schema file with the same base name as your action (e.g.,BookMeetingAction.cs → BookMeeting.json):
IqraInfrastructure/Managers/FlowApp/Apps/CalCom/Actions/BookMeeting.json
The
x-fetcher property links a field to a data fetcher for dynamic dropdowns. See Schema Definition for details.Step 4: Create a data fetcher
Data fetchers populate dynamic dropdowns:IqraInfrastructure/Managers/FlowApp/Apps/CalCom/Fetchers/GetEventTypesByIdFetcher.cs
context parameter contains the current form state, allowing dependent fetchers:
Step 5: Build and test
1
Build the project
The
FlowAppSchemaGenerator runs at build time and generates the GetInputSchemaJson() method:Generated code
2
Verify discovery
Check the logs on startup:If your app isn’t discovered, verify:
- Class implements
IFlowApp - Class is not abstract or an interface
- Class is in the same assembly as
FlowAppManager
3
Test in the UI
- Configure credentials in the admin dashboard
- Create a new agent script
- Add your FlowApp action to the flow
- Fill in the form and test execution
Public apps (no authentication)
For apps that don’t require credentials:RequiresIntegration = false in your actions:
Best practices
Use descriptive action and fetcher keys
Use descriptive action and fetcher keys
- Good:
BookMeeting,GetEventTypes,SendEmail - Bad:
Action1,Fetch,DoStuff
Define meaningful output ports
Define meaningful output ports
Use specific ports for common error cases:This allows agents to handle errors gracefully.
Return structured data in results
Return structured data in results
Include relevant data in the result for downstream nodes:
Handle rate limits and retries
Handle rate limits and retries
Implement retry logic with exponential backoff:
Log errors with context
Log errors with context
Use structured logging:
Next steps
Schema definition
Learn advanced schema features like conditional fields, dynamic fetchers, and custom validation