Set SLAs and automate actions
The time targets a ticket has to meet, and the automations that run unattended.
POST /slas stores a time target; POST /triggers stores an automation. The two usually get configured together, because the commonest trigger is the one that warns an SLA is about to breach.
SLAs
An SLA policy carries a name and two optional targets in minutes: first response and resolution. The applies_to filter says which threads it covers, by channel, brand or priority, using whatever the workspace's routing already uses to tell them apart. business_hours_only pauses the clock outside the team's coverage hours instead of counting wall-clock time.
Reading needs slas:read; writing, slas:write.
curl -X POST https://api.vitrinadev.com/api/v1/slas \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Soporte estándar",
"target_first_response_minutes": 30,
"target_resolution_minutes": 1440,
"business_hours_only": true,
"applies_to": { "channel": "whatsapp" }
}'{
"data": {
"id": "d7d7d7d7-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"name": "Soporte estándar",
"target_first_response_minutes": 30,
"target_resolution_minutes": 1440,
"business_hours_only": true,
"applies_to": { "channel": "whatsapp" },
"active": true,
"created_at": "2026-01-10T13:00:00.000Z",
"updated_at": "2026-09-10T13:00:00.000Z"
}
}name is unique per workspace, and repeating it returns a 409. The two targets are independent: a policy can set a first-response target, a resolution target, or both.
No policy applies itself yet
Nothing automatically works out which policy covers a given conversation or
ticket from applies_to. That matching is done by the surfaces that already
know the SLA, such as the ticket board and the coverage clock. Deleting a
policy with DELETE /slas/{id} recomputes nothing backwards either: tickets
that already carried it keep whatever coverage state they had reached.
Triggers
A trigger fires when its event happens. Events include a conversation going idle, a message arriving, and a ticket being created, resolved or assigned. Before it runs, the trigger checks its conditions, a { logic: 'all' | 'any', items: [{ field, op, value }] } tree. If those match, it runs its actions in order.
An action can send a message, add a private note or call a webhook. It can also assign a person or a team, move a lead to a stage, add a tag, change status or snooze.
Reading needs triggers:read; writing, triggers:write.
curl -X POST https://api.vitrinadev.com/api/v1/triggers \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Avisar si nadie responde en 2 horas",
"event": "conversation_idle",
"duration_hours": 2,
"conditions": { "logic": "all", "items": [{ "field": "channel", "op": "eq", "value": "whatsapp" }] },
"actions": [{ "type": "assign_team", "value": "cccccccc-0000-4000-8000-000000000001" }]
}'{
"data": {
"id": "d8d8d8d8-0000-4000-8000-000000000001",
"name": "Avisar si nadie responde en 2 horas",
"event": "conversation_idle",
"duration_hours": 2,
"conditions": { "logic": "all", "items": [{ "id": "c1", "field": "channel", "op": "eq", "value": "whatsapp" }] },
"actions": [{ "id": "a1", "type": "assign_team", "value": "cccccccc-0000-4000-8000-000000000001" }],
"enabled": true,
"fire_once_per_conversation": true,
"stop_after_run": false,
"run_count": 0,
"last_run_at": null
}
}event: "conversation_idle" requires duration_hours, between 1 and 720; every other event ignores it. Each condition's and each action's id is a local key inside that trigger. It's there so a future edit can say which one to replace, and it points at no other resource. Omit it and the API assigns one.
Trap
Editing a trigger lends no sending authority
Creating or editing a trigger with a send_message or add_private_note
action needs no messages:send scope. The message goes out when the trigger
fires, not in the request that creates it, and that request gives your
credential no permission to send.
The full contracts live in the SLAs and Triggers reference. To receive sla.breached and the events a trigger fires, see Webhooks.