Skip to content

Webhooks and automation

To put it plainly: FlowDesk does not send a webhook or callback to your system on request lifecycle events (status changed, assigned, completed and so on). This is not a limitation added late to the plan; it is a design decision of the current version. It appears explicitly in the integration surface’s official out-of-scope list: “webhooks/callbacks (not available in this version, outcomes are learned by polling)”. Nothing in the code contradicts it either: under v1/integration/* and v1/external/* there is no component that makes an outbound request or calls a URL of yours.

You may notice an endpoint named v1/integration/inbound-email/webhook: despite the name, that is not a webhook going to your system; it is an inbound endpoint through which your mail provider (Mailgun, for example) delivers e-mail to FlowDesk, and it is of no use to you (see Installation → E-mail settings). There is no counterpart you can listen to for request lifecycle events.

What this means: you learn outcomes by polling, not by push. The rest of this page explains how to do that reliably.

The tools you have are described in detail on Creating requests; here is the summary from an “attaching to events” point of view:

  • For the current state of a single request: GET /v1/integration/tickets/{id} or .../by-tracking-key/{trackingKey}. The single-request response is invalidated on every write, so these two endpoints always give the current result, never a delayed one.
  • Efficient polling with ETag: the single-request response carries an ETag; send the value from your previous query as If-None-Match and you get a bodiless 304 when the request has not changed, so you do not have to carry the whole body over and over just to find out whether something changed.
  • For scanning several requests: GET /v1/integration/tickets?statusIds=..., but that response is only time-cached (45 seconds by default) and is not invalidated on write; use it for bulk scanning, not for the moment-to-moment state of one request.

A practical pattern: keep a polling timer per trackingKey on your side (frequent right after opening the request, thinning out over time: 1s, 2s, 4s, then minutes), and stop when the request’s isCompleted/ticketStatusId reaches the state you expect, or when it hits an upper bound set by your own business rules. On a 429, wait for the Retry-After period and continue; see Creating requests → Error contract.

Why your request can change without any action from you

Section titled “Why your request can change without any action from you”

After you open a request with v1/integration/tickets, its state can change for reasons outside your API call: an agent replies from the dashboard, an SLA escalation chain hands the request up a level, or an automation rule defined in the dashboard (the workflow engine) fires. The practical consequence for a polling integration: your request’s state can change even when you do nothing, which is why you need regular polling rather than a single “read it once and done”.

That automation engine is configured in the dashboard by an administrator, is not part of the integration API, and can neither be created nor queried with your token. Knowing what it does only helps you understand why your request changed on its own:

  • Triggers: request created, status changed, assigned, customer replied, or a scheduled scan (once a minute).
  • Conditions: a condition tree built with AND/OR over the request’s fields (status, priority, pool, time since the last customer reply, and so on).
  • Actions: changing status, escalation (handing over pool/user plus raising priority), reassignment, sending e-mail, in-dashboard notification, writing to the log.

The same rule does not fire repeatedly on the same request: there is a suppression window of 1440 minutes (one day) by default, and within that window the same rule is skipped silently. Knowing this lets you answer “why did my rule not run again” on your own; if you want to change the setting, your contact is your own organisation’s FlowDesk administrator, not this API.

Because there is no push-based webhook, the classic “retry the webhook X times” concept does not exist. Three things matter for a durable integration on your side:

  1. Idempotency-Key, so you can safely repeat your request-creation calls; see Creating requests → Safe retries.
  2. Respecting Retry-After on a 429: successful responses carry no rate-limit header, so you cannot see your remaining quota in advance; base your backoff decision only on the Retry-After value in the 429 response.
  3. Backing off and retrying on 503 / FD:0011: if the deployment’s licence state is temporarily refusing operations, that has nothing to do with your request; get in touch with your organisation’s FlowDesk administrator.