{"_id":"59fcc7ff067f8d00286142b7","project":"54c0e51215af820d001a38a6","version":{"_id":"54f8de4e4339bb1900c8bffb","project":"54c0e51215af820d001a38a6","forked_from":"54f8de14c6cabe23005c02a2","__v":32,"createdAt":"2015-03-05T22:53:02.044Z","releaseDate":"2015-03-05T22:53:02.044Z","categories":["54f8de4e4339bb1900c8bffc","54f8de4e4339bb1900c8bffd","54f8de4e4339bb1900c8bffe","54f8de4e4339bb1900c8bfff","54f8de4e4339bb1900c8c000","54ff6057563d7419002d666e","55007b6ecfeeea17004717dc","5501d779f2ef1e0d003116eb","55116ef89f7c7619005f853b","554bb366f245703100ddd39f","554d226b374fec0d007e64db","555e09f18ab3180d001ac605","555e0b2b4f5e5a0d00836d77","561d1f8b92a0cc350018b24f","562a956c96b5f40d0026eb60","5654c3378a26202b00c17cb8","5697a94b0b09a41900b24546","5739d89e37b52e3200a3a3cc","57ac94252c0b220e00a94570","57ac97a1ad44fc0e003be066","57ac9a3a8f312d0e00e96c75","57ac9c187ae5c60e004ba3a3","58178bee62e4500f009404f6","581a39711a63870f008b621d","581a3b4f0c65b20f00247fcb","5926e0606c729e0f00595f95","5954033ea5bbca002d27ae91","596ce53e0aeafe00157eb1ba","596ce87a8b79f4001a8f6139","598cad2e96193400190d879a","598cbcd3dc20c6000fdfb9c3","598cbd8496193400190d8955","59fcc7c9591add0026c91457","5a020b7856ea82001c8c9342","5a09bc64a91882001c56c2ed","5a71fa2de9aa84007a8bccdb"],"is_deprecated":false,"is_hidden":false,"is_beta":true,"is_stable":true,"codename":"","version_clean":"1.0.0","version":"1"},"category":{"_id":"59fcc7c9591add0026c91457","project":"54c0e51215af820d001a38a6","version":"54f8de4e4339bb1900c8bffb","__v":0,"sync":{"url":"","isSync":false},"reference":false,"createdAt":"2017-11-03T19:47:21.098Z","from_sync":false,"order":1,"slug":"webhooks","title":"Webhooks"},"user":"560000e90c703d1900952ff2","__v":0,"parentDoc":null,"updates":[],"next":{"pages":[],"description":""},"createdAt":"2017-11-03T19:48:15.258Z","link_external":false,"link_url":"","githubsync":"","sync_unique":"","hidden":false,"api":{"results":{"codes":[]},"settings":"","auth":"required","params":[],"url":""},"isReference":false,"order":0,"body":"Webhooks allow you to quickly find out if something happened in Fleetio. You can subscribe to certain events and whenever that event happens, Fleetio will make a HTTP POST to your endpoint containing the relevant data (serialized as JSON).\n[block:callout]\n{\n  \"type\": \"info\",\n  \"body\": \"Webhooks are only available on our Advanced plans\"\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Timing & Delivery\"\n}\n[/block]\nWhenever an update event occurs in Fleetio, Fleetio will wait a little for any other identical events before firing off a message to your webhook. So if 5 people edited the same vehicle within a minute, you will only get one message. This is done to prevent your endpoint from being overloaded. Events based on creation or deletion are fired off as soon as possible.\n\nWebhook events are asynchronous. We will do our best to deliver them as soon as possible to your endpoint, so you should not rely on them for anything time sensitive. Your application should be prepared for delays in receiving messages, or even out of order messages if there are interruptions or delays in the network.\n[block:api-header]\n{\n  \"title\": \"Message Format\"\n}\n[/block]\nFleetio will make a HTTP POST to your endpoint with a content type of `application/json`.\nThe body of the POST will contain a JSON message that looks like the following:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"{\\n  id: 1,\\n  event: \\\"vehicle_updated\\\",\\n  timestamp: \\\"2017-11-03T10:15:38.741-05:00\\\",\\n  payload: {\\n    \\\"id\\\": 123,\\n    \\\"current_meter_value\\\": 110111.0,\\n    additional vehicle fields.....\\n  }\\n}\",\n      \"language\": \"json\"\n    }\n  ]\n}\n[/block]\nAs you can see from the sample message, the payload will always contain the object that caused the webhook to fire. So if the event is `vehicle_updated`, the payload will contain a vehicle object. Similarly, if the webhook event is `contact_created`, the payload will contain a contact object.\n\nEach message is timestamped by the `timestamp` attribute indicating when the event happened. This is a ISO8601 string, that is either the account's time zone or Central Time, if there is none set.\n[block:api-header]\n{\n  \"title\": \"Verifying Messages\"\n}\n[/block]\nIn order to protect your endpoint from malicious hackers, Fleetio signs each message \nwith a shared key that you can find by selecting the \"View Secret Key\" action in the dropdown menu of your webhook. Using this key, Fleetio computes the HMAC SHA-256 digest with the message body and sends it in the **X-Fleetio-Webhook-Signature** HTTP header. \n\nIn order to verify that the message came from Fleetio, all you have to do is compute the HMAC SHA-256 digest of the raw HTTP body using the webhook secret as the key, and compare it with the **X-Fleetio-Webhook-Signature** HTTP header.\n\nIn Ruby, it would look like this:\n[block:code]\n{\n  \"codes\": [\n    {\n      \"code\": \"OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), webhook.shared_key, message.body)\",\n      \"language\": \"ruby\"\n    }\n  ]\n}\n[/block]\n\n[block:api-header]\n{\n  \"title\": \"Response\"\n}\n[/block]\nYour endpoint **MUST** respond with a HTTP 200 code within **30 seconds**. Any other code will make Fleetio think your endpoint failed to handle the message.\n[block:api-header]\n{\n  \"title\": \"Failures and Retries\"\n}\n[/block]\nIf you fail to handle the message, Fleetio will try 4 more times (for a total of 5 attempts) to deliver the message to your endpoint. The timing of each attempt is described in the table below:\n[block:parameters]\n{\n  \"data\": {\n    \"h-0\": \"Attempt\",\n    \"h-1\": \"Timing\",\n    \"0-0\": \"1\",\n    \"1-0\": \"2\",\n    \"2-0\": \"3\",\n    \"3-0\": \"4\",\n    \"4-0\": \"5\",\n    \"0-1\": \"1 minute after the original event\",\n    \"1-1\": \"1 minute after last failure\",\n    \"2-1\": \"5 minutes after last failure\",\n    \"3-1\": \"15 minutes after last failure\",\n    \"4-1\": \"30 minutes after last failure\"\n  },\n  \"cols\": 2,\n  \"rows\": 5\n}\n[/block]\nIf your endpoint fails to successfully handle the message after 5 attempts, we will mark the message as failed and undeliverable. The account owner and the creator of the webhook will also receive an email notification.\n\nAfter **3 consecutive** failed messages, **we will disable your webhook**, and send an email notification to the account owner and the webhook creator. It is up to you to fix your endpoint and then manually reenable the webhook under your Fleetio account settings.\n[block:api-header]\n{\n  \"title\": \"Events\"\n}\n[/block]\nFleetio will save all webhook events for 30 days. **After 30 days of an event occurring, that event will be automatically removed**. You can view all events that have been fired for your webhooks on the Webhook Events index page.\n\nFor a reference to all events Fleetio publishes, please go [here](https://developer.fleetio.com/v1/docs/events-reference).\n[block:api-header]\n{\n  \"title\": \"Webhook Event Statuses\"\n}\n[/block]\n\n[block:parameters]\n{\n  \"data\": {\n    \"0-0\": \"Success\",\n    \"h-0\": \"Status\",\n    \"h-1\": \"Description\",\n    \"0-1\": \"Successfully POSTed to webhook endpoint\",\n    \"1-0\": \"Failed\",\n    \"1-1\": \"Failed to POST to endpoint. This could either be due to your endpoint not returning a HTTP 200, or your endpoint taking more than 30 seconds to respond, or something else.\",\n    \"2-0\": \"Sending\",\n    \"2-1\": \"Fleetio is currently POSTing a message to the webhook endpoint.\",\n    \"3-0\": \"Will Not Send\",\n    \"3-1\": \"The webhook endpoint was disabled (either by Fleetio or by a user) before it was able to POST.\"\n  },\n  \"cols\": 2,\n  \"rows\": 4\n}\n[/block]","excerpt":"","slug":"webhooks-overview","type":"basic","title":"Overview"}
Webhooks allow you to quickly find out if something happened in Fleetio. You can subscribe to certain events and whenever that event happens, Fleetio will make a HTTP POST to your endpoint containing the relevant data (serialized as JSON). [block:callout] { "type": "info", "body": "Webhooks are only available on our Advanced plans" } [/block] [block:api-header] { "title": "Timing & Delivery" } [/block] Whenever an update event occurs in Fleetio, Fleetio will wait a little for any other identical events before firing off a message to your webhook. So if 5 people edited the same vehicle within a minute, you will only get one message. This is done to prevent your endpoint from being overloaded. Events based on creation or deletion are fired off as soon as possible. Webhook events are asynchronous. We will do our best to deliver them as soon as possible to your endpoint, so you should not rely on them for anything time sensitive. Your application should be prepared for delays in receiving messages, or even out of order messages if there are interruptions or delays in the network. [block:api-header] { "title": "Message Format" } [/block] Fleetio will make a HTTP POST to your endpoint with a content type of `application/json`. The body of the POST will contain a JSON message that looks like the following: [block:code] { "codes": [ { "code": "{\n id: 1,\n event: \"vehicle_updated\",\n timestamp: \"2017-11-03T10:15:38.741-05:00\",\n payload: {\n \"id\": 123,\n \"current_meter_value\": 110111.0,\n additional vehicle fields.....\n }\n}", "language": "json" } ] } [/block] As you can see from the sample message, the payload will always contain the object that caused the webhook to fire. So if the event is `vehicle_updated`, the payload will contain a vehicle object. Similarly, if the webhook event is `contact_created`, the payload will contain a contact object. Each message is timestamped by the `timestamp` attribute indicating when the event happened. This is a ISO8601 string, that is either the account's time zone or Central Time, if there is none set. [block:api-header] { "title": "Verifying Messages" } [/block] In order to protect your endpoint from malicious hackers, Fleetio signs each message with a shared key that you can find by selecting the "View Secret Key" action in the dropdown menu of your webhook. Using this key, Fleetio computes the HMAC SHA-256 digest with the message body and sends it in the **X-Fleetio-Webhook-Signature** HTTP header. In order to verify that the message came from Fleetio, all you have to do is compute the HMAC SHA-256 digest of the raw HTTP body using the webhook secret as the key, and compare it with the **X-Fleetio-Webhook-Signature** HTTP header. In Ruby, it would look like this: [block:code] { "codes": [ { "code": "OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), webhook.shared_key, message.body)", "language": "ruby" } ] } [/block] [block:api-header] { "title": "Response" } [/block] Your endpoint **MUST** respond with a HTTP 200 code within **30 seconds**. Any other code will make Fleetio think your endpoint failed to handle the message. [block:api-header] { "title": "Failures and Retries" } [/block] If you fail to handle the message, Fleetio will try 4 more times (for a total of 5 attempts) to deliver the message to your endpoint. The timing of each attempt is described in the table below: [block:parameters] { "data": { "h-0": "Attempt", "h-1": "Timing", "0-0": "1", "1-0": "2", "2-0": "3", "3-0": "4", "4-0": "5", "0-1": "1 minute after the original event", "1-1": "1 minute after last failure", "2-1": "5 minutes after last failure", "3-1": "15 minutes after last failure", "4-1": "30 minutes after last failure" }, "cols": 2, "rows": 5 } [/block] If your endpoint fails to successfully handle the message after 5 attempts, we will mark the message as failed and undeliverable. The account owner and the creator of the webhook will also receive an email notification. After **3 consecutive** failed messages, **we will disable your webhook**, and send an email notification to the account owner and the webhook creator. It is up to you to fix your endpoint and then manually reenable the webhook under your Fleetio account settings. [block:api-header] { "title": "Events" } [/block] Fleetio will save all webhook events for 30 days. **After 30 days of an event occurring, that event will be automatically removed**. You can view all events that have been fired for your webhooks on the Webhook Events index page. For a reference to all events Fleetio publishes, please go [here](https://developer.fleetio.com/v1/docs/events-reference). [block:api-header] { "title": "Webhook Event Statuses" } [/block] [block:parameters] { "data": { "0-0": "Success", "h-0": "Status", "h-1": "Description", "0-1": "Successfully POSTed to webhook endpoint", "1-0": "Failed", "1-1": "Failed to POST to endpoint. This could either be due to your endpoint not returning a HTTP 200, or your endpoint taking more than 30 seconds to respond, or something else.", "2-0": "Sending", "2-1": "Fleetio is currently POSTing a message to the webhook endpoint.", "3-0": "Will Not Send", "3-1": "The webhook endpoint was disabled (either by Fleetio or by a user) before it was able to POST." }, "cols": 2, "rows": 4 } [/block]