Webhooks
Trigger AppPilot flows from your integration by event name, instead of polling.
How it works
The public External API exposes POST /v1/webhooks/trigger (scope webhooks.write). You send an event name; Appficient matches AppPilot triggers (or custom keys) and starts runs.
See also the Webhooks API reference.
curl -sS -X POST https://api.appficient.nl/v1/webhooks/trigger \
-H "Authorization: Bearer apf_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"event": "invoice.paid",
"entity_type": "invoice",
"entity_id": 522,
"data": { "guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890" }
}'Request and response
Request body (required: event; optional: data, entity_type, entity_id):
{
"event": "invoice.paid",
"entity_type": "invoice",
"entity_id": 522,
"data": {
"guid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}Response:
{
"data": {
"event": "invoice.paid",
"matched": 1,
"runs": [
{
"flow_guid": "c9d0e1f2-a3b4-5678-9012-789012345678",
"run_guid": "d0e1f2a3-b4c5-6789-0123-890123456789",
"status": "queued"
}
]
},
"meta": {}
}Events
Built-in event names. Custom keys are also accepted.
| Event | When |
|---|---|
ticket.inbound_message | Inbound ticket message received |
ticket.created | Ticket created |
ticket.status_changed | Ticket status changed |
ticket.closed | Ticket closed |
ticket.message | Ticket message posted |
ticket.stale | Ticket idle too long |
quote.fase_changed | Quote phase changed |
quote.viewed | Quote viewed |
quote.accepted | Quote accepted |
quote.created | Quote created |
quote.converted_to_project | Quote converted to project |
quote.silent | Quote without response |
deal.won | Deal won |
deal.lost | Deal lost |
deal.phase_changed | Deal phase changed |
deal.quote_accepted | Deal quote accepted |
deal.created | Deal created |
deal.stalled | Deal stalled |
deal.phase_idle | Deal idle in the same phase |
deal.close_due | Deal close date approaching |
deal.no_followup | Deal without follow-up |
sales.document_sent | Sales document sent |
invoice.created | Invoice created |
invoice.credited | Invoice credited |
invoice.paid | Invoice paid |
invoice.late | Invoice overdue |
project.created | Project created |
project.completed | Project completed |
project.status_changed | Project status changed |
project.phase_completed | Project phase completed |
workorder.completed | Work order completed |
customer.created | Customer created |
customer.updated | Customer updated |
customer.first_invoice_paid | First invoice of a customer paid |
customer.inactive | Customer inactive |
customer.no_followup | Customer without follow-up |
customer.payment_overdue | Customer payment overdue |
subscription.expiring | Subscription expiring |
mail.unanswered | Mail unanswered |
document.draft | Document in draft |
work.recurring | Recurring work |
planning.scheduled | Planning scheduled |
planning.rescheduled | Planning rescheduled |
planning.updated | Planning updated |
planning.unscheduled | Planning unscheduled |
planning.deleted | Planning deleted |
Reliability
- Rate limit on this route: 30/minute.
- Handle runs idempotently on your side if you resend the same trigger.