Documentation

AI-generated workflows

Describe an automation in plain English and get a workflow JSON back.

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

POST/automation/ai/generateJWT
curl -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"]
    }
  }'
FieldTypeDescription
description*string

The plain-English ask. Be specific about trigger, timing, and the action.

context.availableDataTypesstring[]

Collections the AI may reference. Helps it pick valid datatype values.

context.availableTemplatesstring[]

Notification template IDs the AI may reference.

context.customFieldsobject

Map of datatype[fieldNames]. Lets the AI use real custom fields.

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

POST/automation/ai/improveJWT

Send 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

POST/automation/ai/validateJWT

Static analysis against the workflow shape — flags broken nextStepId links, missing required config fields, type mismatches. Returns {isValid, errors, suggestions}.

Templates

POST/automation/ai/templatesJWT

Returns 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 availableTemplates and customFields in context to 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.
Always validate before activating

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.