Automation API
Create and manage automations to automate business logic and workflows
Automations allow you to define workflows that automatically execute actions when specific triggers occur. Use automations to streamline repetitive tasks, enforce business rules, and integrate with external systems.
Overview
An automation consists of three parts:
- Trigger - What starts the automation (e.g., a record is created)
- Conditions - Optional rules that determine if the automation should run
- Actions - What happens when the automation executes
Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /automations | List all automations |
| GET | /automations/:id | Get a single automation |
| POST | /automations | Create an automation |
| PATCH | /automations/:id | Update an automation |
| DELETE | /automations/:id | Delete an automation |
| POST | /automations/:id/enable | Enable an automation |
| POST | /automations/:id/disable | Disable an automation |
| GET | /automations/:id/logs | Get execution logs |
| POST | /automations/:id/test | Test automation (dry run) |
List Automations
Retrieve all automations in your workspace.
curl -X GET "https://api.getcoherence.io/v1/automations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Query Parameters
| Parameter | Description | Example |
|---|---|---|
module | Filter by module slug | ?module=contacts |
enabled | Filter by status | ?enabled=true |
trigger_type | Filter by trigger type | ?trigger_type=record.created |
Response
{
"data": [
{
"id": "auto_abc123",
"name": "Notify on new lead",
"description": "Send Slack notification when a lead is created",
"enabled": true,
"trigger": {
"type": "record.created",
"module": "leads"
},
"conditions": [],
"actions": [
{
"type": "call_webhook",
"config": {
"url": "https://hooks.slack.com/...",
"method": "POST"
}
}
],
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"last_run_at": "2024-01-16T14:22:00Z",
"run_count": 47
}
],
"meta": {
"total": 1,
"page": 1,
"per_page": 25
}
}Get Automation
Retrieve a single automation by ID.
curl -X GET "https://api.getcoherence.io/v1/automations/auto_abc123" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json"Response
{
"data": {
"id": "auto_abc123",
"name": "Notify on new lead",
"description": "Send Slack notification when a lead is created",
"enabled": true,
"trigger": {
"type": "record.created",
"module": "leads"
},
"conditions": [
{
"field": "source",
"operator": "equals",
"value": "website"
}
],
"actions": [
{
"type": "call_webhook",
"config": {
"url": "https://hooks.slack.com/services/...",
"method": "POST",
"body": {
"text": "New lead: {{record.name}} from {{record.source}}"
}
}
}
],
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"last_run_at": "2024-01-16T14:22:00Z",
"run_count": 47
}
}Create Automation
Create a new automation.
curl -X POST "https://api.getcoherence.io/v1/automations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome email for new contacts",
"description": "Send a welcome email when a contact is added",
"trigger": {
"type": "record.created",
"module": "contacts"
},
"conditions": [
{
"field": "email",
"operator": "is_not_empty"
}
],
"actions": [
{
"type": "send_email",
"config": {
"to": "{{record.email}}",
"template": "welcome_email"
}
}
]
}'Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Name of the automation |
description | string | No | Description of what it does |
trigger | object | Yes | Trigger configuration |
conditions | array | No | Array of condition objects |
actions | array | Yes | Array of action objects |
enabled | boolean | No | Whether to enable immediately (default: false) |
Response
{
"data": {
"id": "auto_def456",
"name": "Welcome email for new contacts",
"enabled": false,
"trigger": { ... },
"conditions": [ ... ],
"actions": [ ... ],
"created_at": "2024-01-17T09:00:00Z"
}
}Update Automation
Update an existing automation.
curl -X PATCH "https://api.getcoherence.io/v1/automations/auto_abc123" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Updated automation name",
"conditions": [
{
"field": "status",
"operator": "equals",
"value": "qualified"
}
]
}'Updating an automation automatically disables it. Re-enable after testing your changes.
Delete Automation
Permanently delete an automation.
curl -X DELETE "https://api.getcoherence.io/v1/automations/auto_abc123" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"data": {
"id": "auto_abc123",
"deleted": true
}
}Enable/Disable Automation
Toggle an automation on or off.
Enable
curl -X POST "https://api.getcoherence.io/v1/automations/auto_abc123/enable" \
-H "Authorization: Bearer YOUR_API_KEY"Disable
curl -X POST "https://api.getcoherence.io/v1/automations/auto_abc123/disable" \
-H "Authorization: Bearer YOUR_API_KEY"Response
{
"data": {
"id": "auto_abc123",
"enabled": true
}
}Automation Structure
Trigger
The trigger defines what event starts the automation.
interface Trigger {
type: TriggerType;
module?: string; // Required for record triggers
field?: string; // Required for field.changed trigger
schedule?: string; // Required for schedule trigger (cron)
webhook_path?: string; // Required for webhook trigger
}Conditions
Conditions filter when the automation should run. All conditions must be true for the automation to execute.
interface Condition {
field: string;
operator: ConditionOperator;
value?: any;
}
type ConditionOperator =
| "equals"
| "not_equals"
| "contains"
| "not_contains"
| "starts_with"
| "ends_with"
| "greater_than"
| "less_than"
| "is_empty"
| "is_not_empty"
| "changed"
| "changed_to"
| "changed_from";Actions
Actions define what happens when the automation runs. Actions execute in order.
interface Action {
type: ActionType;
config: ActionConfig;
}Trigger Types
record.created
Fires when a new record is created in a module.
{
"trigger": {
"type": "record.created",
"module": "contacts"
}
}record.updated
Fires when any field on a record is updated.
{
"trigger": {
"type": "record.updated",
"module": "deals"
}
}record.deleted
Fires when a record is deleted.
{
"trigger": {
"type": "record.deleted",
"module": "tasks"
}
}field.changed
Fires when a specific field value changes.
{
"trigger": {
"type": "field.changed",
"module": "deals",
"field": "stage"
}
}Use field.changed with a changed_to condition to trigger on specific transitions, like when a deal moves to "Closed Won".
schedule
Fires on a cron schedule. Useful for daily reports, cleanup tasks, or periodic syncs.
{
"trigger": {
"type": "schedule",
"schedule": "0 9 * * 1-5"
}
}Common cron patterns:
| Pattern | Description |
|---|---|
0 9 * * * | Daily at 9 AM |
0 9 * * 1-5 | Weekdays at 9 AM |
0 0 1 * * | First of each month |
*/15 * * * * | Every 15 minutes |
webhook
Fires when an external system calls your webhook URL.
{
"trigger": {
"type": "webhook",
"webhook_path": "my-custom-webhook"
}
}The webhook URL will be:
https://api.getcoherence.io/v1/webhooks/auto_abc123/my-custom-webhook
manual
Fires when triggered via API or button click in the UI.
{
"trigger": {
"type": "manual",
"module": "contacts"
}
}Manually trigger an automation:
curl -X POST "https://api.getcoherence.io/v1/automations/auto_abc123/trigger" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"record_id": "rec_xyz789"
}'Action Types
update_record
Update fields on the triggering record or a related record.
{
"type": "update_record",
"config": {
"record": "trigger",
"updates": {
"status": "processed",
"processed_at": "{{now}}"
}
}
}Update a related record:
{
"type": "update_record",
"config": {
"record": "related",
"module": "accounts",
"record_id": "{{record.account_id}}",
"updates": {
"last_contact_date": "{{now}}"
}
}
}create_record
Create a new record in any module.
{
"type": "create_record",
"config": {
"module": "tasks",
"data": {
"name": "Follow up with {{record.name}}",
"due_date": "{{now | add_days: 3}}",
"assigned_to": "{{record.owner_id}}",
"related_contact": "{{record.id}}"
}
}
}send_email
Send an email using a template or custom content.
{
"type": "send_email",
"config": {
"to": "{{record.email}}",
"template": "welcome_email",
"data": {
"first_name": "{{record.first_name}}",
"company": "{{record.company}}"
}
}
}Or with custom content:
{
"type": "send_email",
"config": {
"to": "{{record.email}}",
"subject": "Welcome to our platform",
"body": "Hi {{record.first_name}},\n\nThank you for signing up!"
}
}send_notification
Send an in-app notification to a user.
{
"type": "send_notification",
"config": {
"user_id": "{{record.owner_id}}",
"title": "New high-value deal",
"message": "{{record.name}} - ${{record.value}}",
"link": "/deals/{{record.id}}"
}
}call_webhook
Make an HTTP request to an external URL.
{
"type": "call_webhook",
"config": {
"url": "https://hooks.slack.com/services/...",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"body": {
"text": "New deal closed: {{record.name}} for ${{record.value}}"
}
}
}delay
Pause execution for a specified duration before continuing to the next action.
{
"type": "delay",
"config": {
"duration": 300,
"unit": "seconds"
}
}| Unit | Description |
|---|---|
seconds | Delay in seconds (max 86400) |
minutes | Delay in minutes (max 1440) |
hours | Delay in hours (max 24) |
days | Delay in days (max 7) |
Delays pause the automation execution. For longer delays, consider using a scheduled automation instead.
Template Variables
Actions support template variables for dynamic content:
| Variable | Description |
|---|---|
{{record.field_name}} | Field value from triggering record |
{{record.id}} | ID of the triggering record |
{{now}} | Current timestamp |
{{user.id}} | ID of user who triggered the action |
{{user.email}} | Email of user who triggered the action |
{{previous.field_name}} | Previous value (for update triggers) |
Filters
Apply filters to transform values:
| Filter | Example | Result |
|---|---|---|
uppercase | {{record.name | uppercase}} | JOHN SMITH |
lowercase | {{record.email | lowercase}} | [email protected] |
add_days | {{now | add_days: 7}} | Date 7 days from now |
date_format | {{record.created_at | date_format: "MMM D, YYYY"}} | Jan 15, 2024 |
Execution Logs
View the execution history of an automation.
curl -X GET "https://api.getcoherence.io/v1/automations/auto_abc123/logs" \
-H "Authorization: Bearer YOUR_API_KEY"Query Parameters
| Parameter | Description | Example |
|---|---|---|
status | Filter by status | ?status=failed |
since | Logs after timestamp | ?since=2024-01-15T00:00:00Z |
limit | Number of logs (max 100) | ?limit=50 |
Response
{
"data": [
{
"id": "log_xyz789",
"automation_id": "auto_abc123",
"status": "success",
"trigger_data": {
"record_id": "rec_abc123",
"event": "record.created"
},
"actions_executed": [
{
"type": "send_email",
"status": "success",
"duration_ms": 245
},
{
"type": "update_record",
"status": "success",
"duration_ms": 32
}
],
"started_at": "2024-01-16T14:22:00Z",
"completed_at": "2024-01-16T14:22:01Z",
"duration_ms": 277
},
{
"id": "log_xyz788",
"automation_id": "auto_abc123",
"status": "failed",
"trigger_data": {
"record_id": "rec_abc122",
"event": "record.created"
},
"actions_executed": [
{
"type": "call_webhook",
"status": "failed",
"error": "Connection timeout after 30000ms"
}
],
"started_at": "2024-01-16T14:00:00Z",
"completed_at": "2024-01-16T14:00:30Z",
"duration_ms": 30000
}
],
"meta": {
"total": 47,
"page": 1,
"per_page": 25
}
}Testing Automations
Dry Run Mode
Test an automation without executing actions. This validates conditions and shows what would happen.
curl -X POST "https://api.getcoherence.io/v1/automations/auto_abc123/test" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"record_id": "rec_xyz789"
}'Response
{
"data": {
"would_execute": true,
"conditions_passed": true,
"conditions_evaluated": [
{
"field": "status",
"operator": "equals",
"value": "qualified",
"actual_value": "qualified",
"passed": true
}
],
"actions_preview": [
{
"type": "send_email",
"config": {
"to": "[email protected]",
"template": "welcome_email"
}
},
{
"type": "update_record",
"config": {
"updates": {
"status": "processed",
"processed_at": "2024-01-17T10:00:00Z"
}
}
}
]
}
}Use dry run mode to test automations with real records before enabling them in production.
Error Handling
Automatic Retries
Failed actions are automatically retried with exponential backoff:
- 1st retry: 1 minute
- 2nd retry: 5 minutes
- 3rd retry: 30 minutes
After 3 failed attempts, the automation is marked as failed for that execution.
Error Notifications
Configure error notifications in automation settings:
{
"error_handling": {
"notify_on_failure": true,
"notify_email": "[email protected]",
"disable_after_failures": 5
}
}Common Errors
| Error Code | Description | Solution |
|---|---|---|
condition_evaluation_failed | Could not evaluate a condition | Check field names and operators |
action_timeout | Action took too long | Increase timeout or simplify action |
webhook_connection_failed | Could not reach webhook URL | Verify URL is accessible |
email_delivery_failed | Email could not be sent | Check email address validity |
record_not_found | Referenced record does not exist | Verify record IDs in conditions |
permission_denied | Automation lacks required permissions | Check automation user permissions |
Circuit Breaker
If an automation fails repeatedly, it will be automatically disabled:
{
"error": {
"code": "automation_disabled",
"message": "Automation disabled after 5 consecutive failures",
"last_error": "webhook_connection_failed"
}
}Re-enable after fixing the issue:
curl -X POST "https://api.getcoherence.io/v1/automations/auto_abc123/enable" \
-H "Authorization: Bearer YOUR_API_KEY"Examples
Notify Sales Team on High-Value Deal
{
"name": "High-value deal notification",
"trigger": {
"type": "record.created",
"module": "deals"
},
"conditions": [
{
"field": "value",
"operator": "greater_than",
"value": 50000
}
],
"actions": [
{
"type": "send_notification",
"config": {
"user_id": "{{record.owner_id}}",
"title": "High-value deal created",
"message": "{{record.name}} - ${{record.value}}"
}
},
{
"type": "call_webhook",
"config": {
"url": "https://hooks.slack.com/services/...",
"method": "POST",
"body": {
"text": ":moneybag: New high-value deal: {{record.name}} (${{record.value}})"
}
}
}
]
}Create Follow-Up Task on Stage Change
{
"name": "Create follow-up on stage change",
"trigger": {
"type": "field.changed",
"module": "deals",
"field": "stage"
},
"conditions": [
{
"field": "stage",
"operator": "changed_to",
"value": "proposal"
}
],
"actions": [
{
"type": "create_record",
"config": {
"module": "tasks",
"data": {
"name": "Send proposal to {{record.name}}",
"due_date": "{{now | add_days: 2}}",
"assigned_to": "{{record.owner_id}}",
"priority": "high"
}
}
}
]
}Daily Summary Email
{
"name": "Daily deals summary",
"trigger": {
"type": "schedule",
"schedule": "0 9 * * 1-5"
},
"actions": [
{
"type": "call_webhook",
"config": {
"url": "https://your-app.com/api/generate-summary",
"method": "POST"
}
}
]
}Next: Learn about Webhooks to integrate external systems.