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:

  1. Trigger - What starts the automation (e.g., a record is created)
  2. Conditions - Optional rules that determine if the automation should run
  3. Actions - What happens when the automation executes

Endpoints

MethodEndpointDescription
GET/automationsList all automations
GET/automations/:idGet a single automation
POST/automationsCreate an automation
PATCH/automations/:idUpdate an automation
DELETE/automations/:idDelete an automation
POST/automations/:id/enableEnable an automation
POST/automations/:id/disableDisable an automation
GET/automations/:id/logsGet execution logs
POST/automations/:id/testTest 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

ParameterDescriptionExample
moduleFilter by module slug?module=contacts
enabledFilter by status?enabled=true
trigger_typeFilter 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

FieldTypeRequiredDescription
namestringYesName of the automation
descriptionstringNoDescription of what it does
triggerobjectYesTrigger configuration
conditionsarrayNoArray of condition objects
actionsarrayYesArray of action objects
enabledbooleanNoWhether 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:

PatternDescription
0 9 * * *Daily at 9 AM
0 9 * * 1-5Weekdays 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"
  }
}
UnitDescription
secondsDelay in seconds (max 86400)
minutesDelay in minutes (max 1440)
hoursDelay in hours (max 24)
daysDelay 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:

VariableDescription
{{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:

FilterExampleResult
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

ParameterDescriptionExample
statusFilter by status?status=failed
sinceLogs after timestamp?since=2024-01-15T00:00:00Z
limitNumber 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 CodeDescriptionSolution
condition_evaluation_failedCould not evaluate a conditionCheck field names and operators
action_timeoutAction took too longIncrease timeout or simplify action
webhook_connection_failedCould not reach webhook URLVerify URL is accessible
email_delivery_failedEmail could not be sentCheck email address validity
record_not_foundReferenced record does not existVerify record IDs in conditions
permission_deniedAutomation lacks required permissionsCheck 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.