Webhooks

A webhook tells your system at once when something changes in an organization's data in myWebLog: a booking, a flight or a remark. Instead of asking the API every few minutes whether anything is new, your server gets a short message when something has actually changed, and fetches the details then.

How it works

  1. Something changes in the organization's data: a member books an aircraft, a flight is logged, a remark is written.
  2. Within about a minute myWebLog sends a POST to the address you have given: what happened, and the id.
  3. Your server checks that the message comes from myWebLog and answers 2xx at once.
  4. Your server fetches the details through the Main API v5 with the organization's API key, for example GET /bookings/123.

The message only says what happened and to which id, so no personal data is sent to your address. An organization also gets events for aircraft that other organizations share with it.

Events

A webhook can get events for bookings, the flight log and remarks, in any combination.

EventSent whendataDetails through
booking.createA booking is made.idGET /bookings/{id}
booking.updateA booking is changed: its time, aircraft, who it is for, its place in a queue.idGET /bookings/{id}
booking.deleteA booking is deleted, also when its aircraft is deleted (bookings that have not ended). A booking that is moved into a queue is deleted and made again with a new id: you get booking.delete for the old id and booking.create for the new one.idCan no longer be fetched
flightlog.createA flight is logged: on the website, in an app or through an integration.idGET /flightlogs/{id}
flightlog.updateA logged flight is corrected, or endorsed (signed) in the aircraft's logbook. An endorsed flight is locked: it can no longer be changed.id; when endorsed also change: endorsedGET /flightlogs/{id}
flightlog.deleteA logged flight is deleted.idCan no longer be fetched
remark.createA remark is written on an aircraft.idGET /remarks/{id}
remark.updateA remark is acknowledged, commented or closed.id, change: acknowledged, commented or closedGET /remarks/{id}
webhook.pingA test: when the webhook is set up, when support tests it, and once a day while it is paused.empty–

The calls are in the Main API v5. GET /remarks/{id} needs read access to the module Objects; it gives the remark with everything that has happened to it.

The request

Every event is a POST with a JSON body to your https address.

HeaderValue
AuthorizationBearer and the webhook's token.
Content-Typeapplication/json
X-Mwl-Event-IdThe event's id: 32 hexadecimal characters, the same on every try. Use it to drop an event you have already received.
X-Mwl-TimestampWhen this try was sent, in Unix time (seconds).
X-Mwl-AttemptWhich try this is, 1 to 8.
X-Mwl-SignatureThe signature: HMAC-SHA256 of the timestamp, a dot and the body, with the webhook's signing key, as 64 hexadecimal characters.
Request-IdThe id of this try. Give it to support when you ask about a delivery.
User-Agentmwl-webhooks/1.0

The body

{
  "organization": { "id": 44 },
  "event_type": "remark.update",
  "data": { "id": 29153, "change": "closed", "object_id": 278 },
  "id": "175b6d93169167ed551b8c593593a227",
  "occurred_at": "2026-10-11T19:31:01Z",
  "schema_version": 1
}
FieldValue
organization.idThe organization whose webhook it is. For an aircraft that is shared with that organization, it is that organization, not the owner of the aircraft.
event_typeWhat happened, see Events.
data.idThe id of the booking, flight or remark.
data.changeOnly on remark.update and on an endorsed flightlog.update, see Events.
data.object_idThe aircraft (object) of the booking, flight or remark, also when it has been deleted and can no longer be fetched. Not on webhook.ping.
idThe event's id, the same as X-Mwl-Event-Id and the same on every try.
occurred_atWhen the change happened, in UTC. X-Mwl-Timestamp is when this try was sent, which can be up to 22 hours later.
schema_versionThe form of the message, now 1. Fields may be added without a new version; a change to an existing field gets a new version.

Read the fields by name and ignore fields you do not know: new fields can be added.

Checking the request

Answer only a request that comes from myWebLog:

  1. The Authorization header is Bearer and your token.
  2. The signature matches: compute HMAC-SHA256 of X-Mwl-Timestamp, a dot (.) and the body exactly as received, with your signing key, and compare it with X-Mwl-Signature in constant time.
  3. The timestamp is recent, for example within 5 minutes, so an old request can not be sent again.

Example in PHP

<?php
$token      = "...";   // from myWebLog support
$signingKey = "...";   // from myWebLog support

$body      = file_get_contents("php://input");
$timestamp = $_SERVER["HTTP_X_MWL_TIMESTAMP"] ?? "";
$signature = $_SERVER["HTTP_X_MWL_SIGNATURE"] ?? "";
$auth      = $_SERVER["HTTP_AUTHORIZATION"] ?? "";

$expected = hash_hmac("sha256", $timestamp . "." . $body, $signingKey);

if (!hash_equals("Bearer " . $token, $auth)
    || !hash_equals($expected, $signature)
    || abs(time() - (int)$timestamp) > 300) {
    http_response_code(401);
    exit;
}

$event = json_decode($body, true);
// Store the event and answer at once; do the work (such as fetching the details) afterwards
http_response_code(202);

On some Apache servers the Authorization header is not passed on to PHP; then the server must be set to pass it on.

Answering, and when it fails

Getting a webhook

Webhooks are set up by myWebLog support. The events are about the organization's data, so the request must come from the organization's administrator, or be approved by them. Email support@myweblog.se with:

You get the token and the signing key, and support sends a webhook.ping to check the address. To fetch the details you also need a key for the Main API: the organization's administrator makes it in myWebLog under ADMIN > System settings > Authorization > API access.

To change the address or the events, to get a new token or signing key, or to stop a webhook, email support.