Webhooks

Webhooks are requests sent by Planado to your server when a change in Planado occurs.

Webhooks can be configured for jobs, clients, and sites.

Technically, a webhook is an HTTP-request made by the Planado server to the URL of your choice. This request has a JSON-encoded body containing information about the change.

Reliable delivery

Webhook is successfully delivered if it received a 2xx code in response.

Failed deliveries retried up to 17 times with increasing interval.

Every request has the X-Planado-Delivery-Attempt header which holds the attempt number starting with 1.

Webhook processing time is limited to 10 seconds. If your server doesn’t respond in time, the request is considered failed.
We count on requests to be processed on the first attempt on average. If we detect that a lot of the attempts fail, we may suspend webhook delivery to your server until the issue is resolved.

Versions and out-of-order delivery

Changes in resources are delivered as they happen. This, however, may lead to out-of-order delivery. Consider the following situation:

  • Change A to job #42 happens. API sends a webhook with the change, but the delivery fails due to an intermittent network error.

  • Change B to job #42 happens. Webhook was successfully delivered.

  • Delivery for change A is successfully retried.

This means that for your server change B happened before change A. Depending on the use case you may want to guarantee the order. For this, webhook body contains the version field, a positive integer incremented on every update of a resource. Each resource gets version equal 1 on creation.

You can save the version value in your system. After that, you have two possible strategies for keeping the order.

Last write wins

Requirements: only the final state matters; all out-of-order deliveries can be safely ignored.

  • When a request arrives, compare the saved value x with one from the request y.

  • If y > x it’s a new update, process it and replace x with y.

  • If y < x it’s a missed update, ignore the request, respond with HTTP 200 OK so that Planado won’t make further retries.

Full replication

Requirements: a fully replicated state.

  • When a request arrives, compare the saved value x with one from the request y.

  • If y == x + 1 it’s a sequential update, process it and replace x with y.

  • If y != x + 1 it’s an out-of-order delivery, respond with HTTP 422 and wait for the missing update to arrive.

In the case of full replication, a single missed update can lead to a sequence of retried deliveries. It may take some time for both systems to catch up.

Sender authentication

To verify that requests are sent by the Planado server, not by some other host, you can configure the "Secret" value in settings. This value is sent in the X-Planado-Secret header. Check this header to verify that the request is authentic.

Structure of webhook body

Webhook body is JSON-encoded object with three keys:

  • event_uuid is a unique identifier of the event.

  • event_type is the type of the change. Examples are "job_created", "client_updated", "site_removed".

  • context contains timestamps and information about the author of the change.

  • job, client or site with a snapshot of the resource.

Context format

Field Type JSON Type Can be null Description

source

UUID

String

No

Unique identifier

happened_at

Datetime

String

No

Time when the event happened

created_at

Datetime

String

No

Time when the event reached the server.
For events happen on a mobile device there may be a significant delay between created_at and happened_at

user_uuid

UUID

String

Yes

Identifier of the event author

user_email

String

String

Yes

Email of the event author

device_uuid

UUID

String

Yes

Device identifier

Temporary API tokens

Webhook requests contain a header (X-Planado-Api-Token) with a temporary API token. These tokens can be used instead of API keys to make an immediate request back to Planado. Tokens are valid for 1 minute after starting a webhook request. Authentication rules are identical to permanent API keys.