The /automation/ai/* endpoints turn natural-language descriptions into automation flow JSON. The generator is provider-agnostic — by default it routes through AIService to whichever LLM the org has configured.
Generate a workflow
/automation/ai/generateJWTcurl -X POST https://appengine.appmint.io/automation/ai/generate \
-H "Authorization: Bearer $JWT" \
-H "orgid: $ORG" \
-H "Content-Type: application/json" \
-d '{
"description": "When a contact is created with the newsletter tag, wait one hour and then send them the welcome email template.",
"context": {
"availableDataTypes": ["contact", "lead", "task"],
"availableTemplates": ["welcome", "onboarding-day-1", "trial-ending"]
}
}'
| Field | Type | Description |
|---|---|---|
| description* | string | The plain-English ask. Be specific about trigger, timing, and the action. |
| context.availableDataTypes | string[] | Collections the AI may reference. Helps it pick valid |
| context.availableTemplates | string[] | Notification template IDs the AI may reference. |
| context.customFields | object | Map of |
The response:
{
"workflow": {
"name": "Welcome new newsletter contacts",
"triggers": [
{ "id": "t1", "type": "contact_created", "config": { "tags": ["newsletter"] } }
],
"steps": [
{ "id": "s1", "type": "action", "config": { "actionType": "delay", "duration": 1, "unit": "hours" }, "nextStepId": "s2" },
{ "id": "s2", "type": "action", "config": { "actionType": "send_notification", "deliveryType": "email", "to": "{{contact.email}}", "templateId": "welcome" } }
]
},
"explanation": "Triggers on contact creation when tagged 'newsletter', waits one hour, sends the welcome template.",
"confidence": 0.92,
"suggestions": [
"Consider adding a check_field_value condition to skip contacts who already received the email."
]
}
The workflow is not saved automatically. Inspect it, validate it, and POST /automation to persist. The flow comes back as the data payload — wrap it in BaseModel:
const generated = await api.post('/automation/ai/generate', { description });
const saved = await api.post('/automation', {
datatype: 'automation',
data: { ...generated.workflow, status: 'draft', enabled: true },
});
Improve an existing workflow
/automation/ai/improveJWTSend the current workflow plus optimization goals. The AI returns a refactored version with annotated improvements.
curl -X POST https://appengine.appmint.io/automation/ai/improve \
-H "Authorization: Bearer $JWT" -H "orgid: $ORG" \
-d '{
"workflow": { /* existing */ },
"goals": ["increase engagement", "reduce manual work"]
}'
Response includes improvedWorkflow and a list of improvements: [{type, description, impact}].
Validate a workflow
/automation/ai/validateJWTStatic analysis against the workflow shape — flags broken nextStepId links, missing required config fields, type mismatches. Returns {isValid, errors, suggestions}.
Templates
/automation/ai/templatesJWTReturns curated workflows. Filter by category or industry in the body.
curl -X POST https://appengine.appmint.io/automation/ai/templates \
-H "Authorization: Bearer $JWT" -H "orgid: $ORG" \
-d '{"category": "onboarding"}'
Limitations
- The generator is not deterministic. Two calls with the same description may produce different IDs and slightly different shapes — always validate before saving.
- It only references action/trigger/condition types it knows about (the built-in registry). Custom actions registered at runtime won't appear unless you list them in
context. - The model may hallucinate template IDs and field names. Pass
availableTemplatesandcustomFieldsincontextto constrain it. - Confidence below 0.7 typically indicates the description was ambiguous — re-prompt with more detail.
- AI usage is metered against the org's AI budget. See usage tracking.
Run POST /automation/ai/validate on the returned workflow, then POST /automation/:id/execute against test data before flipping status to active. The start endpoint registers triggers immediately.