{"info":{"_postman_id":"d195addc-4308-4ed3-a71f-c1ac0871d68e","name":"Dispatch Connect: Playbook","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"description":"<html><head></head><body></body></html>","owner":"42145","collectionId":"d195addc-4308-4ed3-a71f-c1ac0871d68e","publishedId":"RW1gFcwk","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"EF5B25"},"publishDate":"2018-05-31T11:45:16.000Z"},"item":[{"name":"Overview","item":[{"name":"Why \"playbook\"?","item":[],"id":"e571f45f-9123-4192-ab13-30897a81b0b8","description":"<p>Generally speaking API docs are a laundry listing of APIs. And while those APIs are described, the consumer of those APIs generally needs to figure out how to go about stringing together the various APIs in order to accomplish the desired result. Our objective is not only to list the available Dispatch APIs that you have at your disposal, but also to provide you with step by step guidance for the common use cases that we generally encounter. And for that reason we refer to this document as our API \"playbook\" rather than API \"docs\".</p>\n","_postman_id":"e571f45f-9123-4192-ab13-30897a81b0b8"},{"name":"How this document is organized","item":[],"id":"89b5e058-bddc-45b9-a7f9-24768630b499","description":"<p><strong>Quick Starts</strong></p>\n<p>The <a href=\"#1bb09714-ff37-4ae4-961d-1c0000ea1ef3\">Quick Starts</a> cover the most common use cases that are typically required in building an integration with the Dispatch Platform. The recommendation is to follow the Quick Start section that is relevant to your use case which should allow you to quickly stand up a bi-directional integration with Dispatch. Our experience is that the Quick Starts are usually all that is necessary to build a comprehensive, production-ready integration with the Dispatch Platform. You should pick the Quick Start that is relevant to your use case:</p>\n<ul>\n<li><a href=\"#6ed5e5a3-ca51-4b06-ab97-7ff0a4f5c010\">DNM</a> - Relevant if you're an enterprise with a distributed 3rd party network of contractors who fulfill the work. We refer to this as our <em>Decentralized Network Management (DNM)</em> module</li>\n<li><a href=\"#ba5a53b2-8b99-4080-9ec1-ad085b5b7fe6\">FSM</a> - Relevant if you have an internal workforce or franchise type model where you have a high degree of control over compliance in terms of work fulfillment. We refer to this as our <em>Field Service Management (FSM)</em> module</li>\n<li><a href=\"#c406b8ad-fda5-434b-a45a-93b9b88643bf\">Gateway</a> - Relevant if you're an SMB product solution provider and you wish to tightly integrate with multiple job sources/brands (e.g. claims from a warranty company). You can do so by building an integration with the <em>Dispatch Gateway</em>. Once done, you'll be able to automatically receive jobs from the sources of work as well as send updates without requiring double entry of data.</li>\n</ul>\n<p><strong>Use Cases</strong></p>\n<p>The <a href=\"#39c4cc81-2e84-487d-b1f4-a3e98204916d\">Use Cases</a> includes guidance for how to go about building an integration for a variety of different use cases as the need may arise over time or based on your specific needs.</p>\n<p><strong>\"To Dispatch\" and \"From Dispatch\"</strong></p>\n<p>Each section is sub-divided into \"To Dispatch\" and \"From Dispatch\" sections to make it clear in which direction the information is flowing.</p>\n","_postman_id":"89b5e058-bddc-45b9-a7f9-24768630b499"},{"name":"High Level Flow & Code Samples","item":[],"id":"51ed9805-c1ff-4956-a976-424d100d0beb","description":"<p>Please view the working <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples\"><strong>code samples</strong></a> for connecting to our inbound and outbound endpoints. This is a valuable resource that will provide you with a jump start on working with Dispatch Connect (or henceforth \"The Connector\").</p>\n<p>The following diagram shows a high level interaction with the connector endpoints:</p>\n<img src=\"https://user-images.githubusercontent.com/8817368/39719546-38dab446-5242-11e8-9094-941cb1672a8f.png\" />\n\n<p>Our goal is to make connecting with Dispatch simple. To this end, we don't encumber you with multiple different endpoints to hit depending on what you're trying to do. Rather, all inbound requests are sent to a <strong>single</strong> endpoint (as illustrated above). Similarly outbound updates are retrieved from a <strong>single</strong> endpoint.</p>\n<p>That said, we are of course here to help you with any questions that you might have. And it's of course possible that we haven't covered every angle. If we encounter such a case, we will endeavor to make those updates to this documentation rather than address them in scattered emails and what not. In this sense, this is a living repository which will be updated as necessary to incorporate tweaks and enhancements as they become relevant and/or necessary.</p>\n","_postman_id":"51ed9805-c1ff-4956-a976-424d100d0beb"},{"name":"General Conventions","item":[],"id":"2f62cae6-7c1e-4eb5-827b-0e761068ad07","description":"<ul>\n<li><p>All date fields send to Dispatch should be an ISO timestamp unless expressly stated otherwise</p>\n</li>\n<li><p>Addresses:</p>\n<ul>\n<li><code>country</code> is defaulted to <code>United States</code>. The only other valid value at the moment is <code>Canada</code>. Or you can leave this out altogether and we'll assume it refers to the good ol' US of A.</li>\n<li><code>state</code> accepts the 2 character acronym or the <em>correctly</em> spelled long name (M i s s i s i s s i p p i !)</li>\n</ul>\n</li>\n<li><p>External ID - This correlates to the Enterprise ID or the identifier from an external system where the job was originated. We use this for match purposes on the Dispatch side and therefore there is no need for you to store the Dispatch IDs in your system. The convention for external IDs on a payload is as follows:</p>\n<ul>\n<li><code>external_id</code> - this is the external ID for the object itself. For example, if you're passing in a \"job\" record type, this will be your unique reference for the job record.</li>\n<li><code>external_related_id</code> - this is the external ID that points to a related object. For example (assuming a \"job\" record type):<ul>\n<li><code>external_organization_id</code> - this is the job's external organization unique reference</li>\n<li><code>external_customer_id</code> - this is the job's external customer unique reference</li>\n</ul>\n</li>\n</ul>\n</li>\n</ul>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">[\n  {\n    \"header\": {\n      \"record_type\": \"job\",\n      ...\n    },\n    \"record\": {\n      \"external_id\": \"your_job_external_id\",\n      \"external_organization_id\": \"your_job's_organization_external_id\",\n      \"external_customer_id\": \"your_job's_customer_external_id\",\n      ...\n    }\n  }\n]\n\n</code></pre>\n","_postman_id":"2f62cae6-7c1e-4eb5-827b-0e761068ad07"},{"name":"Authentication","item":[{"name":"HMAC","item":[],"id":"1ebe92b9-e964-492c-a97f-bf92df930ce4","description":"<p>This is used throughout these docs is the only authentication that you should be using other than certainly particular use cases pointed out in this doc and described next.</p>\n<p>Dispatch will provision you keys that will look something like this:</p>\n<ul>\n<li>Client ID: account|999|acme</li>\n<li>Client Secret: some_long_secret</li>\n</ul>\n<p>And you will pass them into the API headers as described <a href=\"#eebfe5f0-b55e-4df9-816a-312bcf673fc8\">here</a> and the <a href=\"#962ed6d7-0d98-404c-86c1-8573b0ee6d25\">code samples</a>.</p>\n<p>API calls made by this method are asynchronous and therefore you will always get a <code>200 OK</code> response for a successful POST. If you are curious as to why this is the case, please see the first question in the <a href=\"#6f55f1bc-25da-4b97-b7ec-c3c012edb69f\">FAQ</a>.</p>\n<p>If you want to associate the corresponding Dispatch IDs from a successful operation or be notified of errors you will need to <a href=\"#f4658708-f3a1-4cf5-bd32-2b452d2b2acf\">subscribe</a> to the<code>ack</code> and <code>error</code> messages.</p>\n","_postman_id":"1ebe92b9-e964-492c-a97f-bf92df930ce4"},{"name":"Oauth","item":[{"name":"Retrieve Bearer Token","event":[{"listen":"prerequest","script":{"type":"text/javascript","exec":["\r",""]}},{"listen":"test","script":{"type":"text/javascript","exec":["var data = JSON.parse(responseBody);\r"," \r","if (data.access_token) {\r","  tests[\"Token Generated\"] = true;\r","  postman.setEnvironmentVariable(\"token\", data.access_token);\r","}\r","else {\r","  tests[\"Token Generated\"] = false;\r","}\r","\r","postman.setEnvironmentVariable(\"token\", data.access_token);\r",""]}}],"id":"ffbbb740-1ec3-4ca9-be9f-48de84d8e664","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Cache-Control","value":"no-cache"},{"key":"Postman-Token","value":"41999b5b-f85d-0d7c-eece-cea3e8eaf7c9"}],"body":{"mode":"raw","raw":"{ \"grant_type\": \"client_credentials\", \r\n   \"client_id\": \"{{client_id}}\", \r\n   \"client_secret\": \"{{client_secret}}\" \r\n}\r\n"},"url":"https://api-sandbox.dispatch.me/oauth/token","urlObject":{"protocol":"https","path":["oauth","token"],"host":["api-sandbox","dispatch","me"],"query":[],"variable":[]}},"response":[{"id":"4f2082ac-285c-4b26-b44f-61db1cc884ad","name":"Response","originalRequest":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"},{"key":"Cache-Control","value":"no-cache"},{"key":"Postman-Token","value":"41999b5b-f85d-0d7c-eece-cea3e8eaf7c9"}],"body":{"mode":"raw","raw":"{ \"grant_type\": \"client_credentials\", \r\n   \"client_id\": \"{{client_id}}\", \r\n   \"client_secret\": \"{{client_secret}}\" \r\n}\r\n"},"url":"https://api-sandbox.dispatch.me/oauth/token"},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 25 Oct 2022 10:26:40 GMT"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Transfer-Encoding","value":"chunked"},{"key":"Connection","value":"keep-alive"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Allow-Headers","value":"Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Transaction-ID, X-Analytics-Tags, Analytics-Client-Id, X-Account-ID, X-API-Version, Client-Id"},{"key":"Access-Control-Allow-Methods","value":"DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Expose-Headers","value":"Content-Length"},{"key":"Access-Control-Max-Age","value":"86400"},{"key":"Cache-Control","value":"no-store"},{"key":"Etag","value":"W/\"7bb303b58621f2939da64906d07634fb\""},{"key":"Pragma","value":"no-cache"},{"key":"Set-Cookie","value":"_dispatch_api_session=emIvN212Ny9YWk1UZjVhQ0QyVklCUENkU1ltT1NSUGlmNW9lZWxlOENzelNUL04ycGgrWFozNFNVb25kSUkrRE50TG5STHNiT3N0QTBjenJwWWNRQ25mcWRzWFN1TTJrYlNUalVRRFZ4UHVtNllkMFMxQWx3SmZlNEhkeFluUTMtLTcveE04VFdOWDVlUG1FQnE1dDdieHc9PQ%3D%3D--c833e3e4cf9b19f712305ab116a84690397a93ef; path=/; HttpOnly"},{"key":"Vary","value":"Origin"},{"key":"X-Request-Id","value":"7dc5d0d0-c5ff-4bd8-a5e3-be41f883c8db"},{"key":"X-Runtime","value":"0.039175"},{"key":"X-Transaction-Id","value":"570dd11e-f716-4fb8-9ec0-c54f1fe15b6a"}],"cookie":[],"responseTime":null,"body":"{\n    \"access_token\": \"xxxxxxx8b2284108807290d1593cf01b657e2c7f9c9148b06dd1823f8061f\",\n    \"token_type\": \"bearer\",\n    \"expires_in\": 2544144,\n    \"created_at\": 1666607998\n}"}],"_postman_id":"ffbbb740-1ec3-4ca9-be9f-48de84d8e664"}],"id":"47fc3b18-adf8-40dd-a2be-6f192bafa18b","description":"<p>Our oauth authentication method is only for used for APIs that need to work synchronously and those examples are called out explicitly in these docs. Chances are that you will never need to use this method of authentication, so you can skip this section and come back to it if and when it becomes necessary.</p>\n<p>Dispatch will provision you keys that will look something like this:</p>\n<ul>\n<li>Client ID: some_long_id</li>\n<li>Client Secret: some_long_secret</li>\n</ul>\n<p>This will return an <code>access_token</code> that you will need to pass into<code>Authorization</code> key of the request header for all subsequent API calls:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">Authorization: Bearer xxxx30eaf43d7bf8f27df23a717a0033026a18c62d2a34e64450b528e1726a75\n\n</code></pre>\n","_postman_id":"47fc3b18-adf8-40dd-a2be-6f192bafa18b"}],"id":"82672c32-ca27-41a0-8996-645d69c19bde","description":"<p>There are 2 types of authentication used for integration to Dispatch.</p>\n<ul>\n<li>HMAC</li>\n<li>Oauth (almost never used)</li>\n</ul>\n","_postman_id":"82672c32-ca27-41a0-8996-645d69c19bde"},{"name":"Getting Started","item":[],"id":"1637f979-c83d-4e30-ac95-c8cd638300bf","description":"<p>The recommended steps to get started are as follows:</p>\n<ol>\n<li><p>Receive auth keys from Dispatch</p>\n</li>\n<li><p>Use the working <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples\">code samples</a> to start authenticating and sending/receiving data (see next step)</p>\n</li>\n<li><p>You should now be able to log into <a href=\"https://work-sandbox.dispatch.me\">https://work-sandbox.dispatch.me</a> using the service provider phone number that you supplied in your payload and “work the job” as a dispatcher and a tech. It’s a very intuitive experience but please see our <a href=\"http://training.dispatch.me\">training</a> for additional help (the training directs you to go to our production apps but during testing you’ll be using our sandbox apps)</p>\n</li>\n<li><p>Determine which \"Quick Start\" best fits your integration model</p>\n</li>\n<li><p>Wire up your system to send data to Dispatch. The payload structure should either be in an agreed upon custom format or in the canonical formats described in the “To Dispatch” playbook section.</p>\n</li>\n<li><p>Wire up your system to receive updates from Dispatch. The updates you make will be sent to our <code>agent/out</code> endpoint waiting for you to pick them up and process them. The “From Dispatch” playbook section describes the updates you can expect to receive (If you do not “care” for some of these updates we’d recommend just acknowledging and ignoring them. At some point when you do care for them you can just start consuming them). The payload structure will either be in the canonical formats described in the above link (default) or in an agreed upon custom format.</p>\n</li>\n<li><p>Testing and cutover</p>\n</li>\n</ol>\n<p>Please let us know if you have any questions</p>\n","_postman_id":"1637f979-c83d-4e30-ac95-c8cd638300bf"},{"name":"Dispatch Inbound (+)","item":[{"name":"Payload Structure","item":[],"id":"6e0e06aa-e37c-4715-96a2-bb0d3bcfc1ea","description":"<p>If required, you can send data in literally any format to Dispatch. If you do that, then it will be necessary to map from the structure that you are sending through to a structure that Dispatch understands. This exercise is typically performed by a member of the Dispatch ProServices team.</p>\n<p>It is possible however to eliminate this mapping step using our <em>canonical</em> payloads. The payload examples included within this document follow Dispatch's \"canonical\" payload. If you adhere to these, the connector will know how to process them automatically. If you are sending custom payloads, then you do not need to be adhering to these canonical structures.</p>\n<p>In a nutshell:</p>\n<ul>\n<li>If you are using Dispatch's canonical payloads you will need to ensure your payloads match those within this document</li>\n<li>If you are using custom payloads, then you do not need to adhere to the payloads in this document. Dispatch will take care of mapping what you send over as necessary. It will still be helpful for you to review the payload examples in this playbook so you can familiarize yourself with the data required for a successful integration.</li>\n</ul>\n","_postman_id":"6e0e06aa-e37c-4715-96a2-bb0d3bcfc1ea"},{"name":"Inbound Endpoint","item":[],"id":"962ed6d7-0d98-404c-86c1-8573b0ee6d25","description":"<p>The endpoint to send all inbound requests are:</p>\n<ul>\n<li>Sandbox: <a href=\"https://connect-sbx.dispatch.me/agent/in\">https://connect-sbx.dispatch.me/agent/in</a></li>\n<li>Production: <a href=\"https://connect.dispatch.me/agent/in\">https://connect.dispatch.me/agent/in</a></li>\n</ul>\n<p>Our <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/DispatchInbound\">inbound sample code</a> has some working examples for both canonical and customer payloads in a number of different programming languages. This should help you get going.</p>\n<p>To be clear: Dispatch only has a single endpoint with which to send all inbound requests. Each record identifies what transaction needs to run by inspecting:</p>\n<ul>\n<li>The <code>RecordType</code> http header or ...</li>\n<li>An identifying attribute in the payload body (the canonical payloads use this method). Generally speaking, this method is preferred because if you use the http header option you are essentially limiting yourself to a single transaction type per post, whereas if you include this in the payload body, you can have multiple transaction types per post (again, refer to the canonical payload examples in this document to see this option in action)</li>\n</ul>\n","_postman_id":"962ed6d7-0d98-404c-86c1-8573b0ee6d25"},{"name":"Http Headers","item":[],"id":"eebfe5f0-b55e-4df9-816a-312bcf673fc8","description":"<p>The following should be included in the http headers:</p>\n<ul>\n<li><code>X-Dispatch-Key</code> - e.g. account|999|acme - public ID</li>\n<li><code>X-Dispatch-Signature</code> - the hmac hash of the private key</li>\n<li><code>RecordType</code> - (optional - see section above) e.g. \"job\", \"organization\" - can be any value that distinguishes the payload. This is only required if the the payload content cannot be used to determine what record type is being passed.</li>\n<li><code>MessageId</code> - (optional but recommended) this should be a unique value for the message being sent. You can use this to correlate with the \"msg_id\" that is sent with <a href=\"https://playbooks.dispatch.me/#f4658708-f3a1-4cf5-bd32-2b452d2b2acf\">the ack and err outbound messages</a></li>\n</ul>\n","_postman_id":"eebfe5f0-b55e-4df9-816a-312bcf673fc8"},{"name":"Upsert","item":[],"id":"46d0cf6e-3648-4982-917e-d8865fe09f73","description":"<p>The <code>external_id</code> you pass in is used for lookup logic. Such that:</p>\n<ul>\n<li>If the <code>external_id</code> does not exist on Dispatch, a new record will be inserted</li>\n<li>Otherwise the record will be updated</li>\n</ul>\n","_postman_id":"46d0cf6e-3648-4982-917e-d8865fe09f73"},{"name":"Processing Options","item":[{"name":"Bulk Processing","item":[{"name":"Orchestration","id":"5e03f259-b9d3-45f4-98c8-905d5af3f1f1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"job\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"title\": \"Job title\",\r\n      \"status\": \"scheduled\",\r\n      \"description\": \"Some description.\\n\\n# Accepts *markdown*\",\r\n      \"external_id\": \"your_enterprise_job_id\",\r\n      \"address\": {\r\n        \"street_1\": \"1213 Summer St\",\r\n        \"street_2\": \"apt. 1\",\r\n        \"postal_code\": \"01234\",\r\n        \"city\": \"Boston\",\r\n        \"state\": \"MA\"\r\n      },\r\n      \"service_type\": \"plumber\",\r\n      \"customer\": {\r\n        \"first_name\": \"Jane\",\r\n        \"last_name\": \"Doe\",\r\n        \"external_id\": \"your_enterprise_customer_id\",\r\n        \"email\": \"email@dispatch.me\",\r\n        \"phone_numbers\": [\r\n          {\r\n            \"number\": \"+15550913813\",\r\n            \"primary\": true,\r\n            \"type\": \"Mobile\"\r\n          }\r\n        ],\r\n        \"home_address\": {\r\n          \"street_1\": \"3913 Ford Street\",\r\n          \"city\": \"Revere\",\r\n          \"state\": \"MA\",\r\n          \"postal_code\": \"02151\"\r\n        }\r\n      },\r\n      \"external_organization_id\": \"your_organization_id\"\r\n    }\r\n  },\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"user\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"external_id\": \"your_tech_id\",\r\n      \"first_name\": \"John\",\r\n      \"last_name\": \"Kruger\",\r\n      \"roles\": [\r\n        \"technician\"\r\n      ],\r\n      \"phone_number\": \"(555) 122-1912\",\r\n      \"email\": \"devs+paulkruger@dispatch.me\",\r\n      \"external_organization_id\": \"your_organization_id\"\r\n    }\r\n  },\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"appointment\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"external_id\": \"your_enterprise_job_id\",\r\n      \"time\": \"2018-06-13T22:00:00.000Z\",\r\n      \"duration\": 1600,\r\n      \"external_user_id\": \"your_tech_id\",\r\n      \"external_job_id\": \"your_enterprise_job_id\"\r\n    }\r\n  },\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"attachment\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"external_job_id\": \"your_enterprise_job_id\",\r\n      \"entity_type\": \"Job\",\r\n      \"description\": \"some note\"\r\n    }\r\n  }\r\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Let’s say you want to create job, creating an appointment and assign it to a technician and add note all in one go. You can simply pass all this into the payload and call the API once. The Quick Starts are good examples that employ this option</p>\n<p>Take note that the order is important as the payload will be processed in the order the data is provided.</p>\n<p>So essentially, you want to have the following sections passed into the payload:</p>\n<ul>\n<li>job</li>\n<li>technician (only if there's a chance the technician does not yet exist in Dispatch or you wish to update the tech details)</li>\n<li>appointment</li>\n<li>note</li>\n</ul>\n<p>The payload illustrates how you can send over multiple requests at once.</p>\n<p>In the event this is relevant, we recommend you reach out to your Dispatch representative to advise on the payload structure to send.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"5e03f259-b9d3-45f4-98c8-905d5af3f1f1"},{"name":"Bulk Processing","id":"02e5fd93-cf79-4a4e-8378-f1878ea71015","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"job\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"title\": \"job 1\",\r\n      \"other payload fields\": \"...\"\r\n    }\r\n  },\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"job\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"title\": \"job 2\",\r\n      \"other payload fields\": \"...\"\r\n    }\r\n  },\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"job\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"title\": \"job 3\",\r\n      \"other payload fields\": \"...\"\r\n    }\r\n  },\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"job\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"title\": \"job 4\",\r\n      \"other payload fields\": \"and so on\"\r\n    }\r\n  }\r\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Send a whole bunch of requests through at once. The connector will take care of the rest. The payload illustrates how you can send over multiple requests at once.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"02e5fd93-cf79-4a4e-8378-f1878ea71015"}],"id":"c7dc4f42-670e-4e0c-b778-7c8444a1fff7","description":"<p>You'll notice that all the <em>canonical</em> payload examples are sent in an array structure i.e. it is enclosed in <code>[]</code>. This means that you can send your requests individually or in bulk. It is generally recommended to send as many requests at a time. So if for example you are polling your data and picking up a change set to send over to Dispatch, you can either:</p>\n<ul>\n<li>Call the API for each requests</li>\n<li>Call the API once and past all requests into the payload</li>\n</ul>\n<p>It is generally recommended to follow the latter approach where ever possible.</p>\n<p>This section illustrates two common use cases for bulk processing.</p>\n<ul>\n<li>Orchestration - call a related set of APIs one after the other</li>\n<li>Bulk Processing - import records into Dispatch</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"69821bff-cdc6-48b9-83b5-12754516b9ef","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"e3be719d-5a35-4851-a8af-130a2801394e","type":"text/javascript","exec":[""]}}],"_postman_id":"c7dc4f42-670e-4e0c-b778-7c8444a1fff7"},{"name":"CSV","item":[{"name":"Organization","id":"57375c97-8b93-4368-9ada-571e30440689","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"text/csv"}],"body":{"mode":"raw","raw":"v3.organization.name,v3.organization.email,v3.organization.external_id,v3.organization.phone_number,v3.organization.address.street_1,v3.organization.address.street_2,v3.organization.address.city,v3.organization.address.state\nAlpha,alpha@dispatch.me,555-424-2312,1724 Beacon St,Apt 1a,Brookline,MA\nBeta,beta@dispatch.me,555-904-5223,88 Quincy St,,New York,NY"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>We are just providing the canonical example for the organization record. As you'll notice the headers of the file have a dot notation that correlates with the corresponding canonical json format. The same is true for the import/export CSV format for the other Dispatch entities (technician, job, appointment, billing documents etc.).</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"57375c97-8b93-4368-9ada-571e30440689"}],"id":"6a263b72-80a6-48d0-b9b2-13c323befbbd","description":"<p>The connector can support any inbound and outbound format. However as CSV is a fairly common format we have added a section to address individually. And... as with all connector integrations - we can work with CSV files with any column header naming convention (we have a simple translation layer that can be configured to transform the input into the format required for importing to Dispatch). And similarly for the outbound - if the file needs to have particular column headers we can do the translation on our end to meet that objective.</p>\n<p>That notwithstanding, the rest of this section will use the Dispatch inbound/outbound canonical format to illustrate.</p>\n","event":[{"listen":"prerequest","script":{"id":"db40bbef-dd4d-49b8-8a3e-db398c10fe62","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"06dc852b-face-441c-afd8-c061ee30e178","type":"text/javascript","exec":[""]}}],"_postman_id":"6a263b72-80a6-48d0-b9b2-13c323befbbd"}],"id":"586587ee-ec31-4347-90d7-52df30436b3b","description":"<p>At it's heart, the connector is an orchestrator of Dispatch's lower level APIs. A single update to Dispatch may involve multiple lower level interactions (GET, POST, PATCH on jobs, customers, etc.). We don't want you to have to be encumbered with having to know how to interact with Dispatch's lower level APIs. Rather our expectation is that you send all the data needed for a given transaction in a single payload to a single endpoint and the connector will perform all the magic for you.</p>\n","_postman_id":"586587ee-ec31-4347-90d7-52df30436b3b"}],"id":"8cfef1f4-fd46-49cc-91c3-7d63dee4a392","description":"<p>The <strong>To Dispatch</strong> sections in this document describe the Dispatch Inbound integration use cases.</p>\n","_postman_id":"8cfef1f4-fd46-49cc-91c3-7d63dee4a392"},{"name":"Dispatch Outbound (+)","item":[{"name":"Payload Structure","item":[],"id":"3571ed91-9317-4784-a706-b7721daed3db","description":"<p>Every payload that you pick up from the outbound endpoint will include the following payload wrapper. The details inside the <code>Payload</code> key will contain the relevant updates for your system. The wrapper elements - specifically <code>ProcedureID</code>and <code>Receipt</code> are used to mark the payload as having been received and will remove the payload from the queue. The technical steps for doing so are best illustrated in the <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/DispatchOutbound\">outbound code samples</a>.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">[\n   {\n    \"Message\": {\n      \"Request\": {\n        \"ProcedureID\": \"b332b621-f7ef-405d-8075-7332aef9bba7\",\n        \"Type\": \"some_type\",\n        \"Payload\": {\n          \"some_payload\": \"either the canonical described in this document or an agreed upon custom format\"\n        }\n      },\n      \"ID\": \"ed172c8b-aba0-4f1b-b477-6dc9c487fcbd\",\n      \"Receipt\": \"AQEBQ4Uw8YrVICgfZjXqtQhK6/PBodouACu8J4P0z27ysnHLTi7rC0r7cueMFnq9CuDpG6lXtCTKdXrjjrUM0GTi3PCY/tjCAd8uC77KN3tTLGFwiSKRUHoni4wLqRjyvNYnJFv2Y1sHn8DSgSIzB8kx5Zv6krK17jvzwhxom0+nM5g99iuavW+TtrDdnQVwc5lPw5/q+AuxSVzkWQS3eyP1AVXpXUpRUuDutvPggo8890HPPO6p+BfPZ1STxB1bN62PXuRRgG1RMu+O3vfP78kGR+DWkJSUr4kDuX3LLhztNtTgyPY6BQbcF7SZBMNExGkf+B1LbUlDmXtd33U5QjAXzw==\"\n    }\n  }\n]\n\n</code></pre>\n<p>The following should be included in the http headers:</p>\n<ul>\n<li><p><code>X-Dispatch-Key</code> - same as with inbound endpoint</p>\n</li>\n<li><p><code>X-Dispatch-Signature</code> - same as with inbound endpoint</p>\n</li>\n</ul>\n<p>The following conventions apply to all event processing:</p>\n<ul>\n<li><p><code>external_id</code> - This is the Enterprise's record ID</p>\n</li>\n<li><p><code>friendly_external_id</code> (only for jobs) - this is an optional field. Very often systems have the technical \"ugly ID\" that only the techies in your organization know exists. And there is also a \"friendly ID\" that end users and customers use as references. If this is the case, then please put the \"ugly ID\" into the <code>external_id</code> and the \"friendly ID\" into <code>friendly_external_id</code></p>\n</li>\n<li><p><code>updated_at</code> - Use this to mark the time the event occured</p>\n</li>\n</ul>\n<p>The structures defined in \"From Dispatch\" sections are our canonical default. We like to keep these payloads small and relevant to make it easier and more obvious for you to process. However, if you think there are data elements that you need, please let us know and we should be able to configure it for you. Similarly (as described in the section above), if you already have your own preferred structure and/or format in which you prefer to receive the data, please let us know - there's a good chance we'll be able to accomodate you .</p>\n<p>Please be aware that we may put additional events in the stream as our product evolves. Although we will not <em>change</em> the names of attributes in the payload, it is possible that we'll add <em>new</em> attributes to the payload. <strong>Therefore make sure that your payload consumption will not break if a new attribute starts being included.</strong></p>\n<p>If you are not using the outbound endpoint for picking up messages (see next section) then the payload will not contain the <code>Message</code> envelope. It will look as follows:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">  {\n    \"type\": \"some_type\",\n    \"payload\":\n    {\n        \"some_payload\": \"either the canonical described in this document or an agreed upon custom format\"\n    }\n}\n\n</code></pre>\n<p>Where:</p>\n<ul>\n<li><p><code>type</code> - e.g. <code>job</code>, <code>appointment</code> etc.</p>\n</li>\n<li><p><code>payload</code> - data is the same as what is delivered in the <code>Payload</code> in the agent out endpoint.</p>\n</li>\n</ul>\n","_postman_id":"3571ed91-9317-4784-a706-b7721daed3db"},{"name":"Outbound Endpoint","item":[],"id":"8eaf2873-77e7-41f0-bb32-5ccdc837d49f","description":"<p>The endpoint to send all inbound requests are:</p>\n<ul>\n<li><p>Sandbox: <a href=\"https://connect-sbx.dispatch.me/agent/in\">https://connect-sbx.dispatch.me/agent/out</a></p>\n</li>\n<li><p>Production: <a href=\"https://connect.dispatch.me/agent/in\">https://connect.dispatch.me/agent/in</a></p>\n</li>\n</ul>\n<p>Our <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/DispatchOutbound\">outbound sample code</a> has some working examples for both canonical and customer payloads in a number of different programming languages. This should help you get going.</p>\n<p>Dispatch can support other types of outbound integrations such as sending webhooks to a provided endpoint, SFTP or FTP location if that is your preference (SFTP, FTP and other similar \"unusual\" use cases may incur an additional fee in order to support).</p>\n","_postman_id":"8eaf2873-77e7-41f0-bb32-5ccdc837d49f"},{"name":"Validation","item":[],"id":"3476fb12-0709-4dec-a06d-4742c95130a4","description":"<p>Updates received on the Dispatch Platform may be received from various sources. Most updates will be made directly using the Dispatch apps but they may also be made via our gateway connected apps, such as Service Titan, Service Fusion and House Call Pro.</p>\n<p>While we can guarantee adherence to strict data input when using the Dispatch apps for receiving field updates, we cannot guarantee that this strictness will be adhered to when updates are received from one of the gateways connected apps (simply because those apps have their own internal logic which are governed by the companies that own those apps).</p>\n<p>An example, might be what we call \"status messages\". When pausing a job in Dispatch you have the option of specifying a pause reason from a list that the user can select from. This most likely will not be the case when receiving a similar update from the gateway connected apps and therefore the pause reason may be different or missing in those cases. The same may be the case for other updates.</p>\n<p>Therefore we advocate for a more lenient validation policy when receiving updates from Dispatch. Because our view is that it's better for you to receive as much info as is provided from the field rather than having some updates be blocked due to strict validation policies (e.g. in this case, if you validated a pause update for having a different pause reason -- or lacking any -- than what we've set up in Dispatch, you'd miss the update that the job was paused entirely). So our philosophy is that less complete information is better than no information when it comes to gateway connected updates.</p>\n","_postman_id":"3476fb12-0709-4dec-a06d-4742c95130a4"},{"name":"Polling Design Best Practices","item":[],"id":"9e6b027d-46d8-48f2-96ed-4ae5c009fc02","description":"<ul>\n<li><p><strong>Each time you poll the agent/out endpoint you should pull down using a</strong> <strong><code>maxNumberOfMessages</code></strong> <strong>of 10</strong> (this is currently the highest number of messages you can request at a time). If the messages returned is equal to <code>maxNumberOfMesssages</code> you should poll again. Repeat until the queue is empty. In this way, you will clear out the queue each time you poll which ensures that your updates will be timely and the queue will remain low. The <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/DispatchOutbound\">code samples</a> incorporate this logic in them - be sure to follow this guidance!</p>\n</li>\n<li><p><strong>Make sure to \"ack\" each message directly after downloading it.</strong> That is, you should NOT poll for 10 messages, process them all and then ack each message. Instead you should poll for 10 messages, process the first and then ack it, process the second and ack it and so on. This is important because there is an expiration (typically 30 seconds) to ack a polled message and if you do it after that time, the ack will be rejected and the message will stay in the queue until you poll it again. Again the <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/DispatchOutbound\">code samples</a> incorporate this logic in them, so if you follow the pattern shown you'll be in good shape.</p>\n</li>\n<li><p><strong>Separate polling the endpoint from the business logic to update your business system.</strong> Often business logic (including multiple API interplay steps) can be involved and slow the system down. You should instead download the messages into a local store (e.g. sql table) and \"ack\" immediately after which lets us know that you received the message. From there you can process into your business systems as necessary. Needless to say, if you process directly to your business system and that takes \"too long\", you will run into the expiration issue mentioned above.</p>\n</li>\n<li><p><strong>Only have a single process that polls the endpoint.</strong> If you have multiple processes polling the endpoint they can interfere with one another (as SQS makes messages invisible to other processes from the process being polled in order to prevent a message from being processed more than once). If you wish to employ multiple processes to poll the endpoint, then you should ensure that they are timed to alternate with one another and you should reach out Dispatch as we may need to tune the queue based on your polling strategy.</p>\n</li>\n<li><p><strong>If for some reason you get an exception while locally storing a message, do not ack the message.</strong> If you do, the message will disappear from the queue and there will be data loss. By not acking it, you are ensuring that the message remains on the queue for processing the next time you poll. However, please be aware that if you are repeatedly getting exceptions while locally storing a message, the queue will grow and will block processing due to the FIFO nature of the queue. Therefore you should be sure to research this event should it occur to prevent a backlog (which will have the affect of delaying the timely processing of messages sent from Dispatch)</p>\n</li>\n</ul>\n","_postman_id":"9e6b027d-46d8-48f2-96ed-4ae5c009fc02"}],"id":"55e918db-425e-4015-be05-d8a586b08a74","description":"<p>You can subscribe to Dispatch events in order to process updates into your system. The <strong>From Dispatch</strong> sections in this document describe the relevant use cases that you should follow. There are however some conventions that apply across the board and these are noted in the sections below.</p>\n","_postman_id":"55e918db-425e-4015-be05-d8a586b08a74"},{"name":"Postman","item":[],"id":"f5148e32-7c19-42f2-a429-9c64d2b8aac8","description":"<p>While these docs have been created in postman and you can launch them in the postman desktop experience, the payload samples will not work within postman. This is because the connector requires HMAC authentication which is not currently supported in Postman. Instead, you will need to work within an <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples\">environment like Python</a> to get the examples working.</p>\n","_postman_id":"f5148e32-7c19-42f2-a429-9c64d2b8aac8"},{"name":"IP Whitelisting","item":[],"id":"21985f89-1f13-4204-bced-21af10612285","description":"<p>If you require IP whitelisting you will need to white list the following IPs:</p>\n<p><strong>Production</strong>:</p>\n<ul>\n<li>52.207.11.96</li>\n<li>100.24.162.73</li>\n<li>52.201.100.93</li>\n<li>34.224.162.59</li>\n</ul>\n<p><strong>Sandbox</strong>:</p>\n<ul>\n<li>3.233.225.94</li>\n<li>34.224.162.59</li>\n</ul>\n","_postman_id":"21985f89-1f13-4204-bced-21af10612285"},{"name":"Sandbox Links","item":[],"id":"b6735f29-6e74-4cba-a990-5e87d38d3bb8","description":"<p>You should perform testing against our sandbox apps. Please use the following links:</p>\n<ul>\n<li><a href=\"https://manage-sandbox.dispatch.me\">Manage Desktop App</a> - Corporate Internal User View (depending on your use case, this may or may not be relevant)</li>\n<li><a href=\"https://work-sandbox.dispatch.me\">Work Desktop App</a> - Contractor View (for Dispatchers)</li>\n<li>Dispatcher Mobile App<ul>\n<li><a href=\"https://install.appcenter.ms/orgs/dispatch-technologies/apps/sandbox-dispatch-manager-1/distribution_groups/external%20-%20public\">Android</a></li>\n<li><a href=\"https://install.appcenter.ms/orgs/dispatch-technologies/apps/sandbox-dispatch-manager/distribution_groups/external%20-%20public\">iOS</a></li>\n</ul>\n</li>\n<li>Technician Mobile App<ul>\n<li><a href=\"https://install.appcenter.ms/orgs/dispatch-technologies/apps/sandbox-dispatch-field-1/distribution_groups/external%20-%20public\">Android</a></li>\n<li><a href=\"https://install.appcenter.ms/orgs/dispatch-technologies/apps/sandbox-dispatch-field/distribution_groups/external%20-%20public\">iOS</a></li>\n</ul>\n</li>\n</ul>\n<p>If you’re using an iPhone, you may receive this message when first opening the app (this only will happen for the sandbox app as it's not in the app store):</p>\n<img src=\"https://content.screencast.com/users/nvsimon/folders/Playbooks/media/e0ed0adc-b21e-4644-b5ac-0e336ecd3dc0/06.29.2018-15.38.png\" />\n\n<p>Go to Settings | General | Device Management and trust the app:</p>\n<img src=\"https://content.screencast.com/users/nvsimon/folders/Playbooks/media/6fcbcd11-2f98-4c8f-8949-2d8d8397553b/06.29.2018-15.43.png\" />","_postman_id":"b6735f29-6e74-4cba-a990-5e87d38d3bb8"},{"name":"Questionaire","item":[],"id":"563a28eb-1b4c-46f8-bbaa-6f58777cec88","description":"<p>If you have not yet engaged with the Dispatch team it would be helpful to respond to this questionaire. This will help clarify your use case and help us provide you with the necessary guidance for your use case.</p>\n<p><strong>Business model</strong></p>\n<p>Do you maintain your own W2 workforce or do you use contractors?</p>\n<p><strong>Geographical Areas</strong></p>\n<p>How many geographical areas do you cover? Do any of your techs overlap between these locations?</p>\n<p><strong>Appointment Scheduling</strong></p>\n<p>What is your preferred method of setting up an appointment?</p>\n<ol>\n<li>We’ll determine that in our system and pass that into Dispatch</li>\n<li>We would like to let the contractor negotiate that with the customer</li>\n<li>We’d like to collect preferred times from the customer and send those over to the contractor</li>\n<li>Combination of the above or other? Please describe</li>\n</ol>\n<p><strong>Service Provider Setup</strong></p>\n<p>You can either have the Service Providers set up “on the fly” (i.e. the first time they have a job sent to them they’ll receive a notification to get download the app etc.) or they can be set up in advance. What is your preference?</p>\n<p><strong>Decline Reasons</strong></p>\n<p>When contractors are sent a job they have the option to decline. First of all, should they have that option. Second of all, the following are the decline reasons they will see by default. Let us know if you’d like to adjust these:</p>\n<ul>\n<li>Incorrect Service Area</li>\n<li>No Availability</li>\n<li>Wrong Trade</li>\n</ul>\n<p><strong>Complete Reasons</strong></p>\n<p>When a job is complete there are various “complete reasons” that can be selected from. The following is what they will see by default. Let us know if you would like to adjust these:</p>\n<ul>\n<li>Service Provided</li>\n<li>Customer Does Not Want Service</li>\n</ul>\n<p><strong>Source System</strong></p>\n<p>Is your source system home grown or do you use a 3rd party product? If the latter, what product are you using? Which programming language will you be using?</p>\n<p><strong>Canonical/non-Canonical</strong></p>\n<p>The playbooks describe canonical data structures for <a href=\"https://playbooks.dispatch.me/#c5e28ae2-134f-4fa3-98dd-955bea2a89f0\">sending</a> and <a href=\"https://playbooks.dispatch.me/#c73af39b-732f-4f5b-b3a9-650154d2f687\">receiving</a> data. Will you be using these canonical structures or would you prefer to define your own (either for sending or receiving or both)?</p>\n","_postman_id":"563a28eb-1b4c-46f8-bbaa-6f58777cec88"},{"name":"FAQ","item":[{"name":"Why do I see a \"200 OK\"?","item":[],"id":"f7482974-5d46-4daa-8de4-83d9bc833409","description":"<p><strong>Why do I see an \"200 OK\" message in cases where the payload I sent through did not achieve the desired result?</strong></p>\n<p>This is for 2 main reasons:</p>\n<ol>\n<li>The connector <code>agent/in</code> endpoint is a multi purpose endpoint. You will send data to this endpoint regardless of whether you're creating an organization, job, technician or something else entirely. The <code>agent/in</code> endpoint therefore is merely a way to receive requests that are then passed on to our lower level APIs for processing into Dispatch.</li>\n<li>The connector is a data mapping tool. Though we accept a canonical payload (described in this playbook) we also allow custom payloads to be sent through in which case we'll do the mapping to ensure the desired result is achieved. Once again, this means that we cannot validate that the structure adheres to any particular format.</li>\n</ol>\n","_postman_id":"f7482974-5d46-4daa-8de4-83d9bc833409"},{"name":"Retries","item":[],"id":"f6b1ce50-32da-43f7-a72f-f4540f838c3f","description":"<p><strong>Do you have a retry mechanism?</strong></p>\n<p>Yes. Per above the <code>agent/in</code> endpoint does nothing else than receive inbound requests. It then passes it onto the Dispatch lower level services for processing to Dispatch (which includes the validation, mapping, cross-referencing/upsert logic and necessary API steps). And in that layer a retry mechanism is inbuilt such that if there is a period of disruption (500 errors) the retry mechanism will automatically kick in. This also means that Dispatch stores all requests sent to the connector <code>agent/in</code> endpoint regardless of whether it got successfully processed into Dispatch. And we have this archive at our disposal for analysis and replay purposes (if that action becomes necessary).</p>\n<p>Given this, the only possible point of failure between a source system and Dispatch is if the <code>agent/in</code> endpoint is not available. And the only time that would happen is if AWS had some sort of outage which is a very rare occurrence. That said, in order to achieve an absolute fail safe design, we would recommend that you build in a retry mechanism when posting to our <code>agent/in</code> endpoint.</p>\n","_postman_id":"f6b1ce50-32da-43f7-a72f-f4540f838c3f"},{"name":"Empty response on agent/out","item":[],"id":"38e2694d-c968-4ed8-84c7-9200cdb72f6a","description":"<p><strong>When I post to agent/out in rapid succession subsequent posts come up with an empty response. If I post again a little later, the response comes up again. Why is that?</strong></p>\n<p>This is a feature of Amazon SQS which is the underlying technology and it is employed to prevent two parallel processes from processing the same message. By default this \"black out\" is 30 seconds but can be adjusted if necessary. This is typically something that is encountered while debugging in a development environment. We recommend that you follow the processing logic implemented in the code samples which will clear out the queue for each iteration.</p>\n","_postman_id":"38e2694d-c968-4ed8-84c7-9200cdb72f6a"},{"name":"Typical errors","item":[],"id":"beb9fbf7-86a0-4429-a1fa-3c015d9968c2","description":"<p><strong>What errors should I expect to see at the</strong> <strong><code>agent/out</code></strong> <strong>endpoint?</strong></p>\n<p>Almost all errors that you'll encounter will be during the initial development and testing phase. Once that stage has been passed, you'll find that errors are very few and far between. In fact, a key architectural goal of the connector is to maximize throughput and eliminate errors stopping integration to the extent possible. This is because the thing that is most disconcerting to end users is when there is a disruption in service. For example, if an invalid email is passed we will strip it out rather than stopping the integration. The same is true for invalid phone numbers. And therefore for all practical considerations, the following are the errors we tend to see in a production environment:</p>\n<ul>\n<li>Job Errors<ul>\n<li>Address not complete - if both state and zip are missing</li>\n</ul>\n</li>\n<li>Technician Errors<ul>\n<li>Missing email and phone number - at least one required</li>\n<li>Invalid phone</li>\n<li>Phone number must be mobile</li>\n<li>Invalid email</li>\n</ul>\n</li>\n</ul>\n","_postman_id":"beb9fbf7-86a0-4429-a1fa-3c015d9968c2"}],"id":"6f55f1bc-25da-4b97-b7ec-c3c012edb69f","_postman_id":"6f55f1bc-25da-4b97-b7ec-c3c012edb69f","description":""},{"name":"Salesforce Connector","item":[{"name":"Overview","item":[],"id":"0fbc2264-0c8e-4f6a-8e6d-9b35e079305d","description":"<p>As we have a strategic relationship with Salesforce and many of our typical prospects and clients use Salesforce we have built a Salesforce connector to make it super easy to integrate with Salesforce. Whatever your configuration!</p>\n<p>Let's review that last point for a minute. We're fully aware that within 5 minutes of installing Salesforce inside your organization, you have utilized Salesforce's incredible extensible platform to add new custom fields, objects - you name it! <strong>Therefore it is a central tenet of our Salesforce integration that we are not tied to any specific Salesforce configuration. We are not tied to specific licensing.</strong> Whatever your current Salesforce implementation, no matter how highly customized (and believe us, we've seen incredibly customized Salesforce environments - doesn't phase us in the least) - we can integrate to it no problem!</p>\n<p>Another item worth mentioning is that we do have considerable experience on the Salesforce Platform and therefore our generally recommended implementation strategy is to let Dispatch focus on building the integration. In fact, you can consider us as an additional resource on your projects - in that we'll take care of the integration aspect. And of course, we'll do this with full transparency so that you can know and be sure what changes we are implementing into your environment. Based on this, a typical project implementation breaks down as follows:</p>\n<ul>\n<li>Salesforce business logic - often you want to make enhancement to your Salesforce platform. Forms, LWC, workflows, etc. This is your business logic and you'll usually work with a Salesforce expert or consultant who will help you bring these to life.</li>\n<li>Salesforce Dispatch integration - this is where we typically come in. We just make sure that whatever needs to flow over (object, fields etc.) gets sent over. And whatever needs to flow back from Dispatch gets sent back. We'll typically add the necessary fields as it pertains to integration as well as the integration logic itself (more about this below). And obviously we'll work with your implementation team in terms of the additional objects and fields that they have created.</li>\n</ul>\n<p>The above is a good separation of concerns - business logic vs. integration logic. And provides a clear delineation of who is responsible for which aspect. The <a href=\"#5f88500b-87a3-4ffc-88ed-37f430ba4634\">example</a> further illustrates and discusses this point.</p>\n","_postman_id":"0fbc2264-0c8e-4f6a-8e6d-9b35e079305d"},{"name":"Dispatch Connect and the Salesforce Connector","item":[],"id":"42e96984-9954-4984-a49c-cb76f92e7347","description":"<p>So why would you want to use the Salesforce Connector given that we have our Dispatch Connect integration product (as evidenced by this playbook)?</p>\n<p>Dispatch Connect is used as our general purpose integration tool. The Salesforce connector essentially uses the power of Dispatch Connect behind the scenes. That is when we send updates from Salesforce we are sending it to our <a href=\"#962ed6d7-0d98-404c-86c1-8573b0ee6d25\">connect inbound endpoint</a> using a <a href=\"#6e0e06aa-e37c-4715-96a2-bb0d3bcfc1ea\">custom (or non-canonical) payload structure</a> for further processing on the Dispatch backend. And when we send updates from Dispatch to Salesforce we are leveraging our <a href=\"#55e918db-425e-4015-be05-d8a586b08a74\">connect outbound</a> layer.</p>\n<p>We just make it very easy to do that using Salesforce apex via our managed package.</p>\n<p>We then do all the transformational work as part of the Dispatch Connect mapping layer. Which means:</p>\n<ul>\n<li>Inbound payloads from Salesforce containing your custom objects and fields are transformed as necessasry in the connect mapping layer.</li>\n<li>Outbound payloads to Salesforce are similarly transformed to update the fields that require updating.</li>\n</ul>\n<p>This will be expanded on in the <a href=\"#5f88500b-87a3-4ffc-88ed-37f430ba4634\">example</a>.</p>\n","_postman_id":"42e96984-9954-4984-a49c-cb76f92e7347"},{"name":"Using Agile","item":[],"id":"ff0032bf-1dc9-4c15-8ca7-b1a46e415f06","description":"<p>Given the preamble of the <a href=\"#0fbc2264-0c8e-4f6a-8e6d-9b35e079305d\">overview</a>, it may come as no surprise that we like to follow an agile approach for Salesforce projects - if you allow us to do so! Experience has shown that visualizing the integration is the best way to approach a project as early as possible in the project lifecycle. Visualization allows concepts to be brought down from the abstract into the tangible and therefore serves to educate in very real terms how the systems can work together, how the integration can be built (and with what speed), and what kind of data flows between the systems and how it might look on either side of the divide. And of course it allows an iterative approach based on that experience. See something you like, or something you don't like? Well we can adjust that and meet again (typically in very short order ) to review the revised look and so on and so forth. In summary, a typical agile approach would typically work as follows:</p>\n<ul>\n<li>Give access of a sandbox instance of your production environment to Dispatch with the briefest of explanation of where your providers (typically types of `Accounts`) and jobs (typically `Work Orders`) are stored in Salesforce. No further detail. <strong>This is all we need to get going.</strong></li>\n<li>Give Dispatch a little time to build out a 2 way integration with Dispatch letting our team make some assumptions for the data that needs to flow.</li>\n<li>Meet to review - we'll provide a demo. If this is the first deep dive, it should definitely help you to understand the things mentioned above. Input provided from this session will serve to further make it relevant in subsequent sessions.</li>\n<li>Give Dispatch a little time to take in the input from above and incorporate and make it more relevant</li>\n<li>And so on and so forth</li>\n</ul>\n<p>Having said all that, we'd encourage you to give Dispatch access to your sandbox at the earliest stage of the project. If possible, straight after the kick off!</p>\n","_postman_id":"ff0032bf-1dc9-4c15-8ca7-b1a46e415f06"},{"name":"Salesforce Dev Features","item":[{"name":"Dispatch Managed Package","item":[{"name":"Dispatch Connect Aligned Integration Product","item":[],"id":"95f99be0-442d-4aca-8ca3-0f6b9356bcf2","description":"<p>New Salesforce integrations will use this product exclusively. As mentioned earlier in the documentation, the Salesforce Connector interacts with the Dispatch Connect product. This document describes in detail both the inbound and outbound integration flows.</p>\n<ul>\n<li><p>Inbound (<a href=\"#70e7df32-7dd4-44ad-b904-c3e9327eb151\">Salesforce to Dispatch</a>) - the managed package is used to send hmac encrypted payloads to the Dispatch Connect endpoint. The Dispatch Connect credentials for doing so are stored and encrypted in the Salesforce instance.</p>\n</li>\n<li><p>Request/Response - in certain use cases, it may be necessary to use real time request/response integration features. Retrieving <a href=\"#d184cc9a-674a-44ad-ab40-1858ec734225\">service provider availability</a> is a typical use case for this. The Managed Package <a href=\"#6ce24bf6-2933-4d2c-ab32-4a93974f5ee7\">wraps around these API use cases</a> to return the relevant data. The Dispatch credentials for doing so are stored and encrypted in the Salesforce instance.</p>\n</li>\n<li><p>Outbound (Dispatch to Salesforce) - Dispatch Connect interacts directly with the Salesforce instance to <a href=\"#9a68b6ec-58ab-4dc4-a549-8fadf8fa6c40\">send updates back to Salesforce</a> using a designated Salesforce user. Credentials for doing so are stored in Dispatch.</p>\n</li>\n</ul>\n","_postman_id":"95f99be0-442d-4aca-8ca3-0f6b9356bcf2"},{"name":"Legacy Salesforce Integration Product","item":[],"id":"780e3172-98a2-411b-ad9f-895841d9d392","description":"<p>This interacts directly with the lower level Dispatch APIs. The documentation for this can be viewed <a href=\"https://github.com/Nahis/connector-salesforce-mapping-fsl\">here</a>.</p>\n<p><em>Note: in new Salesforce integrations, it is unlikely that we'll be using any features of the legacy integration product</em>.</p>\n","_postman_id":"780e3172-98a2-411b-ad9f-895841d9d392"}],"id":"7b1074d5-7132-4473-9282-7ef0f568162a","description":"<p>This is part of the Dispatch integration product that interacts with the Dispatch APIs. The Managed Package contains features to support:</p>\n<ul>\n<li><p><a href=\"#95f99be0-442d-4aca-8ca3-0f6b9356bcf2\">Dispatch Connect Aligned Integration Product</a></p>\n</li>\n<li><p><a href=\"#780e3172-98a2-411b-ad9f-895841d9d392\">Legacy Salesforce Integration Product</a></p>\n</li>\n</ul>\n<p>New features added to the Dispatch Managed Package can be upgraded using the standard Salesforce Managed Package upgrade process.</p>\n","_postman_id":"7b1074d5-7132-4473-9282-7ef0f568162a"},{"name":"Dispatch Change Set","item":[],"id":"5bcc468b-7b59-4ead-b5a9-8dec1a9392b5","description":"<p>This contains the triggers, classes and custom fields that we add to your environment. This allows us to get <em>your specific</em> Salesforce setup (objects, fields) and send over to Dispatch. In our latest iteration of our connector (and our recommended approach) the triggers and classes of this change set functions solely as a <em>publisher</em> of change in your Salesforce environment. We'll review this in detail in the <a href=\"#5f88500b-87a3-4ffc-88ed-37f430ba4634\">example</a>.</p>\n","_postman_id":"5bcc468b-7b59-4ead-b5a9-8dec1a9392b5"}],"id":"aa8f2c3e-2675-4d70-b660-130a56cb4422","description":"<p>A Dispatch deployment with the Salesforce Connector typically consists of the following Salesforce technology features:</p>\n<ul>\n<li><p><a href=\"#7b1074d5-7132-4473-9282-7ef0f568162a\">Dispatch Managed Package</a></p>\n</li>\n<li><p><a href=\"#5bcc468b-7b59-4ead-b5a9-8dec1a9392b5\">Dispatch Change Set</a></p>\n</li>\n</ul>\n","_postman_id":"aa8f2c3e-2675-4d70-b660-130a56cb4422"},{"name":"Governor Limits","item":[],"id":"6fbaf866-a480-4cad-a1c1-8d05f5205823","description":"<p>No we're not talking about excesses of power! As pretty much everyone knows Salesforce enforces limits on API usage and such like. So this section is to provide some insight on how we'll impact that with the Salesforce Connector.</p>\n<p>The short answer should be very little and we can make it smaller still! Allow us to explain...</p>\n<h3 id=\"from-salesforce-to-dispatch\"><strong>From Salesforce to Dispatch</strong></h3>\n<p>Take a look at the <a href=\"#5f88500b-87a3-4ffc-88ed-37f430ba4634\">example</a> that will illustrate this (and shows our recommended approach). The following is required to send data from Salesforce to Dispatch:</p>\n<ul>\n<li>Publisher - typically we use a trigger for this</li>\n<li>Change - we recommend putting in a conditional statement to ensure the fields the integration \"cares about\" have changed. That avoids unnecessary chattiness</li>\n<li>Query - get relevant objects and fields using SOQL</li>\n<li>Send to Dispatch - this involves a single API call to Dispatch Connect no matter how many records may have changed. Always a single API call.</li>\n</ul>\n<p>So typically, if we consider transactional data like Work Orders, you'd have the above occur for every <strong>relevant</strong> save that is made. So multiply that by the number of saves you typically make a day and you arrive at the usage to expect.</p>\n<p>Other typical updates include:</p>\n<ul>\n<li>Linked records - for example, Work Order Line Items (WOLIs) often need to be sent over. We'd similarly need to have a trigger that sends over an update any a <strong>relevant</strong> change is made to those records. Again you can do the math based on how many of these events you're likely to have in terms of governor limits.</li>\n<li>Setup data - by this we mean service providers, employees and related data. Related data in these cases might be skills that may be relevant and linked in a 1:M fashion and such like. Generally speaking \"setup data\" is much lower from a transactional point of view.</li>\n</ul>\n<p>Given the above, we typically have negligible impact on governor limits. And believe us when we tell you that we have very highly dynamic Salesforce implementations (think \"dispatch board\" operation in Salesforce) - so it's not like we haven't been tested in this regard (and these projects are mostly on our older version of the Salesforce Connector which involve multiple API calls for every update as opposed to just the one with our latest product). We can say with confidence that governor limits have never been a concern of any kind in all our Salesforce projects to date (and we'll remove this sentence if and when that happens!)!</p>\n<p>That said, there is an efficient way to dramatically decrease the amount of API hits if that is still a concern - by orders of magnitude. And that is to use Salesforce scheduled jobs which would work as follows:</p>\n<ul>\n<li>Trigger for the publisher per above</li>\n<li>Change for the relevant updates per above</li>\n<li>Flag for update - flag the Salesforce record for update (on the record or in another Salesforce object). Name it \"Dispatch Pending\" or similar.</li>\n<li>The schedule job will then pick up all flagged records in a single query and then:<ul>\n<li>Post to the connector using a single API</li>\n<li>Unset the flag for update</li>\n</ul>\n</li>\n</ul>\n<p>The above approach will aggregate your changes and obviously reduce the number of times it needs to post to Dispatch.</p>\n<p>We'd generally recommend to have this on a frequent schedule of every minute or so, but that can be adjusted based on business need.</p>\n<p>We have followed this approach on various projects but the reasons have never been due to countering governor limits concerns although it definitely can be used for that.</p>\n<h3 id=\"from-dispatch-to-salesforce\">From Dispatch to Salesforce</h3>\n<p>As mentioned earlier, the updates from Dispatch to Salesforce happen entirely on the Dispatch Connect side. There is typically no Salesforce component for this. While this is our recommended approach we have employed other approaches historically which include webhooks and the Salesforce event bus.</p>\n<p>Using our recommended approach, updates from Dispatch are sent in real time back to Salesforce. We use a Salesforce user to make those updates via the Salesforce API. So for example, when a status, schedule, note, attachment, custom form is modified on the Dispatch side and that change is relevant to be sent to Salesforce, we'll call the API for each update made.</p>\n<p>So following this approach updates would be pretty frequent because updates of these nature are frequent. But to our knowledge (informed by Salesforce consulting firms we've worked with in the past), external Salesforce API calls do not affect governor limits (though we could be wrong... and things sometime change with Salesforce!).</p>\n<p>So what are strategies to decrease the frequency of API calls from Dispatch if that still a concern?</p>\n<ul>\n<li>On the Dispatch side, we could queue them and instead of making an API call per update, we could do it periodically via a scheduled job (every minute would be recommended if we followed this approach).</li>\n<li>We could send those updates \"elsewhere\" (you tell us) and then you could process them into Salesforce</li>\n</ul>\n<p>Generally we don't recommend queueing updates from Dispatch as we like to do these real time as real time tends to be important for such updates. So unless it is a necessity we'd advise against it. And if it is a necessity we'd encourage the schedule to be not more than every minute.</p>\n","_postman_id":"6fbaf866-a480-4cad-a1c1-8d05f5205823"},{"name":"From Salesforce to Dispatch","item":[{"name":"Example 1","item":[{"name":"Trigger","item":[],"id":"533087f3-b32b-442e-af6c-00e57ceef1c7","description":"<p>Add a new trigger or update an existing trigger if you prefer with the snippet below. This should include the following:</p>\n<ul>\n<li><p>Only include the relevant events. So in our example, we know that Work Orders are never sent to Dispatch upon creation - that happens down the line. So we just include an <code>on update</code> event. If that's different in your case, then include an <code>after insert</code> event. It's not common but it's possible you may also need to include an <code>on delete</code> event (in the event you want it to cancel or similar on the Dispatch side)</p>\n</li>\n<li><p>Limit it to <code>isafter</code></p>\n</li>\n<li><p>Call the trigger handler</p>\n</li>\n</ul>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-c\">trigger WorkOrderTrigger on WorkOrder (after update) {\n    // ----------------------\n    // Dispatch\n    // ----------------------\n    if (Trigger.isafter) {\n        DispatchTriggerHandler.JobToDispatch(Trigger.new, Trigger.oldMap);\n    }\n    // ----------------------\n}\n\n</code></pre>\n","_postman_id":"533087f3-b32b-442e-af6c-00e57ceef1c7"},{"name":"Change, Query and Send to Dispatch","item":[],"id":"fb35371e-7654-416a-b894-95d7bd30e796","description":"<p>We'll do these together because they pretty much happen that way. Include the snippet below in your <code>DispatchTriggerHandler</code> class.</p>\n<p>We generally recommend creating the following datetime fields (which Dispatch typically does as part of the integration work):</p>\n<ul>\n<li><p><code>Dispatch_Send</code> - used to indicate you want to send data <em><strong>to</strong></em> Dispatch</p>\n</li>\n<li><p><code>Dispatch_Last_Synced</code> - used to indicate that the sync <strong>to</strong> Dispatch was successful</p>\n</li>\n<li><p><code>Last_Updated_from_Dispatch</code> - used to indicate the last time an update was received <em><strong>from</strong></em> Dispatch</p>\n</li>\n</ul>\n<p>Note the following:</p>\n<ul>\n<li><p>Change - this consist of the following</p>\n<ul>\n<li><p>the <code>if (rec.Dispatch_Send__c != null)</code> condition</p>\n<ul>\n<li><p>Create a workflow that updates this <code>Dispatch_Send</code> field on the Work Order at the point that a Work Order should be sent. So whatever your business logic is to indicate that should happen – you just set up your workflow to set the <code>Dispatch_Send</code> field when you're ready to send. And if that business logic changes, just adjust the workflow to reflect that change. This separates the “sync to Dispatch” from the business logic required to sync it and creates a nice separation from a business logic/integration point of view.</p>\n</li>\n<li><p>Once this field is populated, it syncs and all future relevant updates are also synced to Dispatch. That is, if this field is populated but remains unchanged and another relevant Dispatch field based on your mapping document is updated – that will still sync as an update to Dispatch (and you can see this in the code as the condition is just checking that it's not null not that it has been updated).</p>\n</li>\n</ul>\n</li>\n<li><p><code>relevantFields</code> containing a list of fields relevant to the integration and passing that into the <code>dispconn.DispatchMappingHelper.getChangedFields</code> helper and storing the result in <code>changedFieldsMap</code></p>\n</li>\n<li><p><code>updatedFromSalesforce</code> variable that checks if the update was made on the Salesforce side or via integration</p>\n</li>\n<li><p>check if <code>changedFieldsMap</code> and <code>updatedFromSalesforce</code>are true as a necessary condition for executing the query</p>\n</li>\n</ul>\n</li>\n<li><p>Query - including a query to return all relevant fields and store in a list. In the example below, we've but that in <code>recs</code>. A query is only required if you need to query data from related records otherwise you can just send us the trigger data. We recommend including the following fields in the query for logging purposes: <code>Dispatch_Last_Synced__c, LastModifiedBy.Name, LastModifiedDate</code></p>\n</li>\n<li><p>Send to Dispatch - exactly as shown! This uses a global function from the Salesforce Connector managed package.</p>\n</li>\n</ul>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>public class DispatchTriggerHandler {\n    private static boolean firstRun = true;\n    public static void JobToDispatch(List newList, Map oldMap){\n        if (!firstRun) { return; }\n        Set&lt;Id&gt; recIds = new Set&lt;Id&gt;();\n        Map&lt;Id, Map&lt;String, Object&gt;&gt; changedFieldsMap = new Map&lt;Id, Map&lt;String, Object&gt;&gt;();\n        Set&lt;String&gt; relevantFields = new Set&lt;String&gt;{\n            'Dispatch_Send__c', 'Subject', 'Description', 'Category__c', 'Sub_Category__c'\n        };        \n        for(Case rec : newList) {\n            if (rec.Dispatch_Send__c != null) {\n                Case oldRec = oldMap.get(rec.Id);\n                changedFieldsMap = dispconn.DispatchMappingHelper.getChangedFields(oldRec, rec, relevantFields);\n                Boolean updatedFromSalesforce =(oldRec.Last_Updated_from_Dispatch__c == rec.Last_Updated_from_Dispatch__c &amp;&amp; \n                                                oldRec.Dispatch_Last_Synced__c == rec.Dispatch_Last_Synced__c);\n               if (changedFieldsMap.size() &gt; 0 &amp;&amp; updatedFromSalesforce) {\n                    recIds.add(rec.Id);\n                }\n            }\n        }\n        if (recIds.size() &gt; 0) {\n            List recs = [SELECT Id, Name, Dispatch_Last_Synced__c, LastModifiedBy.Name, LastModifiedDate, \n                                      CaseNumber, Subject, Description, Category__c, Sub_Category__c, ContactEmail,  ContactPhone, ContactId, Account.ShippingStreet, \n                                      Account.ShippingCity, Account.ShippingState, Account.ShippingPostalCode, Account.Name, Contact.FirstName, Contact.LastName,\n                                      Property__r.Name, Property__r.City__c, Property__r.State__c, Property__r.Zip__c\n                                      //(SELECT Id, Description FROM CaseLineItems ORDER BY LineItemNumber)\n                                FROM Case \n                               WHERE Id IN :recIds];        \n        }\n        dispconn.DispatchMappingHelper.sendToDispatch(recs, changedFieldsMap, false);\n    }\n}\n\n</code></pre>","_postman_id":"fb35371e-7654-416a-b894-95d7bd30e796"}],"id":"5f88500b-87a3-4ffc-88ed-37f430ba4634","description":"<p>This example only shows the method of getting data out of Salesforce. Because as mentioned in the sections above, writing data from Dispatch to Salesforce occurs entirely on the Dispatch Connect mapping side and therefore there's typically no Salesforce component required for it.</p>\n<p>As mentioned there are 4 components required for sending data from Salesforce to Dispatch. And they're all really simple!</p>\n<ul>\n<li><p>Trigger for publish</p>\n</li>\n<li><p>Change for relevant data to remove unnecessary chattiness</p>\n</li>\n<li><p>Query using SOQL for relevant objects and fields</p>\n</li>\n<li><p>Post to Dispatch</p>\n</li>\n</ul>\n<p>So let's go through them.</p>\n","_postman_id":"5f88500b-87a3-4ffc-88ed-37f430ba4634"},{"name":"Example 2","item":[],"id":"ea7d0c81-4814-4ef7-8f59-3d32c10a56fb","description":"<p>We don't really need to as the above illustrates how it's done and it's rinse and repeat for every other object you wish to send to Dispatch. But just for good measure we'll provide you with a snippet from the <code>DispatchTriggerHandler</code> class for sending over Account records (typically Service Providers) to Dispatch.</p>\n<p>This follows the same paradigm as the one above. The differences include:</p>\n<ul>\n<li><p>We recommend including a <code>Dispatch_Me</code> checkbox (which Dispatch typically does as part of the integration work) to flag which of your Service Providers you wish to send over to Dispatch. And the code filters using that.</p>\n</li>\n<li><p>No need to crate a <code>Dispatch_Send</code> field as the <code>Dispatch_Me</code> checkbox is sufficient</p>\n</li>\n<li><p>No need to create a <code>Last_Updated_from_Dispatch__c</code> field as this integration is only 1 way to Dispatch (other than the sync confirmation which will be reflected in the <code>Dispatch_Last_Synced__c</code> field)</p>\n</li>\n</ul>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>    public static void AccountToDispatch(List newList, Map oldMap){\n        if (!firstRun) { return; }\n        firstRun = false;\n        Set&lt;Id&gt; recIds = new Set&lt;Id&gt;();\n        Map&lt;Id, Map&lt;String, Object&gt;&gt; changedFieldsMap = new Map&lt;Id, Map&lt;String, Object&gt;&gt;();\n        Set&lt;String&gt; relevantFields = new Set&lt;String&gt;{\n            'Dispatch_Me__c', 'Name', 'AccountNumber', 'Phone', 'Email__c',\n            'ShippingStreet', 'ShippingCity', 'ShippingState', 'ShippingPostalcode', 'ShippingCountry'\n        };        \n\n        for(Account rec: newList) {\n            if (rec.Dispatch_Me__c) {\n                Account oldRec = oldMap.get(rec.Id);\n                changedFieldsMap = dispconn.DispatchMappingHelper.getChangedFields(oldRec, rec, relevantFields);\n                Boolean updatedFromSalesforce =(oldRec.Dispatch_Last_Synced__c == rec.Dispatch_Last_Synced__c);\n                if (changedFieldsMap.size() &gt; 0 &amp;&amp; updatedFromSalesforce) {\n                    recIds.add(rec.Id);\n                }\n            }\n        }\n        if (recIds.size() &gt; 0) {\n            List recs = [SELECT Id, Name, Dispatch_Last_Synced__c, LastModifiedBy.Name, LastModifiedDate, \n                                        AccountNumber, Phone, Email__c,\n                                        ShippingStreet, ShippingCity, ShippingState, ShippingPostalcode, ShippingCountry\n                                        FROM Account \n                                        WHERE Id IN :recIds\n                                        AND Dispatch_Me__c = true];\n        }\n        dispconn.DispatchMappingHelper.sendToDispatch(recs, changedFieldsMap, false);\n    }\n</code></pre>","_postman_id":"ea7d0c81-4814-4ef7-8f59-3d32c10a56fb"}],"id":"70e7df32-7dd4-44ad-b904-c3e9327eb151","_postman_id":"70e7df32-7dd4-44ad-b904-c3e9327eb151","description":""},{"name":"From Dispatch to Salesforce","item":[],"id":"9a68b6ec-58ab-4dc4-a549-8fadf8fa6c40","description":"<p>As mentioned in the sections above, writing data from Dispatch to Salesforce occurs entirely on the Dispatch Connect mapping side and therefore there's typically no Salesforce component required for it.</p>\n<p>That said, we wanted to provide you with guidance on what to expect in terms of updates sent to Salesforce. Dispatch will typically create any missing fields as part of the integration effort (except for form data, notes and attachments as those typically have business logic best taken care of by the business).</p>\n<ul>\n<li><p>Status/Status reason – typically <code>Dispatch_Status</code>, <code>Dispatch_Status_Reason</code> as strings</p>\n</li>\n<li><p>Last sync - best practice to let you know the time the update was successfully made to Dispatch (typically <code>Dispatch_Last_Synced</code>)</p>\n</li>\n<li><p>Error - best practice to let you know of the error in the event the sync failed to Dispatch (typically <code>Dispatch_Error (255)</code>will be cleared out the next time an update occurs from Salesforce.</p>\n</li>\n<li><p>Milestone timestamps - date/time accepted, scheduled, enroute, started, paused, completed, canceled</p>\n</li>\n<li><p>Start/end appointment window – corresponding date/time fields</p>\n</li>\n</ul>\n<p>Errors (inbound and outbound) will automatically be written to the <code>dispconn__Dispatch_Log__c</code> object. You can add this object to the Salesforce UI or you can query it in SOQL e.g.:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>SELECT Id,Name, dispconn__Error__c, dispconn__Record_Id__c, dispconn__Entity_Name__c, dispconn__Direction__c, CreatedDate, LastModifiedDate \nfrom dispconn__Dispatch_Log__c \nwhere dispconn__Record_Id__c = '0017f00000rjhHlAAI'\norder by LastModifiedDate desc\n\n</code></pre><p>We also recommend sending these errors to the Salesforce notification system <a href=\"https://share.zight.com/5zuk7bGD\">so users can be proactively notified of these errors so they can take the corrective action</a>. To do so, go to <code>Customer Settings &gt; Dispatch Global Settings</code> and a setting titled <code>Alert Notification Id</code> to it. The value should be set to the result of this query:</p>\n<p><code>SELECT Id FROM CustomNotificationType WHERE DeveloperName = 'Dispatch_Connect'</code></p>\n","_postman_id":"9a68b6ec-58ab-4dc4-a549-8fadf8fa6c40"},{"name":"Connector Global Functions","item":[{"name":"Match Orgs","item":[],"id":"061259ea-e482-41db-8ad3-60de14357a96","description":"<p>This API wraps around the <a href=\"#7e79741c-3c7f-48fe-bb3c-60d8989fe377\">Match Orgs</a> core API and the response will be as documented there.</p>\n<p>The following is sample Apex code that you can use to invoke the API and interpret the response:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-java\">Map&lt;String, Object&gt; res = dispconn.DispatchMappingHelper.matchOrgs(new Map&lt;String,String&gt;{'postal_code' =&gt; '75024', 'trades' =&gt; String.join(new List&lt;String&gt;{'trade 1', 'trade 2'}, '|')});\nSystem.debug(JSON.serialize(res));\nfor (Object matchObj : (List&lt;Object&gt;)res.get('account_organizations')) {\n    Map&lt;String, Object&gt; match = (Map&lt;String, Object&gt;)matchObj;\n    System.debug(JSON.serialize(match));\n    for (Object externalId : (List&lt;Object&gt;)match.get('external_ids')) {\n        System.debug('Org external ID (ID in your system - use to update Salesforce):' + (String)externalId);\n        break;\n    }\n}\n\n</code></pre>\n","_postman_id":"061259ea-e482-41db-8ad3-60de14357a96"},{"name":"Match Technicians","item":[],"id":"fac6a7ae-4bca-459a-b4f8-fa6615f98937","description":"<p>This API wraps around the <a href=\"#165792c2-df72-44b6-b863-a3a258eecbee\">Match Techs</a> core API and the response will be as documented there.</p>\n<p>The following is sample Apex code that you can use to invoke the API and interpret the response:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-java\">Map&lt;String, Object&gt; res = dispconn.DispatchMappingHelper.matchTechnicians(new Map&lt;String,String&gt;{'postal_code' =&gt; '02446', 'appointment_duration_minutes' =&gt; '30', 'availability_start_time' =&gt; String.valueOf(dateInUtc), 'availability_end_time' =&gt; String.valueOf(dateInUtc),'trades' =&gt; String.join(new List&lt;String&gt;{'trade 1', 'trade 2'}, '|')});\nSystem.debug(JSON.serialize(res));\nfor (Object matchObj : (List&lt;Object&gt;)res.get('matches')) {\n    Map&lt;String, Object&gt; match = (Map&lt;String, Object&gt;)matchObj;\n    Map&lt;String, Object&gt; user = (Map&lt;String, Object&gt;)match.get('entity');\n    System.debug(JSON.serialize(user));\n    for (Object externalId : (List&lt;Object&gt;)user.get('external_ids')) {\n        System.debug('User external ID (ID in your system - use to update Salesforce):' + (String)externalId);\n        break;\n    }\n    for (Object slotObj : (List&lt;Object&gt;)match.get('slots')) {\n        Map&lt;String, Object&gt; slot = (Map&lt;String, Object&gt;)slotObj;\n        System.debug(JSON.serialize(slot));  // returns list of available times for tech\n    }\n}\n</code></pre>\n","_postman_id":"fac6a7ae-4bca-459a-b4f8-fa6615f98937"},{"name":"Get File","item":[],"id":"cdbceb97-b1d6-41bc-9d82-9cb48857c562","description":"<p>Given a file attachment <code>uuid</code> that you <a href=\"https://playbooks.dispatch.me/#f3f11bce-b781-4713-a09d-e8b8628fa9f7\">obtained from Dispatch</a> you can use this method to retrieve the underlying file name and base64 string.</p>\n<p>Please note that you'll need to add the following URLs to the Salesforce Remote Site Settings:</p>\n<ul>\n<li>Sandbox - <a href=\"https://files-sandbox.dispatch.me\">https://files-sandbox.dispatch.me</a></li>\n<li>Production - <a href=\"https://files.dispatch.me\">https://files.dispatch.me</a></li>\n</ul>\n<p>Sample Usage:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-java\">Map payload = dispconn.DispatchMappingHelper.getFileUrl('7644eac6-575d-4f2b-b5e0-138c7819edae', true);\nsystem.debug('name: '+(String)payload.get('name'));\nsystem.debug('url: '+(String)payload.get('url'));\nsystem.debug('base64: '+(Blob)payload.get('base64'));\n\n</code></pre>\n","_postman_id":"cdbceb97-b1d6-41bc-9d82-9cb48857c562"},{"name":"Get Billing Document PDF","item":[],"id":"e9915918-b3a9-4341-bb06-ab95095ae08e","description":"<p>Given a Dispatch job can use this method to retrieve the all the PDF billing documents linked to it returned as base64 strings.</p>\n<p>Sample Usage:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-java\">Map pdfbase64StringMap = dispconn.DispatchMappingHelper.getBillingDocumentPdfs((String) dispatchJobId, new Map());\nfor (String billingDocId : pdfbase64StringMap.keySet()) {\n    Object pdfbase64String = pdfbase64StringMap.get(billingDocId);\n    Blob b = EncodingUtil.base64Decode(String.valueOf(pdfbase64String));\n}\n\n</code></pre>\n","_postman_id":"e9915918-b3a9-4341-bb06-ab95095ae08e"}],"id":"6ce24bf6-2933-4d2c-ab32-4a93974f5ee7","description":"<p>The Salesforce managed package includes some global methods. These methods wrap around common use case Dispatch APIs such that you are able to make these API calls from Apex with a minimum of effort. They utilize the stored credentials of the managed package.</p>\n","_postman_id":"6ce24bf6-2933-4d2c-ab32-4a93974f5ee7"}],"id":"4468a0c3-45ab-49f8-9db4-ff81d71eb135","_postman_id":"4468a0c3-45ab-49f8-9db4-ff81d71eb135","description":""}],"id":"64745225-fe26-4221-8e33-55f554c3b9c9","_postman_id":"64745225-fe26-4221-8e33-55f554c3b9c9","description":""},{"name":"Quick Starts","item":[{"name":"DNM (Decentralized Network Management)","item":[{"name":"Direct Assign to Provider","item":[{"name":"To Dispatch","item":[{"name":"Jobs","id":"2b5006d1-2f8d-4cea-803a-4e20236e7cde","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"organization\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"organization\": {\n                \"name\": \"Your Service Provider\",\n                \"email\": \"your_service_provider@dispatch.me\",\n                \"external_id\": \"your_enterprise_service_provider_id\",\n                \"phone_number\": \"(555)013-0352\",\n                \"always_create\": true,\n                \"address\": {\n                    \"street_1\": \"3313 Maple Avenue\",\n                    \"postal_code\": \"90731\",\n                    \"city\": \"San Pedro\",\n                    \"state\": \"CA\"\n                }\n            }\n        }\n    },\n    {\n        \"header\": {\n            \"record_type\": \"customer\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"first_name\": \"Jane\",\n            \"last_name\": \"Doe\",\n            \"external_id\": \"your_enterprise_service_provider_id-your_enterprise_customer_id\",\n            \"external_organization_id\": \"your_enterprise_service_provider_id\",\n            \"email\": \"email@dispatch.me\",\n            \"phone_numbers\": [\n                {\n                    \"number\": \"+15550913813\",\n                    \"primary\": true,\n                    \"type\": \"Mobile\"\n                }\n            ],\n            \"home_address\": {\n                \"street_1\": \"3913 Ford Street\",\n                \"city\": \"Revere\",\n                \"state\": \"MA\",\n                \"postal_code\": \"02151\"\n            }\n        }\n    },\n    {\n        \"header\": {\n            \"record_type\": \"job\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"title\": \"Job title\",\n            \"status\": \"offered\",\n            \"description\": \"Some description.\\n\\n# Accepts *markdown*\",\n            \"external_id\": \"your_enterprise_job_id\",\n            \"friendly_external_id\": \"your_friendly_enterprise_job_id\",\n            \"external_customer_id\": \"your_enterprise_customer_id\",\n            \"external_organization_id\": \"your_enterprise_service_provider_id\",\n            \"expected_duration\": 3600,\n            \"symptom\": \"Some symptom\",\n            \"service_fee\": 500,\n            \"service_fee_precollected\": false,\n            \"service_instructions\": \"instruction to tech\",\n            \"contacts\": [\n                {\n                    \"first_name\": \"Jane\",\n                    \"last_name\": \"Doe\",\n                    \"primary\": true,\n                    \"contact_methods\": [\n                        {\n                            \"value\": \"+15550913813\",\n                            \"method\": \"phone\",\n                            \"notify\": true\n                        },\n                        {\n                            \"value\": \"test@abc.com\",\n                            \"method\": \"email\",\n                            \"notify\": true\n                        }\n                    ]\n                }\n            ],\n            \"address\": {\n                \"street_1\": \"1213 Summer St\",\n                \"street_2\": \"apt. 1\",\n                \"postal_code\": \"01234\",\n                \"city\": \"Boston\",\n                \"state\": \"MA\"\n            },\n            \"service_type\": \"plumber\",\n            \"_labels\": [\n                100,\n                101\n            ],\n            \"ui_options\": {\n                \"show_decline\": true,\n                \"accept_title\": \"Accept\",\n                \"decline_title\": \"Decline\",\n                \"reject_reasons\": [\n                    \"wrong_area|I don't service this address|true|false\",\n                    \"wrong_trade|I don't do this type of work|false|true\",\n                    \"no_availability|I can't do this job in time|false|false\",\n                    \"other|Other|true|true\"\n                ]\n            },\n            \"equipment_descriptions\": [\n                {\n                    \"manufacturer\": \"Acme\",\n                    \"model_number\": \"500\",\n                    \"serial_number\": \"01024\",\n                    \"installation_date\": \"2017-10-21T00:00:00Z\",\n                    \"equipment_type\": \"hvac\"\n                }\n            ],\n            \"marketing_attributions\": [\n                {\n                    \"content\": \"bingo\",\n                    \"campaign\": \"mamba\",\n                    \"source\": \"orca\",\n                    \"term\": \"glitter\",\n                    \"media\": \"twitter\"\n                }\n            ],\n            \"suggested_times\": [\n                {\n                    \"start_time\": \"2018-06-05T17:00:00+0000\",\n                    \"end_time\": \"2018-06-05T19:00:00+0000\"\n                },\n                {\n                    \"start_time\": \"2018-06-06T17:00:00+0000\",\n                    \"end_time\": \"2018-06-06T19:00:00+0000\"\n                },\n                {\n                    \"start_time\": \"2018-06-07T17:00:00+0000\",\n                    \"end_time\": \"2018-06-07T17:00:00+0000\"\n                }\n            ],\n            \"custom_fields\": {\n                \"do_not_survey\": \"yes\",\n                \"arrival_type\": \"range\"\n            }\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<h2 id=\"overview\">Overview</h2>\n<p>We call it a Job. You might call it a Work Order, Service Order or something else. Potato, potāto. Anyway, you will be sending these over to us.</p>\n<p>A job has the following main elements:</p>\n<ul>\n<li>Job Details</li>\n<li>Customer Details</li>\n<li>Service Provider/Contractor Details</li>\n</ul>\n<p>Though we are quite forgiving, a job cannot really be a job without some basic information, so please take care to include the following details:</p>\n<ul>\n<li>Customer name (preferably first and last but we'll settle with whatever you can send us)</li>\n<li>Valid address (we need to know where to go!)</li>\n<li>Organization email and/or phone # (and/or organization <code>id</code> if you've pre-created those)</li>\n</ul>\n<p>We will not create duplicate records. Meaning if you send over the same organization or customer record more than once, the system is smart enough to detect they exist.</p>\n<p>We'd also recommend you include a valid customer email and mobile number as that will enhance the experience. Do try to avoid invalid entries such as <code>jim@@abc.com</code> and <code>555123</code> as if you don't manage that we'll be forced to strip them before processing.</p>\n<p>Oh and lastly, we'd really encourage sending over your unique IDs into the <code>external_id</code> fields for the job and organization. This field is used for matching in order to process updates as described above.</p>\n<p>Send this payload and voila - a job will be created in Dispatch!</p>\n<h2 id=\"special-fields\">Special Fields</h2>\n<p>If you are providing a custom payload then you can skip this next section. Most of the fields in the payload should be self explanatory. But we do want to bring the following to your attention:</p>\n<h6 id=\"job-record\">job record:</h6>\n<ul>\n<li><code>friendly_external_id</code> - this is an optional field. Very often systems have the technical \"ugly ID\" that only the techies in your organization know exists. And there is also a \"friendly ID\" that end users and customers use as references. If this is the case, then please put the \"ugly ID\" into the <code>external_id</code> and the \"friendly ID\" into <code>friendly_external_id</code></li>\n<li><code>status</code> - the default mapping expects the following values:<ul>\n<li>offered - offers the job to the service provider</li>\n<li>unscheduled - if you wish to accept on behalf of the service provider</li>\n<li>rejected - if you wish to reject on behalf of the service provider</li>\n<li>complete</li>\n<li>canceled</li>\n</ul>\n</li>\n<li><code>description</code> - this can accept <a href=\"https://dillinger.io/\">markdown</a> formatting</li>\n<li><code>contacts</code> - you can include this section to specify 1 or more contacts for the job. This can differ or be the same as to what you pass on the customer record.</li>\n<li><code>expected_duration</code> - If relevant specify the expected duration of the job in seconds.</li>\n<li><code>suggested_times</code> - This is an optional section. If you include it will offer the service provider these as \"suggested times\" that the customer has indicated are preferable.</li>\n<li><code>ui_options</code> - This is an optional section. It allows you to specify reject reasons for a job offered to a service provider. You can use what's presented in this example or provider your own list. The format of the reject reasons uses the following format: <code>value|friendly_label|show_text|require_text</code> where:<ul>\n<li><code>value</code> - technical field value e.g. \"wrong_area\"</li>\n<li><code>friendly_label</code> - e.g. \"Wrong Area\"</li>\n<li><code>show_text</code> - true/false. If true, an additional free text field will display</li>\n<li><code>require_text</code> - true/false. Make free text required entry.</li>\n</ul>\n</li>\n<li><code>custom_fields</code> - you can specify any number of custom fields here. These will not show up on the front end by default, so please coordinate with Dispatch what your objective is, if using these.</li>\n<li><code>brand_id</code> - if you want to customize the look and feel of notifications depending on the brand the job is created for, please reach out to Dispatch with the brands you wish to set up.</li>\n<li><code>labels</code> - if you want to apply labels to jobs, please reach out to Dispatch with the values you wish to use before using this option (remove the leading \"_\" if you want to use this field).</li>\n</ul>\n<h6 id=\"customer-record\">customer record</h6>\n<ul>\n<li>Dispatch requires that the <code>external_id</code> passed here is unique per organization. This is probably not the case in your system, therefore you should prefix with the external ID of the organization as shown in the payload example</li>\n</ul>\n<h6 id=\"organization-record-ie-service-provider-or-contractor\">organization record (i.e. service provider or contractor):</h6>\n<ul>\n<li>Only a single service provider record is currently supported</li>\n<li>This record should only be passed in if you're creating these records on the fly. Otherwise, if service providers are created in advance this record should not be passed and instead just pass <code>organization_id</code> or <code>external_organization_id</code> into the job record</li>\n<li>Please note that if you pass in a job to Dispatch with an <code>external_organization_id</code> of \"contractor_1\" and later you update that to \"contractor_2\", the Dispatch Platform will automatically cancel the job for the first contractor and create another for the second.</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"2b5006d1-2f8d-4cea-803a-4e20236e7cde"},{"name":"Organizations","id":"49cb6560-bb65-45f0-b90e-fa02251d342a","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n\t{\r\n\t  \"header\": {\r\n\t    \"record_type\": \"organization\",\r\n\t    \"version\": \"v3\"\r\n\t  },\r\n\t  \"record\": {\r\n\t\t  \"name\" : \"Your Service Provider\",\r\n\t\t  \"email\" : \"your_service_provider@dispatch.me\",\r\n\t\t  \"external_id\": \"your_enterprise_id\",\r\n\t\t  \"phone_number\" : \"(555)010-0352\",\r\n\t\t  \"address\": {\r\n\t\t        \"street_1\": \"3310 Maple Avenue\",\r\n\t\t        \"postal_code\": \"90731\",\r\n\t\t        \"city\": \"San Pedro\",\r\n\t\t        \"state\": \"CA\"\r\n\t\t }\r\n\t  }\r\n\t}\r\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<h2 id=\"overview\">Overview</h2>\n<p>We call it an Organization. You might call it a Service Provider, Contractor, 3rd Party, Installer or something else. Tomato, tomāto.</p>\n<p>Now the things is, you don't actually have to send these over to us separately. If you send these with the aforementioned job then we'll create them on the fly. However, sometimes it is preferred for these to be created separately in advance and if that's the case for you then you've come to the right place.</p>\n<p>At a minimum, please ensure you provide us with the following bits of information (although the more the merrier of course):</p>\n<ul>\n<li>Name</li>\n<li>Valid Phone Number</li>\n</ul>\n<p>It's also really good practice to include your unique organization ID in the <code>external_id</code> attribute as then you can reference that when sending jobs over.</p>\n<p>Oh and definitely the address. We use that to determine the time zone and if it's omitted we're forced to default to EST. So you may want to pass this so the guys in CA can sleep in a little bit.</p>\n<p>Send this payload and Bob's your contractor!</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"49cb6560-bb65-45f0-b90e-fa02251d342a"}],"id":"c5e28ae2-134f-4fa3-98dd-955bea2a89f0","event":[{"listen":"prerequest","script":{"id":"5007f813-77a2-4493-9dd4-70c24ae848bd","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"dc507a1a-af78-4f9d-894f-cdd583bbda3a","type":"text/javascript","exec":[""]}}],"_postman_id":"c5e28ae2-134f-4fa3-98dd-955bea2a89f0","description":""},{"name":"From Dispatch","item":[{"name":"Job Related Events","id":"ade1b10c-6eb7-445c-8bf2-affaaa45e78d","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Job</em> events. These events are wrapped in a <code>job</code> key ().</p>\n<p>These are the cases that should be monitored:</p>\n<ul>\n<li>Accepted</li>\n<li>Rejected (with configurable reasons)</li>\n<li>Completed (with configurable reasons e.g. Ready for Billing)</li>\n<li>Paused (with configurable reasons e.g No Show, Waiting for Parts, Cannot Contact Customer)</li>\n<li>Canceled (with configurable reasons)</li>\n<li>Created (only if you are not sending jobs directly to Dispatch)</li>\n</ul>\n<p>Job events have the following basic payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"job\": {\n                        \"id\": 30462,\n                        \"status\": \"some_status\",\n                        \"status_message\": \"some message\",\n                        \"updated_at\": \"2018-05-18T10:05:46+0000\",\n                        \"external_id\": \"your_system_id\"\n                        ]\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"job-accepted\">Job Accepted</h2>\n<ul>\n<li>Status: <code>unscheduled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"job-rejected\">Job Rejected</h2>\n<ul>\n<li>Status: <code>rejected</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the reject reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<h2 id=\"job-completed\">Job Completed</h2>\n<ul>\n<li>Status: <code>complete</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the complete reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<p>This event is generated in the following circumstances:</p>\n<ul>\n<li>By completing an appointment using the \"Ready for Billing\" reason (and there are no other open appointment on the job)</li>\n<li>By completing a job directly via the Dispatch Manage Portal</li>\n</ul>\n<p>Therefore:</p>\n<ul>\n<li>If all you need to monitor is whether a job is complete or not then you should process this event</li>\n<li>If you want to track granularity at the appointment level then you should also process the appointment <code>complete</code> event (not required in most cases)</li>\n</ul>\n<p>Note:</p>\n<ul>\n<li>A follow up appointment can be created even after a job has been completed. If this happens another appointment <code>scheduled</code> event will be generated</li>\n</ul>\n<h2 id=\"job-paused\">Job Paused</h2>\n<ul>\n<li>Status: <code>paused</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the pause reason from the <code>status_message</code> (see examples below)</li>\n</ul>\n</li>\n</ul>\n<p>This event is generated in the following circumstances:</p>\n<ul>\n<li>By completing an appointment as a \"no show\"</li>\n<li>By completing an appointment as \"waiting for parts\"</li>\n<li>By indicating on the job that you \"cannot contact customer\"</li>\n<li>Other pause events configured for your instance</li>\n</ul>\n<h2 id=\"job-canceled\">Job Canceled</h2>\n<ul>\n<li>Status: <code>canceled</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the cancel reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<p>This event is emitted when a job is canceled. Therefore:</p>\n<ul>\n<li>If all you need to monitor is whether a job is canceled or not then you should subscribe to this event</li>\n<li>If you want to track granularity at the appointment level then you should also subscribe to the appointment <code>canceled</code> event (not required in most cases)</li>\n</ul>\n<h2 id=\"job-created\">Job Created</h2>\n<p>Sometimes jobs don't originate from you sending them directly to Dispatch. For example, if customers use a web page for requesting service those jobs could be sent to Dispatch. If you want to subscribe so that you can create them in your system then read on.</p>\n<p>This event is a little beefier than other events as it contains the details of the job which you presumably want to copy to your system.</p>\n<ul>\n<li>Status: <code>offered</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"job\": {\n                        \"id\": 30462,\n                        \"organization_id\": 11776,\n                        \"title\": \" Claim Details 206\",\n                        \"status\": \"offered\",\n                        \"status_message\": \"\",\n                        \"description\": \"some description\",\n                        \"updated_at\": \"2018-05-18T10:05:46+0000\",\n                        \"service_type\": \"air conditioning\",\n                        \"service_fee\": 0,\n                        \"address\": {\n                            \"street_1\": \"1755 Ridgeview Dr\",\n                            \"street_2\": \"\",\n                            \"postal_code\": \"76012\",\n                            \"city\": \"Arlington\",\n                            \"state\": \"TX\",\n                            \"country\": \"United States\",\n                            \"timezone\": \"America/Chicago\",\n                            \"latitude\": 32.7633905735029,\n                            \"longitude\": -97.1352367468659\n                        },\n                        \"external_id\": \"your_system_id\",\n                        \"customer\": {\n                            \"first_name\": \"James\",\n                            \"last_name\": \"Dodd\",\n                            \"company_name\": \"\",\n                            \"email\": \"devs+dodd@dispatch.me\",\n                            \"phone_number\": \"+15559803824\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"ade1b10c-6eb7-445c-8bf2-affaaa45e78d"},{"name":"Appointment Related Events","id":"b3aab504-5d8c-4028-9cd4-8fd519108658","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Appointment</em> events. These events are wrapped in an <code>appointment</code> key.</p>\n<p>These are the cases that should be monitored:</p>\n<ul>\n<li>Scheduled</li>\n<li>OMW</li>\n<li>Started</li>\n<li>Completed*</li>\n<li>Canceled*</li>\n</ul>\n<p>*Only if appointment granularity is required, otherwise you should track these with the corresponding job events.</p>\n<p>There is both a job <code>external_id</code> and appointment <code>external_id</code> in this payload. If you are monitoring the appointment level you should use the appointment reference otherwise it will be sufficient to use the job reference.</p>\n<p>Appointment events have the following basic payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"appointment\": {\n                        \"id\": 18663,\n                        \"external_id\": \"your_system_id\",\n                        \"status\": \"some_status\",\n                        \"job_id\": 30463,\n                        \"updated_at\": \"2018-05-18T10:08:38+0000\",\n                        \"start_time\": \"2018-05-19T15:00:00+0000\",\n                        \"end_time\": \"2018-05-19T16:00:00+0000\",\n                        \"job\": {\n                            \"external_id\": \"your_system_id\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"appointment-scheduled\">Appointment Scheduled</h2>\n<ul>\n<li>Status: <code>scheduled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-omw\">Appointment OMW</h2>\n<ul>\n<li>Status: <code>enroute</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-started\">Appointment Started</h2>\n<ul>\n<li>Status: <code>started</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-completed\">Appointment Completed</h2>\n<ul>\n<li>Status: <code>complete</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-canceled\">Appointment Canceled</h2>\n<ul>\n<li>Status: <code>canceled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"b3aab504-5d8c-4028-9cd4-8fd519108658"},{"name":"Notes & Attachment Events","id":"ddc8ae76-f98e-4235-88a2-4d67657cb045","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for consuming <em>notes</em> and <em>attachment</em> events. These events are wrapped in an <code>attachment</code> element.</p>\n<p>Processing notes:</p>\n<ul>\n<li>The payloads for both of these events are very similar. The only difference is that a note will have a <code>description</code> attribute and an attachment will have a <code>file_token</code> element as you'll see in the examples below. Use this for your branch logic.</li>\n<li>It's possible for a note to get deleted or updated. Therefore it is recommended that you store the Dispatch note <code>id</code> so that it can be referenced later on. If the <code>deleted_at</code> is not null, it means the note has been deleted.</li>\n</ul>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"notes\">Notes</h2>\n<p>Note events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    {\n        \"Payload\": {\n            \"Actions\": [\n                {\n                    \"ID\": null,\n                    \"Put\": {\n                        \"attachment\": {\n                            \"id\": 3675,\n                            \"entity_type\": \"Job\",\n                            \"entity_id\": 30463,\n                            \"description\": \"some note\",\n                            \"updated_at\": \"2018-05-18T10:14:51+0000\",\n                            \"deleted_at\": null,\n                            \"job\": {\n                                \"external_id\": \"your_system_id\"\n                            }                            \n                        }\n                    }\n                }\n            ]\n        }\n    }\n\n</code></pre>\n<p>There's nothing more to it. Just pick up the <code>description</code> and process to your system.</p>\n<h2 id=\"attachment\">Attachment</h2>\n<p>Attachment events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"attachment\": {\n                        \"id\": 3676,\n                        \"entity_type\": \"Job\",\n                        \"entity_id\": 30463,\n                        \"file_token\": \"37f3cf22-f1c5-437c-a078-8608e25a0b2b\",\n                        \"name\": \"DispatchConnect.png\",\n                        \"updated_at\": \"2018-05-18T10:15:49+0000\",\n                        \"deleted_at\": null,\n                        \"job\": {\n                            \"external_id\": \"your_system_id\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre><p>Please refer to <a href=\"https://playbooks.dispatch.me/?version=latest#f3f11bce-b781-4713-a09d-e8b8628fa9f7\">this section</a> for a write up on how to render the image using the retrieved file token.</p>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"ddc8ae76-f98e-4235-88a2-4d67657cb045"},{"name":"Survey Events","id":"91b901e3-d376-4f59-8ba0-9121361a8ccb","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Survey</em> events. These events are wrapped in an <code>surveyresponse</code> element.</p>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"survey-submitted\">Survey Submitted</h2>\n<p>Survey events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    {\n        \"Payload\": {\n            \"Actions\": [\n                {\n                    \"ID\": null,\n                    \"Put\": {\n                        \"surveyresponse\": {\n                            \"account_message\": \"Average\",\n                            \"account_rating\": 3,\n                            \"id\": 4361,\n                            \"job_id\": 30459,\n                            \"message\": \"Great!\",\n                            \"rating\": 5,\n                            \"updated_at\": \"2018-05-18T10:57:10+0000\",\n                            \"job\": {\n                                \"external_id\": \"your_system_id\"\n                            }\n                        }\n                    }\n                }\n            ]\n        }\n    }\n\n</code></pre>\n<p>The survey <code>message</code> is broken up as follows:</p>\n<ul>\n<li>Text in [ ] are the \"Tell us why\" reasons</li>\n<li>The remainder are the \"additional comments\"</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"91b901e3-d376-4f59-8ba0-9121361a8ccb"}],"id":"c73af39b-732f-4f5b-b3a9-650154d2f687","description":"<h2 id=\"overview\">Overview</h2>\n<p>If you need to update your system based on updates made on the Dispatch platform then this section is for you! If you managed to successfully send a job to Dispatch then you will be able to <a href=\"https://www.screencast.com/t/uZ5DxiioftvJ\">sign in as a Dispatcher and Technician and work the job</a>.</p>\n<p>As a general rule, an event will only appear in the stream if it's something that originated from the Dispatch Platform. This means that we will not echo updates that originated in your system back to you!</p>\n<p><strong>And very importantly, please be sure to follow <a href=\"https://playbooks.dispatch.me/?version=latest#dispatch-outbound\">these Polling Design Best Practices</a></strong>  </p>\n<h2 id=\"event-summary\">Event Summary</h2>\n<p>This section lists the typical events that we think you should be monitoring (see this section for additional <a href=\"https://playbooks.dispatch.me/?version=latest#d3bae626-b827-45bf-a713-bdb25357011a\">Connect Use Cases</a>). If you encounter a case that you think is not covered, please reach out to us to review.</p>\n<ul>\n<li>Job<ul>\n<li>Job Accepted <code>job.unscheduled</code></li>\n<li>Job Declined <code>job.rejected</code> (with configurable reasons e.g. Incorrect Service Area, No Availability, Wrong Trade)</li>\n<li>Job Completed: <code>job.complete</code> (with configurable reasons e.g. Ready for Billing)</li>\n<li>Job Paused: <code>job_paused</code> (with configurable reasons e.g. No Show, Waiting for Parts, Cannot Contact Customer)</li>\n<li>Job Canceled: <code>job.canceled</code> (with configurable reasons)</li>\n<li>Job Created: <code>job.offered</code> (only necessary when the jobs do not get sent directly from your system)</li>\n</ul>\n</li>\n<li>Appointment<ul>\n<li>Appointment Scheduled: <code>appointment.scheduled</code></li>\n<li>Technician OMW: <code>appointment.enroute</code></li>\n<li>Appointment Started: <code>appointment.started</code></li>\n<li>Appointment Complete: <code>appointment.complete</code> <em>(only if you need to track at the appointment level - usually sufficient to use <code>job.complete</code>)</em></li>\n<li>Appointment Canceled: <code>appointment.canceled</code> <em>(only if you need to track at the appointment level - usually sufficient to use <code>job.canceled</code>)</em></li>\n</ul>\n</li>\n<li>Survey<ul>\n<li>Submitted by Customer: <code>survey.submitted</code></li>\n</ul>\n</li>\n<li>Notes/Attachments<ul>\n<li>Note: <code>note</code></li>\n<li>Attachment: <code>attachment</code></li>\n</ul>\n</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"ce1b102a-29ae-4690-897f-6a388cd194b0","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"8cc04b65-241a-46e6-8f1e-dae6cfc535b6","type":"text/javascript","exec":[""]}}],"_postman_id":"c73af39b-732f-4f5b-b3a9-650154d2f687"}],"id":"da4b7616-8067-4be8-90f3-16c6c2a0c85e","description":"<p>Use this section when the service provider assignment logic is performed in your system of record such that the job already comes with a service provider assigned when it hits Dispatch.</p>\n","event":[{"listen":"prerequest","script":{"id":"7f282b0f-a36e-4ad9-981d-888729fbd620","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"7fdfe78e-d992-4928-84cb-a3b70f24d401","type":"text/javascript","exec":[""]}}],"_postman_id":"da4b7616-8067-4be8-90f3-16c6c2a0c85e"},{"name":"Match","item":[{"name":"To Dispatch","item":[{"name":"Organizations","id":"b073f81f-b94b-455d-b53e-26aae60f526b","request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"organization\",\r\n            \"version\": \"v3\"\r\n        },\r\n        \"record\": {\r\n            \"name\": \"Your Service Provider\",\r\n            \"email\": \"your_service_provider@dispatch.me\",\r\n            \"external_id\": \"your_enterprise_id\",\r\n            \"phone_number\": \"(555)010-0352\",\r\n            \"address\": {\r\n                \"street_1\": \"3310 Maple Avenue\",\r\n                \"postal_code\": \"90731\",\r\n                \"city\": \"San Pedro\",\r\n                \"state\": \"CA\"\r\n            }\r\n        }\r\n    },\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"trade_account_org\"\r\n        },\r\n        \"record\": {\r\n            \"external_id\": \"your_external_org_id\",\r\n            \"trades\": [\"Trade 1\", \"Trade 2\", \"Trade 3\"],\r\n            \"external_organization_id\": \"your_external_org_id\"\r\n        }\r\n    },\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"service_area\",\r\n            \"version\": \"v1\"\r\n        },\r\n        \"record\": {\r\n            \"external_id\": \"your_external_org_id\",\r\n            \"external_organization_id\": \"your_external_org_id\",\r\n            \"service_area_type\": \"zcta5\",\r\n            \"name\": \"Your Service Provider (recommend setting to the same value as your Service Provider name)\",\r\n            \"postal_codes\": [\r\n                {\r\n                    \"postal_code\": \"02446\"\r\n                },\r\n                {\r\n                    \"postal_code\": \"02447\"\r\n                },\r\n                {\r\n                    \"postal_code\": \"02488\"\r\n                }\r\n            ]\r\n        }\r\n    },\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"billing_item\",\r\n            \"version\": \"v2\"\r\n        },\r\n        \"record\": {\r\n            \"title\": \"Widget\",\r\n            \"item_type\": \"service\",\r\n            \"description\": \"Widget Description\",\r\n            \"external_id\": \"your_catalog_id\",\r\n            \"external_organization_id\": \"your_external_org_id\",\r\n            \"price\": 200,\r\n            \"sku\": \"widget\",\r\n            \"active\": true,\r\n            \"trades\": [\r\n                \"Trade 1\",\r\n                \"Trade 2\"\r\n            ],\r\n            \"price_locked\": false\r\n        }\r\n    }\r\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<h2 id=\"overview\">Overview</h2>\n<p>We call it an Organization. You might call it a Service Provider, Contractor, 3rd Party, Installer or something else. Tomato, tomāto.</p>\n<p>For the match scenario, you will want to create these records in advance... so that you can auto-assign the jobs to them.</p>\n<p>At a minimum, please ensure you provide us with the following bits of information (although the more the merrier of course):</p>\n<ul>\n<li>Name</li>\n<li>Valid Phone Number</li>\n<li>External Organization ID - your unique reference</li>\n</ul>\n<p>Oh and definitely the address. We use that to determine the time zone and if it's omitted we're forced to default to EST. So you may want to pass this so the guys in CA can sleep in a little bit.</p>\n<p>Send this payload and Bob's your contractor!</p>\n<h2 id=\"match-setup\">Match Setup</h2>\n<p>In order to leverage the match algorithm, you may also want to send over the additional payloads included in the example. These should be mostly self-explanatory, but here's an explanation in terms of what these are used for.</p>\n<h6 id=\"trade_account_org-record\">trade_account_org record:</h6>\n<p>This is used to assign trades to orgs which can be used to auto-match and will also be used for filtering purposes on the front end.</p>\n<ul>\n<li><code>external_organization_id</code> - this should match the <code>external_id</code> passed into the <code>organization</code> record</li>\n<li><code>external_id</code> - in most cases this should be the same as <code>external_organization_id</code></li>\n<li><code>trades</code> - List of trades. Note that these should be user friendly as they are also displayed on the front end.</li>\n</ul>\n<h6 id=\"service_area-record\">service_area record:</h6>\n<p>This is used to zip code coverage areas to orgs which can be used to auto-match. The example here is set up using US postal codes, but we also support Canadian postal codes and tracts. See the \"Use Cases\" for examples of those.</p>\n<ul>\n<li><code>external_organization_id</code> - this should match the <code>external_id</code> passed into the <code>organization</code> record</li>\n<li><code>external_id</code> - in most cases this should be the same as <code>external_organization_id.</code></li>\n<li><code>external_organization_id</code>- for US postal codes set to <code>zcta5</code>. See Use Cases for other formats.</li>\n<li><code>postal_codes</code> - Include all the zip codes covered in this section</li>\n</ul>\n<h6 id=\"billing_item-record\">billing_item record:</h6>\n<p>This is the product catalog. This is not used for auto-assign and therefore is optional for match. It is included here because these can be limited to the trades defined above.</p>\n<ul>\n<li><code>external_organization_id</code> - this should match the <code>external_id</code> passed into the <code>organization</code> record</li>\n<li><code>external_id</code> - in most cases this should be the same as <code>external_organization_id.</code></li>\n<li><code>item_type</code> - <code>product</code> or <code>service</code></li>\n<li><code>trades</code> - Specify the trade list you want to link the billing item to.</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"b073f81f-b94b-455d-b53e-26aae60f526b"},{"name":"Jobs","id":"7b40e27d-d44e-4c55-b296-62fbebdf3b15","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"offer\",\n            \"version\": \"v2\"\n        },\n        \"record\": {\n            \"customer\": {\n                \"first_name\": \"Jane\",\n                \"last_name\": \"Doe\",\n                \"external_id\": \"your_enterprise_service_provider_id-your_enterprise_customer_id\",\n                \"email\": \"email@dispatch.me\",\n                \"phone_numbers\": [\n                    {\n                        \"number\": \"+15550913813\",\n                        \"primary\": true,\n                        \"type\": \"Mobile\"\n                    }\n                ],\n                \"home_address\": {\n                    \"street_1\": \"3913 Ford Street\",\n                    \"city\": \"Revere\",\n                    \"state\": \"MA\",\n                    \"postal_code\": \"02151\",\n                    \"country\": \"United States\"\n                }\n            },\n            \"title\": \"Job title\",\n            \"status\": \"unassigned\",\n            \"description\": \"Some description.\\n\\n# Accepts *markdown*\",\n            \"external_id\": \"your_enterprise_job_id\",\n            \"symptom\": \"Some symptom\",\n            \"service_fee\": 500,\n            \"service_fee_precollected\": false,\n            \"service_instructions\": \"instruction to tech\",\n            \"contacts\": [\n                {\n                    \"first_name\": \"Jane\",\n                    \"last_name\": \"Doe\",\n                    \"primary\": true,\n                    \"contact_methods\": [\n                        {\n                            \"value\": \"+15550913813\",\n                            \"method\": \"phone\",\n                            \"notify\": true\n                        },\n                        {\n                            \"value\": \"test@abc.com\",\n                            \"method\": \"email\",\n                            \"notify\": true\n                        }\n                    ]\n                }\n            ],\n            \"address\": {\n                \"street_1\": \"1213 Summer St\",\n                \"street_2\": \"apt. 1\",\n                \"postal_code\": \"02151\",\n                \"city\": \"Boston\",\n                \"state\": \"MA\",\n                \"country\": \"United States\"\n            },\n            \"service_type\": \"plumber\",\n            \"trades\": [\n                \"Trade 1\"\n            ],\n            \"_labels\": [\n                {\n                    \"label_id\": 100\n                },\n                {\n                    \"label_id\": 101\n                }\n            ],\n            \"equipment_descriptions\": [\n                {\n                    \"manufacturer\": \"Acme\",\n                    \"model_number\": \"500\",\n                    \"serial_number\": \"01024\",\n                    \"installation_date\": \"2017-10-21T00:00:00Z\",\n                    \"equipment_type\": \"hvac\"\n                }\n            ],\n            \"custom_fields\": {\n                \"do_not_survey\": \"yes\",\n                \"arrival_type\": \"range\"\n            }\n        },\n        \"ui_options\": {\n            \"show_decline\": true,\n            \"accept_title\": \"Accept\",\n            \"decline_title\": \"Decline\",\n            \"reject_reasons\": [\n                \"wrong_area|I don't service this address|true|false\",\n                \"wrong_trade|I don't do this type of work|false|true\",\n                \"no_availability|I can't do this job in time|false|false\",\n                \"other|Other|true|true\"\n            ]\n        }\n    },\n    {\n        \"header\": {\n            \"record_type\": \"auto_assign_org\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"external_id\": \"your_enterprise_job_id\",\n            \"include_linked_orgs\": true,\n            \"trades\": [\n                \"Trade 1\"\n            ],\n            \"postal_code\": \"02151\"\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<h2 id=\"overview\">Overview</h2>\n<p>We call it an Offer. You might call it a Work Order, Service Order or something else. Potato, potāto.</p>\n<p>The essential difference between a Dispatch \"job\" vs. an \"offer\" is that while a job is always assigned to a provider, an offer is never initially assigned to a provider. That happens as part of a subsequent \"match\" operation or assignment via the Dispatch UI. Once that assignment happens, the offer is converted into a job and all the usual processing associated with jobs and statuses applies (see \"DNM Quick Start\").</p>\n<p>A offer has the following main elements:</p>\n<ul>\n<li>Job Details</li>\n<li>Customer Details</li>\n</ul>\n<p>Though we are quite forgiving, a job cannot really be a job without some basic information, so please take care to include the following details:</p>\n<ul>\n<li>Customer name (preferably first and last but we'll settle with whatever you can send us)</li>\n<li>Valid address (we need to know where to go!)</li>\n</ul>\n<p>We will not create duplicate records. Meaning if you send over the same organization or customer record more than once, the system is smart enough to detect they exist.</p>\n<p>We'd also recommend you include a valid customer email and mobile number as that will enhance the experience. Do try to avoid invalid entries such as <code>jim@@abc.com</code> and <code>555123</code> as if you don't manage that we'll be forced to strip them before processing.</p>\n<p>Oh and lastly, we'd really encourage sending over your unique IDs into the <code>external_id</code> fields for the offer. This field is used for matching in order to process updates as described above.</p>\n<p>Send this payload and voila - an offer will be created in Dispatch!</p>\n<h2 id=\"special-fields\">Special Fields</h2>\n<p>If you are providing a custom payload then you can skip this next section. Most of the fields in the payload should be self explanatory. But we do want to bring the following to your attention:</p>\n<h6 id=\"offer-record\">offer record:</h6>\n<ul>\n<li><code>status</code> - the default mapping expects the following values:<ul>\n<li>unassigned - offers must be created in this status</li>\n<li>complete</li>\n<li>canceled</li>\n</ul>\n</li>\n<li><code>description</code> - this can accept <a href=\"https://dillinger.io/\">markdown</a> formatting</li>\n<li><code>contacts</code> - you can include this section to specify 1 or more contacts for the job. This can differ or be the same as to what you pass on the customer record.</li>\n<li><code>ui_options</code> - This is an optional section. It allows you to specify reject reasons for a job offered to a service provider. You can use what's presented in this example or provider your own list. The format of the reject reasons uses the following format: <code>value|friendly_label|show_text|require_text</code> where:</li>\n<li><code>custom_fields</code> - you can specify any number of custom fields here. These will not show up on the front end by default, so please coordinate with Dispatch what your objective is, if using these.</li>\n<li><code>trades</code> - List of trades you want to include on the job which can be used in the matching algorith.</li>\n</ul>\n<h2 id=\"match-processing\">Match Processing</h2>\n<p>If you want to invoke the match processing so that it runs immediately after the offer is, you should include the <code>auto_assign_org</code> record. See description <a href=\"#bb712486-b01c-4806-8dab-256f15490fd4\">here</a>.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"7b40e27d-d44e-4c55-b296-62fbebdf3b15"}],"id":"b1989cac-14f9-4907-abfd-30f813e0f075","event":[{"listen":"prerequest","script":{"id":"5007f813-77a2-4493-9dd4-70c24ae848bd","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"dc507a1a-af78-4f9d-894f-cdd583bbda3a","type":"text/javascript","exec":[""]}}],"_postman_id":"b1989cac-14f9-4907-abfd-30f813e0f075","description":""},{"name":"From Dispatch","item":[{"name":"Offer Related Events","id":"6f3c408d-a66d-44ab-8bbd-cb08b2f10d54","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing Offer events. These events are wrapped in a <code>offer</code> key ().</p>\n<p>These are the cases that should be monitored:</p>\n<ul>\n<li>Offered</li>\n<li>Canceled</li>\n</ul>\n<p>Offer events have the following basic payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"offer\": {\n                        \"id\": 30462,\n                        \"status\": \"some_status\",\n                        \"status_message\": \"some message\",\n                        \"updated_at\": \"2018-05-18T10:05:46+0000\",\n                        \"external_id\": \"your_system_id\"\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"offered\">Offered</h2>\n<p>This indicates that the offer sent out was assigned and \"offered\" to an org (via auto or manual assign)</p>\n<ul>\n<li>Status: <code>offered</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"canceled\">Canceled</h2>\n<p>This indicates that the offer was canceled.</p>\n<ul>\n<li>Status: <code>canceled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"6f3c408d-a66d-44ab-8bbd-cb08b2f10d54"},{"name":"Job Related Events","id":"ee72b873-0b9c-4ed7-bfe0-eb8613e85b8f","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Job</em> events. These events are wrapped in a <code>job</code> key ().</p>\n<p>These are the cases that should be monitored:</p>\n<ul>\n<li>Accepted</li>\n<li>Rejected (with configurable reasons)</li>\n<li>Completed (with configurable reasons e.g. Ready for Billing)</li>\n<li>Paused (with configurable reasons e.g No Show, Waiting for Parts, Cannot Contact Customer)</li>\n<li>Canceled (with configurable reasons)</li>\n<li>Created (only if you are not sending jobs directly to Dispatch)</li>\n</ul>\n<p>Job events have the following basic payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"job\": {\n                        \"id\": 30462,\n                        \"status\": \"some_status\",\n                        \"status_message\": \"some message\",\n                        \"updated_at\": \"2018-05-18T10:05:46+0000\",\n                        \"external_id\": \"your_system_id\"\n                        ]\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"job-accepted\">Job Accepted</h2>\n<ul>\n<li>Status: <code>unscheduled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"job-rejected\">Job Rejected</h2>\n<ul>\n<li>Status: <code>rejected</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the reject reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<h2 id=\"job-completed\">Job Completed</h2>\n<ul>\n<li>Status: <code>complete</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the complete reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<p>This event is generated in the following circumstances:</p>\n<ul>\n<li>By completing an appointment using the \"Ready for Billing\" reason (and there are no other open appointment on the job)</li>\n<li>By completing a job directly via the Dispatch Manage Portal</li>\n</ul>\n<p>Therefore:</p>\n<ul>\n<li>If all you need to monitor is whether a job is complete or not then you should process this event</li>\n<li>If you want to track granularity at the appointment level then you should also process the appointment <code>complete</code> event (not required in most cases)</li>\n</ul>\n<p>Note:</p>\n<ul>\n<li>A follow up appointment can be created even after a job has been completed. If this happens another appointment <code>scheduled</code> event will be generated</li>\n</ul>\n<h2 id=\"job-paused\">Job Paused</h2>\n<ul>\n<li>Status: <code>paused</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the pause reason from the <code>status_message</code> (see examples below)</li>\n</ul>\n</li>\n</ul>\n<p>This event is generated in the following circumstances:</p>\n<ul>\n<li>By completing an appointment as a \"no show\"</li>\n<li>By completing an appointment as \"waiting for parts\"</li>\n<li>By indicating on the job that you \"cannot contact customer\"</li>\n<li>Other pause events configured for your instance</li>\n</ul>\n<h2 id=\"job-canceled\">Job Canceled</h2>\n<ul>\n<li>Status: <code>canceled</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the cancel reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<p>This event is emitted when a job is canceled. Therefore:</p>\n<ul>\n<li>If all you need to monitor is whether a job is canceled or not then you should subscribe to this event</li>\n<li>If you want to track granularity at the appointment level then you should also subscribe to the appointment <code>canceled</code> event (not required in most cases)</li>\n</ul>\n<h2 id=\"job-created\">Job Created</h2>\n<p>Sometimes jobs don't originate from you sending them directly to Dispatch. For example, if customers use a web page for requesting service those jobs could be sent to Dispatch. If you want to subscribe so that you can create them in your system then read on.</p>\n<p>This event is a little beefier than other events as it contains the details of the job which you presumably want to copy to your system.</p>\n<ul>\n<li>Status: <code>offered</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"job\": {\n                        \"id\": 30462,\n                        \"organization_id\": 11776,\n                        \"title\": \" Claim Details 206\",\n                        \"status\": \"offered\",\n                        \"status_message\": \"\",\n                        \"description\": \"some description\",\n                        \"updated_at\": \"2018-05-18T10:05:46+0000\",\n                        \"service_type\": \"air conditioning\",\n                        \"service_fee\": 0,\n                        \"address\": {\n                            \"street_1\": \"1755 Ridgeview Dr\",\n                            \"street_2\": \"\",\n                            \"postal_code\": \"76012\",\n                            \"city\": \"Arlington\",\n                            \"state\": \"TX\",\n                            \"country\": \"United States\",\n                            \"timezone\": \"America/Chicago\",\n                            \"latitude\": 32.7633905735029,\n                            \"longitude\": -97.1352367468659\n                        },\n                        \"external_id\": \"your_system_id\",\n                        \"customer\": {\n                            \"first_name\": \"James\",\n                            \"last_name\": \"Dodd\",\n                            \"company_name\": \"\",\n                            \"email\": \"devs+dodd@dispatch.me\",\n                            \"phone_number\": \"+15559803824\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"ee72b873-0b9c-4ed7-bfe0-eb8613e85b8f"},{"name":"Appointment Related Events","id":"9d8e2ee7-bd0a-41cd-b0ef-161498bebc40","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Appointment</em> events. These events are wrapped in an <code>appointment</code> key.</p>\n<p>These are the cases that should be monitored:</p>\n<ul>\n<li>Scheduled</li>\n<li>OMW</li>\n<li>Started</li>\n<li>Completed*</li>\n<li>Canceled*</li>\n</ul>\n<p>*Only if appointment granularity is required, otherwise you should track these with the corresponding job events.</p>\n<p>There is both a job <code>external_id</code> and appointment <code>external_id</code> in this payload. If you are monitoring the appointment level you should use the appointment reference otherwise it will be sufficient to use the job reference.</p>\n<p>Appointment events have the following basic payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"appointment\": {\n                        \"id\": 18663,\n                        \"external_id\": \"your_system_id\",\n                        \"status\": \"some_status\",\n                        \"job_id\": 30463,\n                        \"updated_at\": \"2018-05-18T10:08:38+0000\",\n                        \"start_time\": \"2018-05-19T15:00:00+0000\",\n                        \"end_time\": \"2018-05-19T16:00:00+0000\",\n                        \"job\": {\n                            \"external_id\": \"your_system_id\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"appointment-scheduled\">Appointment Scheduled</h2>\n<ul>\n<li>Status: <code>scheduled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-omw\">Appointment OMW</h2>\n<ul>\n<li>Status: <code>enroute</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-started\">Appointment Started</h2>\n<ul>\n<li>Status: <code>started</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-completed\">Appointment Completed</h2>\n<ul>\n<li>Status: <code>complete</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-canceled\">Appointment Canceled</h2>\n<ul>\n<li>Status: <code>canceled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"9d8e2ee7-bd0a-41cd-b0ef-161498bebc40"},{"name":"Notes & Attachment Events","id":"846f7b18-abb5-4a5d-ab8b-21f56fbca479","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for consuming <em>notes</em> and <em>attachment</em> events. These events are wrapped in an <code>attachment</code> element.</p>\n<p>Processing notes:</p>\n<ul>\n<li>The payloads for both of these events are very similar. The only difference is that a note will have a <code>description</code> attribute and an attachment will have a <code>file_token</code> element as you'll see in the examples below. Use this for your branch logic.</li>\n<li>It's possible for a note to get deleted or updated. Therefore it is recommended that you store the Dispatch note <code>id</code> so that it can be referenced later on. If the <code>deleted_at</code> is not null, it means the note has been deleted.</li>\n</ul>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"notes\">Notes</h2>\n<p>Note events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    {\n        \"Payload\": {\n            \"Actions\": [\n                {\n                    \"ID\": null,\n                    \"Put\": {\n                        \"attachment\": {\n                            \"id\": 3675,\n                            \"entity_type\": \"Job\",\n                            \"entity_id\": 30463,\n                            \"description\": \"some note\",\n                            \"updated_at\": \"2018-05-18T10:14:51+0000\",\n                            \"deleted_at\": null,\n                            \"job\": {\n                                \"external_id\": \"your_system_id\"\n                            }                            \n                        }\n                    }\n                }\n            ]\n        }\n    }\n\n</code></pre>\n<p>There's nothing more to it. Just pick up the <code>description</code> and process to your system.</p>\n<h2 id=\"attachment\">Attachment</h2>\n<p>Attachment events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"attachment\": {\n                        \"id\": 3676,\n                        \"entity_type\": \"Job\",\n                        \"entity_id\": 30463,\n                        \"file_token\": \"37f3cf22-f1c5-437c-a078-8608e25a0b2b\",\n                        \"name\": \"DispatchConnect.png\",\n                        \"updated_at\": \"2018-05-18T10:15:49+0000\",\n                        \"deleted_at\": null,\n                        \"job\": {\n                            \"external_id\": \"your_system_id\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<p>Please refer to <a href=\"https://playbooks.dispatch.me/?version=latest#f3f11bce-b781-4713-a09d-e8b8628fa9f7\">this section</a> for a write up on how to render the image using the retrieved file token.</p>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"846f7b18-abb5-4a5d-ab8b-21f56fbca479"},{"name":"Survey Events","id":"25167c0e-4d78-4e8b-8013-5c0445b968b1","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Survey</em> events. These events are wrapped in an <code>surveyresponse</code> element.</p>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"survey-submitted\">Survey Submitted</h2>\n<p>Survey events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    {\n        \"Payload\": {\n            \"Actions\": [\n                {\n                    \"ID\": null,\n                    \"Put\": {\n                        \"surveyresponse\": {\n                            \"account_message\": \"Average\",\n                            \"account_rating\": 3,\n                            \"id\": 4361,\n                            \"job_id\": 30459,\n                            \"message\": \"Great!\",\n                            \"rating\": 5,\n                            \"updated_at\": \"2018-05-18T10:57:10+0000\",\n                            \"job\": {\n                                \"external_id\": \"your_system_id\"\n                            }\n                        }\n                    }\n                }\n            ]\n        }\n    }\n\n</code></pre>\n<p>The survey <code>message</code> is broken up as follows:</p>\n<ul>\n<li>Text in [ ] are the \"Tell us why\" reasons</li>\n<li>The remainder are the \"additional comments\"</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"25167c0e-4d78-4e8b-8013-5c0445b968b1"}],"id":"feef6d67-7719-4585-b5a7-30430ca67659","description":"<h2 id=\"overview\">Overview</h2>\n<p>If you need to update your system based on updates made on the Dispatch platform then this section is for you! If you managed to successfully send a job to Dispatch then you will be able to <a href=\"https://www.screencast.com/t/uZ5DxiioftvJ\">sign in as a Dispatcher and Technician and work the job</a>.</p>\n<p>As a general rule, an event will only appear in the stream if it's something that originated from the Dispatch Platform. This means that we will not echo updates that originated in your system back to you!</p>\n<p><strong>And very importantly, please be sure to follow <a href=\"https://playbooks.dispatch.me/?version=latest#dispatch-outbound\">these Polling Design Best Practices</a></strong>  </p>\n<h2 id=\"event-summary\">Event Summary</h2>\n<p>This section lists the typical events that we think you should be monitoring (see this section for additional <a href=\"https://playbooks.dispatch.me/?version=latest#d3bae626-b827-45bf-a713-bdb25357011a\">Connect Use Cases</a>). If you encounter a case that you think is not covered, please reach out to us to review.</p>\n<ul>\n<li>Job<ul>\n<li>Job Accepted <code>job.unscheduled</code></li>\n<li>Job Declined <code>job.rejected</code> (with configurable reasons e.g. Incorrect Service Area, No Availability, Wrong Trade)</li>\n<li>Job Completed: <code>job.complete</code> (with configurable reasons e.g. Ready for Billing)</li>\n<li>Job Paused: <code>job_paused</code> (with configurable reasons e.g. No Show, Waiting for Parts, Cannot Contact Customer)</li>\n<li>Job Canceled: <code>job.canceled</code> (with configurable reasons)</li>\n<li>Job Created: <code>job.offered</code> (only necessary when the jobs do not get sent directly from your system)</li>\n</ul>\n</li>\n<li>Appointment<ul>\n<li>Appointment Scheduled: <code>appointment.scheduled</code></li>\n<li>Technician OMW: <code>appointment.enroute</code></li>\n<li>Appointment Started: <code>appointment.started</code></li>\n<li>Appointment Complete: <code>appointment.complete</code> <em>(only if you need to track at the appointment level - usually sufficient to use <code>job.complete</code>)</em></li>\n<li>Appointment Canceled: <code>appointment.canceled</code> <em>(only if you need to track at the appointment level - usually sufficient to use <code>job.canceled</code>)</em></li>\n</ul>\n</li>\n<li>Survey<ul>\n<li>Submitted by Customer: <code>survey.submitted</code></li>\n</ul>\n</li>\n<li>Notes/Attachments<ul>\n<li>Note: <code>note</code></li>\n<li>Attachment: <code>attachment</code></li>\n</ul>\n</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"ce1b102a-29ae-4690-897f-6a388cd194b0","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"8cc04b65-241a-46e6-8f1e-dae6cfc535b6","type":"text/javascript","exec":[""]}}],"_postman_id":"feef6d67-7719-4585-b5a7-30430ca67659"}],"id":"ad21c8ce-8f34-4055-82ef-9dc6bed223b1","description":"<p>Use this scenario when you intend to take advantage of Dispatch's \"match\" algorithm for auto and/or manually assigning the provider record.</p>\n","event":[{"listen":"prerequest","script":{"id":"7f282b0f-a36e-4ad9-981d-888729fbd620","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"7fdfe78e-d992-4928-84cb-a3b70f24d401","type":"text/javascript","exec":[""]}}],"_postman_id":"ad21c8ce-8f34-4055-82ef-9dc6bed223b1"}],"id":"6ed5e5a3-ca51-4b06-ab97-7ff0a4f5c010","description":"<p>The scenarios described in this section are relevant if you're an enterprise who employs a <strong>Decentralized Network (e.g. Contractor Network) for service fulfillment on behalf of your organization</strong>. We refer to this as our Decentralized Network Management (DNM) vertical.</p>\n","_postman_id":"6ed5e5a3-ca51-4b06-ab97-7ff0a4f5c010"},{"name":"(FSM) Field Service Management","item":[{"name":"To Dispatch","item":[{"name":"Organizations","id":"77e6b894-8415-4c4b-b028-8192c6e39b9c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n\t{\r\n\t  \"header\": {\r\n\t    \"record_type\": \"organization\",\r\n\t    \"version\": \"v3\"\r\n\t  },\r\n\t  \"record\": {\r\n\t\t  \"name\" : \"Your Service Provider\",\r\n\t\t  \"email\" : \"your_service_provider@dispatch.me\",\r\n\t\t  \"external_id\": \"your_enterprise_id\",\r\n\t\t  \"phone_number\" : \"(555)010-0352\",\r\n\t\t  \"always_create\": true,\r\n\t\t  \"address\": {\r\n\t\t        \"street_1\": \"3310 Maple Avenue\",\r\n\t\t        \"postal_code\": \"90731\",\r\n\t\t        \"city\": \"San Pedro\",\r\n\t\t        \"state\": \"CA\"\r\n\t\t }\r\n\t  }\r\n\t}\r\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<h2 id=\"overview\">Overview</h2>\n<p>We call it an Organization. You might call it a Franchise, Location, Office or something else. Tomato, tomāto.</p>\n<p>Now the things is, you don't actually have to send these over to us separately. If you send these with the aforementioned job then we'll create them on the fly. However, in a typical W2 use case these are set up in advance and this section will tell you how to do just that.</p>\n<p>At a minimum, please ensure you provide us with the following bits of information (although the more the merrier of course):</p>\n<ul>\n<li>Name</li>\n<li>Valid Phone Number</li>\n</ul>\n<p>It's also really good practice to include your unique organization ID in the <code>external_id</code> attribute as then you can reference that when sending jobs over.</p>\n<p>Oh and definitely the address. We use that to determine the time zone and if it's omitted we're forced to default to EST. So you may want to pass this so the guys in CA can sleep in a little bit.</p>\n<p>Lastly, the <code>always_create</code> flag will result in a new organization being created by circumventing Dispatch's dedup logic (matching on name, address, contact info). It will however not ignore the <code>external_id</code> that you pass through as IDs are, well, special.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"77e6b894-8415-4c4b-b028-8192c6e39b9c"},{"name":"Users","id":"951fcd74-1a65-408c-a237-2055e3d2d734","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"user\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"external_id\": \"your_userid\",\r\n      \"first_name\": \"John\",\r\n      \"last_name\": \"Doe\",\r\n      \"roles\": [\r\n        \"dispatcher\",\r\n        \"technician\"\r\n      ],\r\n      \"phone_number\": \"(555) 122-1912\",\r\n      \"email\": \"devs+johndoe@dispatch.me\",\r\n      \"external_organization_id\": \"your_enterprise_id\"\r\n    }\r\n  },\r\n  {\r\n    \"header\": {\r\n      \"record_type\": \"profile_picture\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"external_id\": \"your_userid\",\r\n      \"external_organization_id\": \"your_enterprise_id\",\r\n      \"attachment\": \"base64string\",\r\n      \"file_name\": \"your_file_name.jpg\"\r\n    }\r\n  }\r\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<h2 id=\"overview\">Overview</h2>\n<p>We call it a User. You might call it an Employee, Tech or something else. </p>\n<p>If you maintain these users in your system of record you are going to want to keep them synchronized with Dispatch and this section will tell you how to do just that.</p>\n<p>At a minimum, please ensure you provide us with the following bits of information (although the more the merrier of course):</p>\n<ul>\n<li>First and Last Name</li>\n<li>Valid Email and/or Phone Number</li>\n<li><code>external_organization_id</code> to link it back the organization</li>\n<li>Roles - either <code>dispatcher</code> (someone who can see other peoples jobs), <code>technician</code> (someone who can only see/work jobs assigned to them) or both</li>\n</ul>\n<p>It's also really good practice to include your unique user ID in the <code>external_id</code> attribute as then you can reference that when sending jobs over.</p>\n<p>If you also wish to send over a photo for your technician, then please also include the <code>profile_picture</code> in your payload (can also be sent as a <a href=\"https://playbooks.dispatch.me/?version=latest#9699b47e-0785-47cd-bac1-f1a8cd3fb96a\">separate payload</a> later if you prefer).</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"951fcd74-1a65-408c-a237-2055e3d2d734"},{"name":"Jobs","id":"51d265a6-376c-485d-8cae-6a120e711978","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"organization\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"organization\": {\n                \"name\": \"Your Service Provider\",\n                \"email\": \"your_service_provider@dispatch.me\",\n                \"external_id\": \"your_enterprise_service_provider_id\",\n                \"phone_number\": \"(555)013-0352\",\n                \"always_create\": true,\n                \"address\": {\n                    \"street_1\": \"3313 Maple Avenue\",\n                    \"postal_code\": \"90731\",\n                    \"city\": \"San Pedro\",\n                    \"state\": \"CA\"\n                }\n            }\n        }\n    },\n    {\n        \"header\": {\n            \"record_type\": \"customer\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"first_name\": \"Jane\",\n            \"last_name\": \"Doe\",\n            \"external_id\": \"your_enterprise_service_provider_id-your_enterprise_customer_id\",\n            \"external_organization_id\": \"your_enterprise_service_provider_id\",\n            \"email\": \"email@dispatch.me\",\n            \"phone_numbers\": [\n                {\n                    \"number\": \"+15550913813\",\n                    \"primary\": true,\n                    \"type\": \"Mobile\"\n                }\n            ],\n            \"home_address\": {\n                \"street_1\": \"3913 Ford Street\",\n                \"city\": \"Revere\",\n                \"state\": \"MA\",\n                \"postal_code\": \"02151\"\n            }\n        }\n    },\n    {\n        \"header\": {\n            \"record_type\": \"job\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"title\": \"Job title\",\n            \"status\": \"offered\",\n            \"description\": \"Some description.\\n\\n# Accepts *markdown*\",\n            \"external_id\": \"your_enterprise_job_id\",\n            \"friendly_external_id\": \"your_friendly_enterprise_job_id\",\n            \"external_customer_id\": \"your_enterprise_customer_id\",\n            \"external_organization_id\": \"your_enterprise_service_provider_id\",\n            \"symptom\": \"Some symptom\",\n            \"service_fee\": 500,\n            \"service_fee_precollected\": false,\n            \"service_instructions\": \"instruction to tech\",\n            \"contacts\": [\n                {\n                    \"first_name\": \"Jane\",\n                    \"last_name\": \"Doe\",\n                    \"primary\": true,\n                    \"contact_methods\": [\n                        {\n                            \"value\": \"+15550913813\",\n                            \"method\": \"phone\",\n                            \"notify\": true\n                        },\n                        {\n                            \"value\": \"test@abc.com\",\n                            \"method\": \"email\",\n                            \"notify\": true\n                        }\n                    ]\n                }\n            ],\n            \"address\": {\n                \"street_1\": \"1213 Summer St\",\n                \"street_2\": \"apt. 1\",\n                \"postal_code\": \"01234\",\n                \"city\": \"Boston\",\n                \"state\": \"MA\"\n            },\n            \"service_type\": \"plumber\",\n            \"equipment_descriptions\": [\n                {\n                    \"manufacturer\": \"Acme\",\n                    \"model_number\": \"500\",\n                    \"serial_number\": \"01024\",\n                    \"installation_date\": \"2017-10-21T00:00:00Z\",\n                    \"equipment_type\": \"hvac\"\n                }\n            ],\n            \"marketing_attributions\": [\n                {\n                    \"content\": \"bingo\",\n                    \"campaign\": \"mamba\",\n                    \"source\": \"orca\",\n                    \"term\": \"glitter\",\n                    \"media\": \"twitter\"\n                }\n            ],\n            \"custom_fields\": {\n                \"do_not_survey\": \"yes\",\n                \"arrival_type\": \"range\"\n            },\n            \"_labels\": [\n                100,\n                101\n            ]\n        }\n    },\n    {\n        \"header\": {\n            \"record_type\": \"appointment\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"external_id\": \"your_enterprise_job_or_appointment_id\",\n            \"time\": \"2020-10-15T22:00:00+0000\",\n            \"duration\": 1600,\n            \"status\": \"scheduled\",\n            \"window_start_time\": \"2020-10-15T13:00:00+0000\",\n            \"window_end_time\": \"2020-10-15T17:00:00+0000\",\n            \"external_user_id\": \"your_user_id\",\n            \"external_secondary_user_ids\": [\n                \"your_user_id2\",\n                \"your_user_id3\"\n            ],\n            \"external_job_id\": \"your_enterprise_job_id\",\n            \"external_organization_id\": \"your_enterprise_service_provider_id\",\n            \"external_type_ids\": [\n                \"type1\"\n            ]\n        }\n    },\n    {\n        \"header\": {\n            \"record_type\": \"auto_assign_technician\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"external_id\": \"your_enterprise_job_id\",\n            \"external_appointment_id\": \"your_enterprise_job_or_appointment_id\",\n            \"external_user_ids\": [\n                \"your_user_id1\",\n                \"your_user_id2\"\n            ],\n            \"external_secondary_user_ids\": [\n                \"your_user_id3\",\n                \"your_user_id4\"\n            ],\n            \"appointment_duration_minutes\": 60,\n            \"address\": {\n                \"street_1\": \"3913 Ford Street\",\n                \"city\": \"Revere\",\n                \"state\": \"MA\",\n                \"postal_code\": \"02151\"\n            },\n            \"postal_code\": \"02151\",\n            \"availability_start_time\": \"2018-05-18T10:00:00+0000\",\n            \"availability_end_time\": \"2018-05-18T14:00:00+0000\",\n            \"override_availability\": false,\n            \"two_tech\": false\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<h2 id=\"overview\">Overview</h2>\n<p>We call it a Job. You might call it a Work Order, Service Order or something else. Potato, potāto. Anyway, you will be sending these over to us.</p>\n<p>A job has the following main elements:</p>\n<ul>\n<li>Job Details</li>\n<li>Customer Details</li>\n<li>Service Provider/Contractor Details</li>\n<li>Appointment and assignment Details</li>\n</ul>\n<p>Though we are quite forgiving, a job cannot really be a job without some basic information, so please take care to include the following details:</p>\n<ul>\n<li>Customer name (preferably first and last but we'll settle with whatever you can send us)</li>\n<li>Valid address (we need to know where to go!)</li>\n<li>Organization email and/or phone # (and/or organization <code>id</code> if you've pre-created those)</li>\n</ul>\n<p>We will not create duplicate records. Meaning if you send over the same organization or customer record more than once, the system is smart enough to detect they exist. This therefore allows you, for example, to change the appointment time, assign and re-assign by just changing those values when sending the payload over.</p>\n<p>We'd also recommend you include a valid customer email and mobile number as that will enhance the experience. Do try to avoid invalid entries such as <code>jim@@abc.com</code> and <code>555123</code> as if you don't manage that we'll be forced to strip them before processing.</p>\n<p>Oh and lastly, we'd really encourage sending over your unique IDs into the <code>external_id</code> fields for the job, appointment, user and organization. This field is used for matching in order to process updates as described above.</p>\n<p>Send this payload and voila - a job will be created in Dispatch!</p>\n<h2 id=\"special-fields\">Special Fields</h2>\n<p>If you are providing a custom payload then you can skip this next section. Most of the fields in the payload should be self explanatory. But we do want to bring the following to your attention:</p>\n<h6 id=\"job-record\">job record:</h6>\n<ul>\n<li><code>friendly_external_id</code> - this is an optional field. Very often systems have the technical \"ugly ID\" that only the techies in your organization know exists. And there is also a \"friendly ID\" that end users and customers use as references. If this is the case, then please put the \"ugly ID\" into the <code>external_id</code> and the \"friendly ID\" into <code>friendly_external_id</code></li>\n<li><code>status</code> - the default mapping expects the following values:<ul>\n<li>complete</li>\n<li>canceled</li>\n</ul>\n</li>\n<li><code>description</code> - this can accept <a href=\"https://dillinger.io/\">markdown</a> formatting</li>\n<li><code>contacts</code> - you can include this section to specify 1 or more contacts for the job. This can differ or be the same as to what you pass on the customer record.</li>\n<li><code>custom_fields</code> - you can specify any number of custom fields here. These will not show up on the front end by default, so please coordinate with Dispatch what your objective is, if using these.</li>\n<li><code>labels</code> - if you want to apply labels to jobs, please reach out to Dispatch with the values you wish to use before using this option (remove the leading \"_\" if you want to use this field).</li>\n</ul>\n<h6 id=\"customer-record\">customer record</h6>\n<ul>\n<li>Dispatch requires that the <code>external_id</code> passed here is unique per organization. This is probably not the case in your system, therefore you should prefix with the external ID of the organization as shown in the payload example</li>\n</ul>\n<h6 id=\"organization-record-ie-service-provider-or-pro\">organization record (i.e. service provider or pro):</h6>\n<ul>\n<li>This record should only be passed in if you're creating these records on the fly. Otherwise, if service providers are created in advance (typical for the FSM model) this record should not be passed and instead just pass <code>organization_id</code> or <code>external_organization_id</code> into the job record.</li>\n<li><code>always_create</code> - we recommend you default to <code>true</code> (see write up <a href=\"https://playbooks.dispatch.me/?version=latest#77e6b894-8415-4c4b-b028-8192c6e39b9c\">here</a>)</li>\n<li>Please note that if you pass in a job to Dispatch with an <code>external_organization_id</code> of \"contractor_1\" and later you update that to \"contractor_2\", the Dispatch Platform will automatically cancel the job for the first contractor and create another for the second.</li>\n</ul>\n<h6 id=\"appointment-record\">appointment record:</h6>\n<ul>\n<li><code>time</code> - estimated/actual start time of the appointment</li>\n<li><code>duration</code> - estimated/actual duration of the appointment (in seconds).</li>\n<li><code>window_start_time</code> and <code>window_end_time</code> - earliest and latest arrival for the appointment (communicated to the customer)</li>\n<li><code>status</code> - you generally want to set this to a value of <code>scheduled</code></li>\n<li>If you have a single appointment to job then just set <code>external_id</code> to <code>external_job_id</code> to the same value</li>\n<li><code>external_user_id</code> if you wish to assign or re-assign this should match the external ID you sent on the user record.</li>\n<li><code>external_secondary_user_ids</code> - if you have additional users you want on the appointment, include them in an array.</li>\n<li><code>external_type_ids</code> - you can specify different record types. This field is optional but if you do use it please ensure you've set up your <a href=\"https://playbooks.dispatch.me/?version=latest#525da6e7-f643-48e3-8f4b-bfe7f93b8466\">appointment types</a></li>\n</ul>\n<h6 id=\"auto_assign_technician-record\">auto_assign_technician record:</h6>\n<p>If you want to leverage auto technician assignment, you should include this record. See explanation <a href=\"#071da253-b7f7-4383-9b78-6c88fc8ef989\">here</a>.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"51d265a6-376c-485d-8cae-6a120e711978"}],"id":"35f635a4-2e5d-415e-b236-7270d6e62b43","event":[{"listen":"prerequest","script":{"id":"5007f813-77a2-4493-9dd4-70c24ae848bd","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"dc507a1a-af78-4f9d-894f-cdd583bbda3a","type":"text/javascript","exec":[""]}}],"_postman_id":"35f635a4-2e5d-415e-b236-7270d6e62b43","description":""},{"name":"From Dispatch","item":[{"name":"Job Related Events","id":"84abb1a8-8111-4319-abb0-12a4b27459b8","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Job</em> events. These events are wrapped in a <code>job</code> element.</p>\n<p>These are the cases that should be monitored:</p>\n<ul>\n<li>Completed (with configurable reasons e.g. Ready for Billing)</li>\n<li>Paused (with configurable reasons e.g. No Show, Waiting for Parts, Cannot Contact Customer)</li>\n<li>Canceled (with configurable reasons)</li>\n<li>Created (only if you are not sending jobs directly to Dispatch)</li>\n</ul>\n<p>Job events have the following basic payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"job\": {\n                        \"id\": 30462,\n                        \"status\": \"some_status\",\n                        \"status_message\": \"some message\",\n                        \"updated_at\": \"2018-05-18T10:05:46+0000\",\n                        \"external_id\": your_system_id\"\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"job-completed\">Job Completed</h2>\n<ul>\n<li>Status: <code>complete</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the complete reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<p>This event is generated in the following circumstances:</p>\n<ul>\n<li>By completing an appointment using the \"Ready for Billing\" reason (and there are no other open appointment on the job)</li>\n<li>By completing a job directly via the Dispatch Manage Portal</li>\n</ul>\n<p>Therefore:</p>\n<ul>\n<li>If all you need to monitor is whether a job is complete or not then you should process this event</li>\n<li>If you want to track granularity at the appointment level then you should also process the appointment <code>complete</code> event (not required in most cases)</li>\n</ul>\n<p>Note:</p>\n<ul>\n<li>A follow up appointment can be created even after a job has been completed. If this happens another appointment <code>scheduled</code> event will be generated</li>\n</ul>\n<h2 id=\"job-paused\">Job Paused</h2>\n<ul>\n<li>Status: <code>paused</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the pause reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<p>This event is generated in the following circumstances:</p>\n<ul>\n<li>By completing an appointment as a \"no show\"</li>\n<li>By completing an appointment as \"waiting for parts\"</li>\n<li>Other pause events configured for your instance</li>\n</ul>\n<h2 id=\"job-canceled\">Job Canceled</h2>\n<ul>\n<li>Status: <code>canceled</code></li>\n<li>Additional processing recommended:<ul>\n<li>Retrieve the cancel reason from the <code>status_message</code></li>\n</ul>\n</li>\n</ul>\n<p>This event is emitted when a job is canceled. Therefore:</p>\n<ul>\n<li>If all you need to monitor is whether a job is canceled or not then you should subscribe to this event</li>\n<li>If you want to track granularity at the appointment level then you should also subscribe to the appointment <code>canceled</code> event (not required in most cases)</li>\n</ul>\n<h2 id=\"job-created\">Job Created</h2>\n<p>Sometimes jobs don't originate from you sending them directly to Dispatch. For example, if customers use a web page for requesting service those jobs could be sent to Dispatch. If you want to subscribe so that you can create them in your system then read on.</p>\n<p>This event is a little beefier than other events as it contains the details of the job which you presumably want to copy to your system.</p>\n<ul>\n<li>Status: <code>offered</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"job\": {\n                        \"id\": 30462,\n                        \"organization_id\": 11776,\n                        \"title\": \" Claim Details 206\",\n                        \"status\": \"offered\",\n                        \"status_message\": \"\",\n                        \"description\": \"some description\",\n                        \"updated_at\": \"2018-05-18T10:05:46+0000\",\n                        \"service_type\": \"air conditioning\",\n                        \"service_fee\": 0,\n                        \"address\": {\n                            \"street_1\": \"1755 Ridgeview Dr\",\n                            \"street_2\": \"\",\n                            \"postal_code\": \"76012\",\n                            \"city\": \"Arlington\",\n                            \"state\": \"TX\",\n                            \"country\": \"United States\",\n                            \"timezone\": \"America/Chicago\",\n                            \"latitude\": 32.7633905735029,\n                            \"longitude\": -97.1352367468659\n                        },\n                        \"external_ids\": [\n                            \"your_system_id\"\n                        ],\n                        \"customer\": {\n                            \"first_name\": \"James\",\n                            \"last_name\": \"Dodd\",\n                            \"company_name\": \"\",\n                            \"email\": \"devs+dodd@dispatch.me\",\n                            \"phone_number\": \"+15559803824\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"84abb1a8-8111-4319-abb0-12a4b27459b8"},{"name":"Appointment Related Events","id":"d41bfc46-4f70-4564-a869-a98003b7d9a1","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Appointment</em> events. These events are wrapped in an <code>appointment</code> element.</p>\n<p>These are the cases that should be monitored:</p>\n<ul>\n<li>Scheduled</li>\n<li>OMW</li>\n<li>Started</li>\n<li>Completed*</li>\n<li>Canceled*</li>\n</ul>\n<p>*Only if appointment granularity is required, otherwise you should track these with the corresponding job events.</p>\n<p>There is both a job <code>external_id</code> and appointment <code>external_id</code> in this payload. If you are monitoring the appointment level you should use the appointment reference otherwise it will be sufficient to use the job reference.</p>\n<p>Appointment events have the following basic payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"appointment\": {\n                        \"id\": 18663,\n                        \"status\": \"some_status\",\n                        \"job_id\": 30463,\n                        \"external_id\": your_system_id\",\n                        \"updated_at\": \"2018-05-18T10:08:38+0000\",\n                        \"start_time\": \"2018-05-19T15:00:00+0000\",\n                        \"end_time\": \"2018-05-19T16:00:00+0000\",\n                        \"job\": {\n                            \"external_id\": your_system_id\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"appointment-scheduled\">Appointment Scheduled</h2>\n<ul>\n<li>Status: <code>scheduled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-omw\">Appointment OMW</h2>\n<ul>\n<li>Status: <code>enroute</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-started\">Appointment Started</h2>\n<ul>\n<li>Status: <code>started</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-completed\">Appointment Completed</h2>\n<ul>\n<li>Status: <code>complete</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n<h2 id=\"appointment-canceled\">Appointment Canceled</h2>\n<ul>\n<li>Status: <code>canceled</code></li>\n<li>Additional processing recommended:<ul>\n<li>None</li>\n</ul>\n</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"d41bfc46-4f70-4564-a869-a98003b7d9a1"},{"name":"Notes & Attachment Events","id":"4d3156e9-0eba-43e2-9c19-42e8367a27a1","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for consuming <em>notes</em> and <em>attachment</em> events. These events are wrapped in an <code>attachment</code> element.</p>\n<p>Processing notes:</p>\n<ul>\n<li>The payloads for both of these events are very similar. The only difference is that a note will have a <code>description</code> attribute and an attachment will have a <code>file_token</code> element as you'll see in the examples below. Use this for your branch logic.</li>\n<li>It's possible for a note to get deleted or updated. Therefore it is recommended that you store the Dispatch note <code>id</code> so that it can be referenced later on. If the <code>deleted_at</code> is not null, it means the note has been deleted.</li>\n</ul>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"notes\">Notes</h2>\n<p>Note events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    {\n        \"Payload\": {\n            \"Actions\": [\n                {\n                    \"ID\": null,\n                    \"Put\": {\n                        \"attachment\": {\n                            \"id\": 3675,\n                            \"entity_type\": \"Job\",\n                            \"entity_id\": 30463,\n                            \"description\": \"some note\",\n                            \"updated_at\": \"2018-05-18T10:14:51+0000\",\n                            \"deleted_at\": null,\n                            \"job\": {\n                                \"external_id\": \"your_system_id\"\n                            }                            \n                        }\n                    }\n                }\n            ]\n        }\n    }\n\n</code></pre>\n<p>There's nothing more to it. Just pick up the <code>description</code> and process to your system.</p>\n<h2 id=\"attachment\">Attachment</h2>\n<p>Attachment events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"attachment\": {\n                        \"id\": 3676,\n                        \"entity_type\": \"Job\",\n                        \"entity_id\": 30463,\n                        \"file_token\": \"37f3cf22-f1c5-437c-a078-8608e25a0b2b\",\n                        \"name\": \"DispatchConnect.png\",\n                        \"updated_at\": \"2018-05-18T10:15:49+0000\",\n                        \"deleted_at: null,\n                        \"job\": {\n                             \"external_id\": \"your_system_id\"\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre><p>Please refer to <a href=\"https://playbooks.dispatch.me/?version=latest#f3f11bce-b781-4713-a09d-e8b8628fa9f7\">this section</a> for a write up on how to render the image using the retrieved file token.</p>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"4d3156e9-0eba-43e2-9c19-42e8367a27a1"},{"name":"Survey Events","id":"c8691bd0-732d-4e55-8e74-831cbd703377","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Survey</em> events. These events are wrapped in an <code>surveyresponse</code> element.</p>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"survey-submitted\">Survey Submitted</h2>\n<p>Survey events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    {\n        \"Payload\": {\n            \"Actions\": [\n                {\n                    \"ID\": null,\n                    \"Put\": {\n                        \"surveyresponse\": {\n                            \"account_message\": \"Average\",\n                            \"account_rating\": 3,\n                            \"id\": 4361,\n                            \"job_id\": 30459,\n                            \"message\": \"Great!\",\n                            \"rating\": 5,\n                            \"updated_at\": \"2018-05-18T10:57:10+0000\",\n                            \"job\": {\n                                \"external_id\": \"your_system_id\"\n                            }\n                        }\n                    }\n                }\n            ]\n        }\n    }\n\n</code></pre>\n<p>The survey <code>message</code> is broken up as follows:</p>\n<ul>\n<li>Text in [ ] are the \"Tell us why\" reasons</li>\n<li>The remainder are the \"additional comments\"</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"c8691bd0-732d-4e55-8e74-831cbd703377"}],"id":"517bb584-ad66-4a40-a3d9-756fc0aaeebe","description":"<h2 id=\"overview\">Overview</h2>\n<p>If you need to update your system based on updates made on the Dispatch platform then this section is for you! If you managed to successfully send a job to Dispatch then you will be able to <a href=\"https://www.screencast.com/t/uZ5DxiioftvJ\">sign in as a Dispatcher and Technician and work the job</a>.</p>\n<p>As a general rule, an event will only appear in the stream if it's something that originated from the Dispatch Platform. This means that we will not echo updates that originated in your system back to you!</p>\n<p><strong>And very importantly, please be sure to follow <a href=\"https://playbooks.dispatch.me/?version=latest#dispatch-outbound\">these Polling Design Best Practices</a></strong>  </p>\n<h2 id=\"event-summary\">Event Summary</h2>\n<p>This section lists the typical events that we think you should be monitoring (see this section for additional <a href=\"https://playbooks.dispatch.me/?version=latest#d3bae626-b827-45bf-a713-bdb25357011a\">Connect Use Cases</a>). If you encounter a case that you think is not covered, please reach out to us to review.</p>\n<ul>\n<li>Job<ul>\n<li>Job Completed: <code>job.complete</code> (with configurable reasons e.g. Ready for Billing)</li>\n<li>Job Paused: <code>job_paused</code> (with configurable reasons e.g. e.g. No Show, Waiting for Parts, Cannot Contact Customer)</li>\n<li>Job Canceled: <code>job.canceled</code> (with configurable reasons)</li>\n<li>Job Created: <code>job.offered</code> (only necessary when the jobs do not get sent directly from your system)</li>\n</ul>\n</li>\n<li>Appointment<ul>\n<li>Appointment Scheduled: <code>appointment.scheduled</code></li>\n<li>Technician OMW: <code>appointment.enroute</code></li>\n<li>Appointment Started: <code>appointment.started</code></li>\n<li>Appointment Complete: <code>appointment.complete</code> <em>(only if you need to track at the appointment level - usually sufficient to use <code>job.complete</code>)</em></li>\n<li>Appointment Canceled: <code>appointment.canceled</code> <em>(only if you need to track at the appointment level - usually sufficient to use <code>job.canceled</code>)</em></li>\n</ul>\n</li>\n<li>Survey<ul>\n<li>Submitted by Customer: <code>survey.submitted</code></li>\n</ul>\n</li>\n<li>Notes/Attachments<ul>\n<li>Note: <code>note</code></li>\n<li>Attachment: <code>attachment</code></li>\n</ul>\n</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"ce1b102a-29ae-4690-897f-6a388cd194b0","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"8cc04b65-241a-46e6-8f1e-dae6cfc535b6","type":"text/javascript","exec":[""]}}],"_postman_id":"517bb584-ad66-4a40-a3d9-756fc0aaeebe"}],"id":"ba5a53b2-8b99-4080-9ec1-ad085b5b7fe6","description":"<p>The scenarios described in this section are relevant if you're an enterprise who either:</p>\n<ul>\n<li>Employs an internal workforce for service fullfillment (e.g. W2)</li>\n<li>Receives a high degree of compliance from the field service organizations that will be fulfilling the work (for example, franchises often this kind of relationshp with their franchisees)</li>\n</ul>\n<p>We refer to this as our Field Service Management (FSM) vertical. </p>\n<p>Although - and this is important - Franchises come in many shapes and sizes and some Franchise business workflows may more closely model our DNM rather than WFM vertical. We will help you determine the best practice usage of Dispatch during the early stages of the project.</p>\n<p>The FSM connector requirements are similar to those of the Decentralized Network (DNM). The primary differences are in the following areas:</p>\n<p><strong>To Dispatch</strong></p>\n<ul>\n<li>Syncing of employee records - as an internal workforce is maintained, these need to be synced to Dispatch (create/update)</li>\n<li>Scheduling to an employee - in the WFM use case, you are often scheduling work directly to an employee from your source system. To accomodate, the job needs to include the appointment and assignment details. You should be able to schedule, reschedule, assign, re-assign, un-assign as necessary.</li>\n</ul>\n<p><strong>From Dispatch</strong></p>\n<ul>\n<li>Contractors have the luxury of determining whether they want to take on the work sent their way. As such, there is typically an \"accept\" or \"decline\" option available. In the WFM use case... not so much. Employees need to do the work that is sent their way. As such the aforementioned options are normally skipped and a job is immediately \"scheduled\" once it hits Dispatch</li>\n</ul>\n<p>The above is of course \"typical\". Your use case may vary and if so we'd love to hear how, so please do reach out.</p>\n","event":[{"listen":"prerequest","script":{"id":"93ad9f98-e558-47eb-aeab-7db4c40ed85f","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"85edd22c-3ae8-4ba2-8aeb-abf05367ca54","type":"text/javascript","exec":[""]}}],"_postman_id":"ba5a53b2-8b99-4080-9ec1-ad085b5b7fe6"},{"name":"Gateway","item":[{"name":"From Dispatch","item":[{"name":"Job Created","id":"52e3123a-a650-4faa-bdb1-5e2541110e73","request":{"method":"POST","header":[],"body":{"mode":"raw","raw":""},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<p>We call it a Job. You might call it a Work Order, Service Order or something else. Potato, potāto. Anyway, you will be receiving these from us. Jobs coming from the Dispatch Platform will have the following payload structure (this describes the core subset of fields that you will see in the actual payload):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">  {\n    \"Payload\": {\n      \"Actions\": [\n      {\n        \"ID\": null,\n        \"Put\": {\n          \"job\": {\n            \"id\": 30462,\n            \"source_id\": 123,\n            \"source\": \"American Pie\",\n            \"organization_id\": 11776,\n            \"organization_external_id\": \"enterprise_contractor_id\",\n            \"title\": \" Claim Details 206\",\n            \"status\": \"offered\",\n            \"status_message\": \"\",\n            \"description\": \"some description - used internally for rendering at Dispatch. We recommend you don't use this field\",\n            \"symptom\": \"some symptom at the job level if relevant\",\n            \"service_instructions\": \"some internal description\",\n            \"service_fee\": 130,\n            \"service_type\": \"air conditioning\",\n            \"updated_at\": \"2018-05-18T10:05:46+0000\",\n            \"address\": {\n              \"street_1\": \"1755 Ridgeview Dr\",\n              \"street_2\": \"\",\n              \"postal_code\": \"76012\",\n              \"city\": \"Arlington\",\n              \"state\": \"TX\",\n              \"country\": \"United States\",\n              \"timezone\": \"America/Chicago\",\n              \"latitude\": 32.7633905735029,\n              \"longitude\": -97.1352367468659\n            },\n            \"external_id\": \"enterprise_job_system_id\",\n            \"customer\": {\n              \"id\": 1234,\n              \"external_id\": \"enterprise_customer_system_id\",\n              \"first_name\": \"James\",\n              \"last_name\": \"Dodd\",\n              \"company_name\": \"\",\n              \"email\": \"devs+dodd@dispatch.me\",\n              \"phone_number\": \"+15559803824\"\n            },\n            \"equipment_descriptions\": [\n              {\n                \"manufacturer\": \"Acme\",\n                \"model_number\": \"500\",\n                \"model_name\": \"heater\",\n                \"serial_number\": \"01024\",\n                \"equipment_type\": \"hte\",\n                \"installation_date\": \"2017-10-21T00:00:00Z\",\n                \"location\": \"2nd floor\",\n                \"symptom\": \"ivr not working\",\n                \"custom_fields\": {\n                  \"field1\": \"may vary per brand\"\n                }\n              }\n            ],\n            \"custom_fields\": {\n              \"field1\": \"may vary per brand\"\n            },\n            \"marketing_attributions\": [\n              {\n                \"content\": \"bingo\",\n                \"campaign\": \"mamba\",\n                \"source\": \"orca\",\n                \"term\": \"glitter\",\n                \"media\": \"twitter\"\n              }\n            ],\n            \"ui_options\": {\n              \"show_decline\": true,\n              \"reject_reasons\": [\n                \"incorrect_service_area\",\n                \"no_availability\",\n                \"wrong_trade\"\n              ],\n              \"complete_reasons\": [\n                \"ready_for_billing\",\n                \"customer_does_not_want_service\"\n              ],\n              \"pause_reasons\": [\n                \"waiting_for_parts\",\n                \"no_show\",\n                \"waiting_on_authorization\"\n              ],              \n              \"cancel_reasons\": [\n                \"provider_canceled\",\n                \"customer_canceled\"\n              ]\n            }\n          }\n        }\n      }\n    ]\n  }\n}\n\n</code></pre>\n<p>Some important things to note:</p>\n<ul>\n<li>It is possible and perhaps even likely that not all data will be present. The elements that are populated might vary from Enterprise to Enterprise</li>\n<li>The <code>description</code> field contains markdown data which is used for rendering purposes on the Dispatch Platform. Which is why you may find that this field contains a lot of <code>#</code> and <code>\\*</code> characters and may not be all that friendly in its plain text format. Therefore as a general rule, we recommend that you <em>do not</em> use this field for integration - the values within it should be contained within the other discrete fields of the payload. If you do wish to use this field then we'd recommend that you either render this in a markdown enabled control on your end or <a href=\"https://www.npmjs.com/package/remove-markdown\">remove the markdown text</a> to make it easier to read. Please do not parse this field for specific data as there is no guarantee that the structure of this description text will change in future iterations potentially breaking your integration.</li>\n<li>Brands typically send us customer names in all sorts of formats. For example it's not uncommon to see a customer name of \"Davie &amp; Bettie\" come over or just see the first name populated and not the last name. To this end, we'd recommend that you use one or a combination of the following when mapping to your system in order to prevent duplicates:<ul>\n<li>customer email</li>\n<li>customer phone</li>\n<li>customer ID coming from Dispatch</li>\n</ul>\n</li>\n<li>The <code>ui_options</code> key contains reason codes that are offered on the front end when certain actions are taken. These will vary per brand. These are fed back through to the brand for visibility. Therefore it is highly recommended that you pick these up and incorporate into your flow. This includes:<ul>\n<li><code>show_decline</code> - if <code>true</code> then the contractor can \"decline\" or \"reject\" the job that they have been offered</li>\n<li><code>reject_reasons</code> - only relevant if <code>show_decline</code> is set. Contains the list of reasons codes that the user can select from when rejecting/declining</li>\n<li><code>complete_reasons</code> - list of reasons the user can select from when a job is being completed</li>\n<li><code>pause_reasons</code> - list of reasons the user can select from when when a job is being paused or placed on hold</li>\n<li><code>cancel_reasons</code> - list of reasons the user can select from when canceling a job</li>\n</ul>\n</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"52e3123a-a650-4faa-bdb1-5e2541110e73"},{"name":"Job Canceled","id":"d5d9c280-7a8f-4d4e-9c46-9b3af2cbc7bd","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<p>If an enterprise cancels a job it will come over with the following structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": null,\n                \"Put\": {\n                    \"job\": {\n                        \"id\": 30462,\n                        \"status\": \"canceled\",\n                        \"status_message\": \"\",\n                        \"updated_at\": \"2018-05-18T10:05:46+0000\",\n                        \"external_id\": enterprise_job_system_id\"\n                        ]\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<p>It is up to you to decide whether and how to handle this event (or if you want to ignore entirely let us know so we can turn off).</p>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"d5d9c280-7a8f-4d4e-9c46-9b3af2cbc7bd"}],"id":"73c9ef8a-8b32-4a3f-b598-b84b21a95112","description":"<h2 id=\"overview\">Overview</h2>\n<p>This section documents the following use cases:</p>\n<ul>\n<li><p>Receive jobs from Dispatch</p>\n</li>\n<li><p>Job cancelations from Dispatch</p>\n</li>\n</ul>\n<h2 id=\"design-considerations\">Design Considerations</h2>\n<p><strong>Very importantly, please be sure to follow</strong> <a href=\"https://playbooks.dispatch.me/?version=latest#dispatch-outbound\"><b>these Polling Design Best Practices</b></a> (if you plan to use the polling strategy)</p>\n","event":[{"listen":"prerequest","script":{"id":"8d13775e-aa1a-4a2a-b4b4-4d8a909d3b51","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"b504eccb-88b3-4d6d-a274-e36036afb880","type":"text/javascript","exec":[""]}}],"_postman_id":"73c9ef8a-8b32-4a3f-b598-b84b21a95112"},{"name":"To Dispatch","item":[{"name":"Job","id":"a99ddffe-00b1-4491-9d88-6781c2cd8014","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>When you send through a status update send over the following:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    [{\n        \"header\": {\n            \"record_type\": \"job\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"id\": 555,\n            \"organization_id\": \"the value you received from Dispatch\",\n            \"source_id\": \"the value you received from Dispatch\",\n            \"status\": \"see status list below\",\n            \"status_message\": \"optional reason for status\",\n            \"resolution\": \"optional resolution text\",\n            \"pause_description\": \"optional additional message when pausing job\"\n        }\n    }]\n\n</code></pre>\n<p>Please try to map the <code>status</code> to one of the following values:</p>\n<ul>\n<li><p><strong>unscheduled</strong> - job is accepted by Service Provider</p>\n</li>\n<li><p>rejected - job is rejected by Service Provider</p>\n</li>\n<li><p><strong>scheduled</strong> (to indicate \"arrived on site\" or \"enroute\" - see below for processing logic of this status)</p>\n</li>\n<li><p><strong>complete</strong></p>\n</li>\n<li><p>paused (to indicate that the job is on hold - see below for an example)</p>\n</li>\n<li><p>canceled</p>\n</li>\n</ul>\n<p>Values in the list above appearing in bold are the critical job milestone statuses that should be sent over to make the connector effort valuable. The others are optional (but definitely recommended if you have them).</p>\n<p>Use the <code>status_message</code> if you want to pass in a reason code. For example, you might send through a <code>complete</code> status with a reason of \"Customer No Show\".</p>\n<p>To report that the technician is enroute set the following:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n    \"status\": \"scheduled\",\n    \"status_message\": \"enroute\"\n}\n\n</code></pre><p>To report that the technician has arrived on site set the following:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n    \"status\": \"scheduled\",\n    \"status_message\": \"started\"\n}\n\n</code></pre><p>To report that you tried to contact the custom set the following:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{\n    \"status\": \"paused\",\n    \"status_message\": \"cannot_contact_customer\",\n    \"pause_description\": \"optional wordier description\"\n}\n\n</code></pre>","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"a99ddffe-00b1-4491-9d88-6781c2cd8014"},{"name":"Appointment","id":"71a80de4-cbe4-4b76-b9d6-4275741e8a45","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>When you schedule or reschedule an appointment send over the following:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    [{\n        \"header\": {\n            \"record_type\": \"appointment\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"organization_id\": \"the value you received from Dispatch\",\n            \"source_id\": \"the value you received from Dispatch\",\n            \"status\": \"scheduled\",\n            \"time\": \"2018-10-30T22:00:00.000Z\",\n            \"duration\": 14400,\n            \"job_id\": 555,\n            \"external_id\": \"your_unique_id\",\n            \"reschedule_reminder\": true\n        }\n    }]\n\n</code></pre>\n<p>Where:</p>\n<ul>\n<li><p><code>time</code> - this is the scheduled start window of the appointment</p>\n</li>\n<li><p><code>duration</code> - this is the duration of the appointment window in <strong>seconds</strong></p>\n</li>\n<li><p><code>external_id</code> - our jobs can have multiple appointments so please include your unique ID so we can know which one to update. If you only have a single appointment per job and you're not sure which value to use you can just repeat the value in the <code>job_id</code> over here.</p>\n</li>\n<li><p><code>reschedule_reminder</code> - (optional) please note that when you reschedule an appointment, a notification will not automatically be sent through to the brand. This is because rescheduling can be a very frequent event which can result in \"spamming\" the brand with updates. Therefore we require a specific indication that you want this update to be reflected and you can use this to do so.</p>\n</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"71a80de4-cbe4-4b76-b9d6-4275741e8a45"},{"name":"Notes","id":"ede42514-37bf-4357-b61d-f02e6e9084a8","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>This is an optional but recommended update. You should only send through notes that are <strong>brand facing</strong>.</p>\n<p>When you send through notes please send the following structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    [{\n        \"header\": {\n            \"record_type\": \"attachment\",\n            \"version\": \"v3\"\n        },\n        \"record\": {\n            \"organization_id\": \"the value you received from Dispatch\",\n            \"job_id\": 555,\n            \"external_id\": \"your unique id\",\n            \"description\": \"some note\"\n        }\n    }]\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"ede42514-37bf-4357-b61d-f02e6e9084a8"},{"name":"Attachments","id":"c9b87ed0-02ba-42f1-b543-98ab3beb474c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","name":"Content-Type","type":"text","value":"application/json"}],"body":{"mode":"raw","raw":"","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>This is an optional but recommended update. You should only send through attachments that are <strong>brand facing</strong>.</p>\n<p>When you send through attachments please send the following structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    [{\n            \"header\": {\n                \"record_type\": \"attachment\",\n                \"version\": \"v3\"\n            },\n            \"record\": {\n                \"organization_id\": \"the value you received from Dispatch\",\n                \"job_id\": 555,\n                \"external_id\": \"your unique id\",\n                \"file\": \"base64encodedstring\",\n                \"name\": \"your_file_name.jpg\"\n            }\n    }]\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"c9b87ed0-02ba-42f1-b543-98ab3beb474c"}],"id":"7cd77dce-27bc-403b-a7fa-eb20b306af25","description":"<p>Updates you send back to Dispatch will be sent back through to the Enterprise. This section describes the updates that we are looking to receive. Though we encourage sending over all updates you deem relevant, the following is the recommended minimum set of updates:</p>\n<ol>\n<li><p>Acceptance - assuming you have an acceptance step</p>\n</li>\n<li><p>Schedule</p>\n</li>\n<li><p>Complete</p>\n</li>\n<li><p>Notes - It would be also be very beneficial to receive notes too.</p>\n</li>\n</ol>\n<p><strong>We would strongly recommend that you send us all relevant job related statuses (and brand facing notes if relevant) that your system generates. If you do so, we will provide you with the exact payload to send over for each of those use cases.</strong> To help guide you, think about categorizing your statuses into the following general \"family\" of statuses:</p>\n<ul>\n<li><p>Not Yet Scheduled (e.g. accepted, pending)</p>\n</li>\n<li><p>Schedule Change (e.g. schedule, re-schedule)</p>\n</li>\n<li><p>Work In Progress (e.g. OMW, started)</p>\n</li>\n<li><p>Hold Status (e.g. follow up, waiting for parts, request auth, no show)</p>\n</li>\n<li><p>Completed (e.g. work complete, customer canceled)</p>\n</li>\n</ul>\n<p>Please note that if you are set up to use a <strong>single</strong> set of API credentials to send updates then please include the following in your http header:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>RecordType: gatway\n\n</code></pre>","event":[{"listen":"prerequest","script":{"id":"4cdf92fa-026e-4b15-b17b-f4906b2c7265","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"22b50d66-229e-4525-9b86-d56cf3c04729","type":"text/javascript","exec":[""]}}],"_postman_id":"7cd77dce-27bc-403b-a7fa-eb20b306af25"},{"name":"FAQs","item":[{"name":"Onboarding & offboarding","item":[{"name":"Onboarding","id":"acd04cff-c72b-43d3-8a2e-a1f068a33438","request":{"method":"POST","header":[{"key":"RecordType","value":"gateway_provision","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"external_organization_id\": \"your_unique_service_provider_id\",\n    \"name\": \"best hvac\",\n    \"api_creds\": {\n        \"api_key\": \"include_api_key_if_relevant\",\n        \"other_api_details\": \"include_any_other_api_info_required_for_authenticating_to_your_product\"\n    },\n    \"email\": \"best@hvac.org\",\n    \"phone_number\": \"555-123-4123\",\n    \"address\": {\n        \"street\": \"4705 Smith Ave\",\n        \"street_line_2\": null,\n        \"city\": \"Philadelphia\",\n        \"state\": \"PA\",\n        \"country\": \"US\"\n    },\n    \"app_id\": \"app_id_dispatch_will_provide\"\n}","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Send this over to Dispatch when you want to connect a provider. This will notify Dispatch... who will then subsequently match it up with the appropriate provider on the Dispatch platform. In the event that Dispatch is unable to perform a match with the details provided, our team will reach out to yours for additional information.</p>\n<p>In the event you want Dispatch to notify your system upon successful activation, you will need to provide Dispatch with an endpoint to do so. If we do, the payload we send back will contain the following (if you want to include additional data elements let us know):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"external_organization_id\": \"your_provider_id\",\n    \"organization_id\": \"the_matched_dispatch_id\"\n}\n\n</code></pre>\n<p>Additional notes:</p>\n<ul>\n<li><p>Required attributes</p>\n<ul>\n<li><p><code>external_organization_id</code> - this is the ID for the provider in your system</p>\n</li>\n<li><p><code>name</code></p>\n</li>\n</ul>\n</li>\n<li><p>Include an http header <code>RecordType: gateway_provision</code></p>\n</li>\n<li><p>You should include as much identifying detail as possible but at a minimum either:</p>\n<ul>\n<li><p>email</p>\n</li>\n<li><p>phone_number</p>\n</li>\n<li><p>address.state</p>\n</li>\n</ul>\n</li>\n<li><p>The <code>app_id</code> is a constant value that we will provide to you (likely the name of your company)</p>\n</li>\n<li><p>In the API creds - pass in whatever information is needed to authenticate to your API (in the event you want us to perform this step)</p>\n</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"acd04cff-c72b-43d3-8a2e-a1f068a33438"},{"name":"Offboarding","id":"a47cf87f-e918-4e88-8ffa-7ad84997b893","request":{"method":"POST","header":[{"key":"RecordType","value":"gateway_deprovision","type":"text"}],"body":{"mode":"raw","raw":"{\n    \"external_organization_id\": \"your_unique_service_provider_id\",\n    \"organization_id\": 123,\n    \"app_id\": \"app_id_dispatch_will_provide\"\n}","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>In the event you want to offboard a previously onboarded provider, you will need to send over this payload.</p>\n<p>Additional notes:</p>\n<ul>\n<li><p>The <code>organization_id</code> is the dispatch Provider ID included in what we sent back to you using your endpoint (in the event you're doing this step). So you'll need to store this somewhere in your system.</p>\n</li>\n<li><p>Include an http header <code>RecordType: gateway_deprovision</code></p>\n</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"a47cf87f-e918-4e88-8ffa-7ad84997b893"}],"id":"acbba8fe-8962-47a2-bf2a-21573419f9ee","description":"<p>What is the processing of onboarding a new service provider on the Dispatch Gateway?</p>\n<p>First of all, we'd recommend that we walk before we run. That is, let's get an MVP gateway integration set up with Dispatch before worrying about how to streamline the onboarding process. The process should be iterative. Also we should consider the need for optimizing the onboarding (and potentially offboarding) in lieu of how many service providers we realistically anticipate coming on board.</p>\n<p>With that said, while the onboarding processing can be streamlined, the process by necessity requires some human input. This is because Dispatch has thousands of service providers on its platform and we need to be sure that we match the correct service provider on our platform with the one on yours. There is no magic bullet here as there's no guarantee that the address, email, contact info that we have will be the same as yours.</p>\n<p>That said, the good news is that the effort for this matching will likely fall on Dispatch's side. To this end, if you're interested in streamlining this process the following is the process we recommend:</p>\n<ul>\n<li><p>Add a process in your app where a user can request connecting with Dispatch</p>\n</li>\n<li><p>When they do so, post the \"onboarding\" payload</p>\n</li>\n<li><p>Dispatch will receive this request, do the validation, and then set this up (at which point they are connected). This typically takes a few hours or less.</p>\n</li>\n<li><p>If you want verfication that the connection has taken place, you will need to provide Dispatch with an endpoint that we can hit for this.</p>\n</li>\n<li><p>For offboarding, send a request to the same endpoint per the \"offboarding\" payload (this update will take effect immediately)</p>\n</li>\n</ul>\n<p><strong>Please also note that the onboarding and offboarding payloads require a special set of \"application keys\" that we will provide to you (only applicable for these payloads).</strong></p>\n","_postman_id":"acbba8fe-8962-47a2-bf2a-21573419f9ee"},{"name":"Do updates get sent to all brands?","item":[],"id":"f0738b44-1f21-4638-bf43-6563447fce99","description":"<p>The short answer is yes. Once you're connected with Dispatch your updates will go to whichever brand is consuming the data, including new ones who have yet to be connected to Dispatch!</p>\n","_postman_id":"f0738b44-1f21-4638-bf43-6563447fce99"},{"name":"How do we know which brand source the job is for?","item":[],"id":"f0ac4617-cecf-4042-82f2-119c4d1f5303","description":"<p>The payload includes a <code>source_id</code> and <code>source</code> field. We'd recommend using the <code>source_id</code> field as that is more reliable and will not change. Dispatch can provide you the source IDs of the sources you are interested in upon request.</p>\n","_postman_id":"f0ac4617-cecf-4042-82f2-119c4d1f5303"},{"name":"How can a new service provider start receiving jobs from a brand?","item":[],"id":"e689b3b5-8517-4996-927a-1b0c1a709fcc","description":"<p>That is entirely between the brand and the service provider! In other words, the service provider should reach out to the brand if they're interested in performing work for them. Dispatch is not involved in that conversation. Once that service provider has been set up, then jobs they receive will begin arriving on the Dispatch platform (obviously provided that the brand is integrated with Dispatch).</p>\n","_postman_id":"e689b3b5-8517-4996-927a-1b0c1a709fcc"},{"name":"Syncing technicians","item":[],"id":"ac4bd85d-9dc6-4e77-8c23-4f8d060d7ba0","description":"<p>We are some times asked whether the assigned technician can be synced to Dispatch. The short answer is no. The following is the explanation in case you're interested in understanding the reasons for this (if not, just skip):</p>\n<blockquote>\n<p>First of all, it should be mentioned that brands typically don't care who performed the work (which technician). They just need to know which subcontractor organization is doing the work and visibility into that work. And the gateway integration gives them this visibility. </p>\n</blockquote>\n<blockquote>\n<p>Secondly, syncing techs for enroute events would send out the the default \"on my way\" notification to the customer who is then able to track their arrival. However, when the technician is not using the Dispatch mobile app (which is typically the case as they're using the <em>your</em> mobile app, the customer will not be able to do this tracking which can negatively impact that experience. </p>\n</blockquote>\n<blockquote>\n<p>Finally, on a more technical note, technician assignment requires syncing over the technician records from your system to Dispatch and ongoing maintenance of those records (create/update/deactivate). This would add considerable complexity to the integration as it would, by its very nature, involve a lot more moving parts. </p>\n</blockquote>\n<p>Having said all that, if you know the brand is interested in knowing which technician was assigned (the only reason to justify such a sync would be for brand visibility), please let us know which brand is requesting this so we can understand the business reason behind this and perhaps we can come up with a creative solution!</p>\n","_postman_id":"ac4bd85d-9dc6-4e77-8c23-4f8d060d7ba0"},{"name":"Round Robin and Jump Ball","item":[],"id":"10084c6a-a2d6-4900-a592-2a4f38e171b1","description":"<p>Some jobs are created via an offer strategy called <em>Round Robin</em> and <em>Jump Ball.</em> Both involve sending the job out for to multiple service providers and only one of those will ultimately service the job. For both of these cases, it is necessary for the service provider to <strong>accept</strong> the job in order to <strong>win</strong> it. And therefore we cannot send these type jobs to the gateway app until it has been accepted or otherwise that would constitute an unfair advantage for gateway connected organizations.</p>\n<p><strong>TLDR: Round Robin and Jump Ball jobs must be accepted in the Dispatch app before they will flow to the gateway app.</strong></p>\n<p>That's really all you need to know but if interested here is a description of these 2 strategies.</p>\n<ul>\n<li><p>Round Robin <strong>-</strong> Job is offered to service providers in sequence and is often time bound before it expires. If that job expires or is rejected it will go to the next service provider in the list.</p>\n</li>\n<li><p>Jump Ball <strong>-</strong> Job is offered to all service providers at once and whoever accepts first wins the job.</p>\n</li>\n</ul>\n","_postman_id":"10084c6a-a2d6-4900-a592-2a4f38e171b1"}],"id":"a171e86c-856e-40c9-954c-00fe29cec07c","_postman_id":"a171e86c-856e-40c9-954c-00fe29cec07c","description":""}],"id":"c406b8ad-fda5-434b-a45a-93b9b88643bf","description":"<p>The scenarios in this section are relevant to you if you offer a BMS (Business Management Solution) field service product solution and you wish to receive jobs and send updates via the Dispatch Platform.</p>\n<p>The standard flow for this use case is depicted as follows:</p>\n<img src=\"https://raw.githubusercontent.com/Nahis/dispatchme/master/gateway_overview.jpg\" alt=\"Gateway Overview\" />\n\n<ol>\n<li><p>Enterprise sends a job to Dispatch</p>\n</li>\n<li><p>You pick this job up <a href=\"https://playbooks.dispatch.me/?version=latest#73c9ef8a-8b32-4a3f-b598-b84b21a95112\">from Dispatch</a> and process into your system (either via polling or webhook)</p>\n</li>\n<li><p>You send through updates <a href=\"https://playbooks.dispatch.me/?version=latest#7cd77dce-27bc-403b-a7fa-eb20b306af25\">to Dispatch</a> which typically include:</p>\n<ul>\n<li><p>Milestone status e.g. accept, scheduled, complete</p>\n</li>\n<li><p>Notes</p>\n</li>\n</ul>\n</li>\n</ol>\n<p>The exception flow for this use case is as follows:</p>\n<ol>\n<li><p>Enterprise sends through a cancelation</p>\n</li>\n<li><p>You send through a cancelation</p>\n</li>\n</ol>\n<p><strong>Whether you choose to implement all are part of these use cases (or beyond) is up to you.</strong></p>\n<p>In addition to the code samples, we've also provided some <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/GatewayUsageExample\">code examples that you can use to draw inspiration from</a>. You'll have to adapt this to the way that your APIs work in your system but these should show some of the thinking that will need to be applied as your build the integration.</p>\n<p>We have also provided a <a href=\"https://docs.google.com/spreadsheets/d/1IvRFx9pDVnIfdBMIIPwGSc98YFmYjCMtyMxxICJnxCo/edit?usp=sharing\">UAT test script</a> that you can use to test the connector (we will have discussed the various scenarios mentioned in this script such that it will be clear which ones are relevant to your use case).</p>\n<p>What is the processing of onboarding a new service provider on the Dispatch Gateway?</p>\n<p>First of all, we'd recommend that we walk before we run. That is, let's get an MVP gateway integration set up with Dispatch before worrying about how to streamline the onboarding process. The process should be iterative. Also we should consider the need for optimizing the onboarding (and potentially offboarding) in lieu of how many service providers we realistically anticipate coming on board.</p>\n<p>With that preamble out of the way, while the onboarding processing can be streamlined, the process by necessity requires some human input. This is because Dispatch has thousands of service providers on its platform and we need to be sure that we match the correct service provider on our platform with the one on yours. There is no magic bullet here as there's no guarantee that the address, email, contact info that we have will be the same as yours.</p>\n<p>That said, the good news is that the effort for this matching will likely fall on Dispatch's side. To this end, if you're interested in streamlining this process the following is the process we recommend:</p>\n<ul>\n<li><p>Add a process in your app where a user can request connecting with Dispatch</p>\n</li>\n<li><p>When they do so, fire off a json webhook that will include the org name, address, and contact info (Dispatch will tell you which endpoint to send this to)</p>\n</li>\n<li><p>Dispatch will receive this request, do the validation, and then set this up (at which point they are connected). This typically takes a few hours or less.</p>\n</li>\n<li><p>If you want verfication that the connection has taken place, you will need to provide Dispatch with an endpoint that we can hit for this.</p>\n</li>\n<li><p>For offboarding, you can similarly send a request to the same endpoint (this update will take effect immediately)</p>\n</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"0840ff3e-d8c8-4106-b647-911929d00dae","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"a873ea78-7efc-41d9-943d-c6eeb59e0dbb","type":"text/javascript","exec":[""]}}],"_postman_id":"c406b8ad-fda5-434b-a45a-93b9b88643bf"}],"id":"1bb09714-ff37-4ae4-961d-1c0000ea1ef3","event":[{"listen":"prerequest","script":{"id":"3dd42158-31ed-4c26-b590-fb92c08cdd82","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"3bc137fd-6b24-47ac-854b-9fa1f70364ae","type":"text/javascript","exec":[""]}}],"_postman_id":"1bb09714-ff37-4ae4-961d-1c0000ea1ef3","description":""},{"name":"Use Cases","item":[{"name":"To Dispatch","item":[{"name":"Appointments","item":[{"name":"Appointment Type","id":"446f139f-a8b6-40ee-9d5b-0903c9ac0ce5","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"appointment_type\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"name\": \"your name\",\n            \"is_default\": false,\n            \"default_duration_seconds\": 7200\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Add your company’s appointment types. When you create aan appointment, you’ll be able specify a type from this list. The only required attribute is the <code>name</code>.</p>\n<p>You can also specify a default duration for the appointment which is relevant if your users can create appointments using the Dispatch front end.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"446f139f-a8b6-40ee-9d5b-0903c9ac0ce5"}],"id":"525da6e7-f643-48e3-8f4b-bfe7f93b8466","event":[{"listen":"prerequest","script":{"id":"83a86be5-3e5d-449a-ab03-719c36608f4e","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"4abc03ca-7dda-4135-8498-224bc5e9b27e","type":"text/javascript","exec":[""]}}],"_postman_id":"525da6e7-f643-48e3-8f4b-bfe7f93b8466","description":""},{"name":"Auto Assign","item":[{"name":"Auto Assign Technician","id":"071da253-b7f7-4383-9b78-6c88fc8ef989","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","name":"Content-Type","type":"text","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"auto_assign_technician\",\r\n            \"version\": \"v3\"\r\n        },\r\n        \"record\": {\r\n            \"external_id\": \"your_enterprise_job_id\",\r\n            \"external_appointment_id\": \"your_enterprise_job_or_appointment_id\",\r\n            \"external_technician_ids\": [\r\n                \"your_user_id1\",\r\n                \"your_user_id2\"\r\n            ],\r\n            \"external_secondary_technician_ids\": [\r\n                \"your_user_id3\",\r\n                \"your_user_id4\"\r\n            ],\r\n            \"appointment_duration_minutes\": 60,\r\n            \"address\": {\r\n                \"street_1\": \"3913 Ford Street\",\r\n                \"city\": \"Revere\",\r\n                \"state\": \"MA\",\r\n                \"postal_code\": \"02151\"\r\n            },\r\n            \"postal_code\": \"02151\",\r\n            \"availability_start_time\": \"2018-05-18T10:00:00+0000\",\r\n            \"availability_end_time\": \"2018-05-18T14:00:00+0000\",\r\n            \"override_availability\": false,\r\n            \"two_tech\": false\r\n        }\r\n    }\r\n]","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>If you want to leverage auto technician assignment via the Dispatch Match algoritm, you should include this record. Also note, that auto assignment might fail in which case, you will be informed about this via <a href=\"#fde46862-b2ec-4017-abb1-acf7bd42adce\">this outbound event</a>.</p>\n<ul>\n<li><code>address</code> - should match that of the job you're trying to schedule</li>\n<li><code>postal_code</code> - should match that of the job you're trying to schedule</li>\n<li><code>two_techs</code> - if set to false only the primary technician IDs are checked for auto-assignment otherwise both primary and secondary technicians are checked.</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"071da253-b7f7-4383-9b78-6c88fc8ef989"},{"name":"Auto Assign Org","id":"bb712486-b01c-4806-8dab-256f15490fd4","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","name":"Content-Type","type":"text","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"auto_assign_org\",\r\n            \"version\": \"v3\"\r\n        },\r\n        \"record\": {\r\n            \"include_linked_orgs\": true,\r\n            \"trades\": [\r\n                \"Trade 1\"\r\n            ],\r\n            \"postal_code\": \"02151\"\r\n        }\r\n    }\r\n]","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>If you want to leverage auto org assignment via the Dispatch Match algoritm, you should include this record. Also note, that auto assignment might fail in which case, you will be informed about this via <a href=\"#439dea2b-6cae-4d1f-9464-3bbda42ace0d\">this outbound event</a>.</p>\n<ul>\n<li><code>trades</code> - This should match the trades passed into the offer. If you don't pass this in, the match won't filter by trade.</li>\n<li><code>postal_code</code> - This should match the postal code you included on the job.</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"bb712486-b01c-4806-8dab-256f15490fd4"}],"id":"4eb36f42-1a33-4d1d-9f94-506e3176e472","event":[{"listen":"prerequest","script":{"id":"3b80ec18-4908-4275-a36e-eba7971ad524","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"a88c5a82-f33a-4605-ab10-afca3b216a74","type":"text/javascript","exec":[""]}}],"_postman_id":"4eb36f42-1a33-4d1d-9f94-506e3176e472","description":""},{"name":"Billing","item":[{"name":"Billing Items (Product Catalog)","id":"251a6ca2-7eb7-4255-98b0-e21864069022","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[{\r\n\t\"header\": {\r\n\t\t\"record_type\": \"billing_item\",\r\n\t\t\"version\": \"v2\"\r\n\t},\r\n\t\"record\": {\r\n\t  \"title\" : \"Widget\",\r\n\t  \"item_type\" : \"service\",\r\n\t  \"description\" : \"Widget Description\",\r\n\t  \"external_id\": \"your_catalog_id\",\t  \r\n\t  \"external_organization_id\": \"your_organization_id\",\r\n\t  \"price\" : 200,\r\n\t  \"sku\" : \"widget\",\r\n\t  \"active\": true,\r\n      \"trades\": [\"Trade 1\", \"Trade 2\"],\r\n      \"price_locked\": false\r\n\t }\r\n}]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Every <em>Line Item</em> used on a <em>Billing Document</em> (Estimate/Invoice) must be linked to a master <em>product catalog</em> item (or <em>Billing Item</em>).</p>\n<p>Therefore you should either create these on the fly as you create your estimates and invoices (as shown in the example in the section for \"Billing Documents\") or you can create these as a separate integration thread as shown here.</p>\n<p>If you provide a trade list linked to the billing items, it will restrict the use of the billing items to those trades.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"251a6ca2-7eb7-4255-98b0-e21864069022"},{"name":"Billing Documents","id":"367ae5dd-53b8-4f2c-bd64-1bbba8145dfc","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n{\r\n\t\"header\": {\r\n\t\t\"record_type\": \"billing_item\",\r\n\t\t\"version\": \"v2\"\r\n\t},\r\n\t\"record\": {\r\n\t  \"title\" : \"Line 1\",\r\n\t  \"item_type\" : \"service\",\r\n\t  \"external_id\": \"your_catalog_id_1\",\r\n\t  \"external_organization_id\": \"your_organization_id\"\r\n\t }\r\n},\r\n{\r\n\t\"header\": {\r\n\t\t\"record_type\": \"billing_item\",\r\n\t\t\"version\": \"v2\"\r\n\t},\r\n\t\"record\": {\r\n\t  \"title\" : \"Line 2\",\r\n\t  \"item_type\" : \"service\",\r\n\t  \"external_id\": \"your_catalog_id_2\",\t  \r\n\t  \"external_organization_id\": \"your_organization_id\"\r\n\t }\r\n},\r\n{\r\n\t\"header\": {\r\n\t\t\"record_type\": \"billing_document\",\r\n\t\t\"version\": \"v2\"\r\n\t},\r\n\t\"record\": {\r\n\t  \"external_id\": \"your_document_id\",\r\n\t  \"external_job_id\" : \"your_job_id\",\r\n\t  \"external_organization_id\": \"your_organization_id\",\r\n      \"external_customer_id\": \"your_customer_id\",\r\n      \"customer\": {\r\n        \"full_name\": \"John Doe\",\r\n        \"address\": {\r\n          \"city\": \"Portland\",\r\n          \"state\": \"OR\",\r\n          \"country\": \"United States\",\r\n          \"street_1\": \"33400 NE 24th Ave.\",\r\n          \"postal_code\": \"33400\"\r\n        }\r\n      },\t  \r\n\t  \"doc_type\" : \"Estimate\",\r\n\t  \"title\": \"Billing Document Title\",\r\n\t  \"description\" : \"Billing Document Description\",\r\n\t  \"discount_amount\": 10,\r\n\t  \"lines\" : [\r\n\t    {\r\n\t      \"external_billing_item_id\": \"your_catalog_id_1\",\r\n\t      \"title\" : \"Line 1\",\r\n\t      \"description\" : \"Line 1 Description\",\r\n\t      \"qty\" : 10,\r\n\t      \"price\" : 1.00,\r\n\t      \"taxable\": false\r\n\t    },\r\n\t    {\r\n\t      \"external_billing_item_id\": \"your_catalog_id_2\",\r\n\t      \"title\" : \"Line 2\",\r\n\t      \"description\" : \"Line 2 Description\",\r\n\t      \"qty\" : 10,\r\n\t      \"price\" : 2.00,\r\n\t      \"taxable\": false\r\n\t    }\r\n\t ]\r\n\t}\r\n}\r\n]\t"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>A Billing Document must be attached to an existing <em>job</em>. And each <code>line</code> of the Billing Document must be linked to a valid <em>Product Catalog</em> or <em>Billing Item</em>.</p>\n<p>You should pay special attention to the following:</p>\n<ul>\n<li>the example shown here illustrates the product catalog items being created \"on the fly\" with the billing document being created. These can also be created separately in advance as shown in the \"product catolog\" section</li>\n<li>billing documents can also be created at the same time the job is created by passing in the billing sections into the json array after the section containing the json for the job</li>\n<li><code>status</code> - Make sure you map this appropriately - the valid values are described in the intro</li>\n<li><code>skip_customer_signature</code> - If you are passing a value of <code>won</code> (for an <em>Estimate</em>) or <code>balance_outstanding</code> (for an <em>Invoice</em>) you will need to set this to true as you are circumventing the signature capture form on the front end.</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"367ae5dd-53b8-4f2c-bd64-1bbba8145dfc"}],"id":"cce93017-10c3-4163-81b8-f63c6a9ed8a3","description":"<p>In Dispatch we refer to both <em>Estimates</em> and <em>Invoices</em> as <strong>Billing Documents</strong>. This is because Estimates and Invoices are two sides of the same coin and are structurely very similar. We differentiate between them use the <code>doc_type</code> attribute on the Billing Document.</p>\n<p>A Billing Document consists of a header and details section:</p>\n<ul>\n<li>Header - this contains standard billing information such as the document number and customer info.</li>\n<li>Details - The details consists of one or more \"line items\". The line item is essentially a <code>product</code> or <code>service</code> that you are selling and every line item must be linked to a master \"billing item\".</li>\n</ul>\n<p>To illustrate the difference between a <em>line item</em> and <em>billing item</em> consider the following:</p>\n<ul>\n<li>You sell <em>hammers</em> - so you add <em>hammer</em> to your product catalog and put them in your inventory. We refer to the product catalog as <strong>billing items</strong> and you can think of this as your <em>product definition</em>.</li>\n<li>From now on you can add <em>hammers</em> as line items to your billing documents. In other words the <strong>line item</strong> is your <em>product instance</em>.</li>\n</ul>\n<p>The typical flow for billing documents is as follows:</p>\n<ul>\n<li>Estimate: draft ==&gt; sent ==&gt; won/lost</li>\n<li>When an estimate is <em>won</em> a corresponding Invoice is created</li>\n<li>Invoice: draft ==&gt; sent ==&gt; balance_outstanding ==&gt; paid </li>\n<li>An invoice can be created without first starting out as estimate</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"37a33c79-92f2-4fb3-b68d-981504fbac4f","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"9e78017a-a049-4724-b6e6-bab22e79ec3b","type":"text/javascript","exec":[""]}}],"_postman_id":"cce93017-10c3-4163-81b8-f63c6a9ed8a3"},{"name":"Calendar Events","item":[{"name":"Calendar Event","id":"b1adc76d-6c86-45cc-aa51-9aed5311a1a6","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"calendar_event\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_external_id\",\n            \"start_time\": \"2019-10-21T08:30:00Z\",\n            \"duration\": 3600,\n            \"title\": \"Lunch\",\n            \"description\": \"Lunch time\",\n            \"external_organization_id\": \"your_external_org_id\",\n            \"external_user_id\": \"your_external_user_id\"\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Please note the following:</p>\n<ul>\n<li>duration is in seconds</li>\n<li>The date format must adhere to what is shown in this example</li>\n<li>If you wish to cancel or delete a calendar event then you should include a <code>\"action\": \"delete\"</code> in the header section</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"b1adc76d-6c86-45cc-aa51-9aed5311a1a6"}],"id":"d3b17ef3-7bea-4316-9d7d-e5e8556ee5ad","description":"<p>Calendar Events are tasks that are not linked to a customer. They generally reflect employee internal activities. Examples include:</p>\n<ul>\n<li>Lunch</li>\n<li>Start Day</li>\n<li>Load Truck</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"c0147d42-0bf1-4634-bf05-1551effbd10a","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"a043a28b-202d-44d2-8638-bcbfb54b0aa4","type":"text/javascript","exec":[""]}}],"_postman_id":"d3b17ef3-7bea-4316-9d7d-e5e8556ee5ad"},{"name":"Jobs","item":[{"name":"Job Notes","id":"f1f8dc4d-bbb4-42c4-bdb4-264b8c2ba38f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","name":"Content-Type","value":"application/json","type":"text"}],"body":{"mode":"raw","raw":"[\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"attachment\",\r\n            \"version\": \"v3\"\r\n        },\r\n        \"record\": {\r\n            \"external_job_id\": \"your_id\",\r\n            \"description\": \"some note\"\r\n        }\r\n    }\r\n]","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"f1f8dc4d-bbb4-42c4-bdb4-264b8c2ba38f"},{"name":"Job Photos","id":"b41c4a4d-39a2-4c07-b8fe-29f05dd31658","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","name":"Content-Type","type":"text","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"attachment\",\r\n            \"version\": \"v3\"\r\n        },\r\n        \"record\": {\r\n            \"external_job_id\": \"your_id\",\r\n            \"file\": \"base64encodedstring\",\r\n            \"name\": \"your_file_name.jpg\"\r\n        }\r\n    }\r\n]","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Please include a file name with extension so we know how to render.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"b41c4a4d-39a2-4c07-b8fe-29f05dd31658"},{"name":"Custom Form","id":"184ca510-fc55-45d3-be0b-b3a125243739","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","name":"Content-Type","type":"text","value":"application/json"}],"body":{"mode":"raw","raw":"[\r\n    {\r\n        \"header\": {\r\n            \"record_type\": \"custom_form\"\r\n        },\r\n        \"record\": {\r\n            \"external_job_id\": \"your_id\",\r\n            \"form_id\": \"wfm_custom_form_your_custom_form_name\",\r\n            \"form_data\": [{\r\n                \"custom_field_1\": \"custom_field_1_value\",\r\n                \"custom_field_2\": \"custom_field_2_value\"\r\n            }]\r\n        }\r\n    }\r\n]","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>If you want to update the custom form via the API you can do so using this.</p>\n<p>Please note that currently custom forms are set up via Dispatch, so please reach out to obtain the relevant custom form name and schema and we'll send along (the fields you place in the <code>form_id</code> and <code>form_data</code> section will need to match these.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"184ca510-fc55-45d3-be0b-b3a125243739"},{"name":"Job Trades","id":"deadf444-aaa8-4807-bd1e-07e0c2a69a11","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"job_trade\"\n        },\n        \"record\": {\n            \"external_job_id\": \"your_job_id\",\n            \"trades\": [\"Trade 1\", \"Trade 2\"]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Use this include job trades on your jobs (and optionally use them for match filtering).</p>\n<p>Items appearing in the list here should match the master list of trades that you provided Dispatch.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"deadf444-aaa8-4807-bd1e-07e0c2a69a11"},{"name":"Suggested Times","id":"4257f959-5f0f-4884-903a-9bf01e1e8e4d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"suggested_times\"\n        },\n        \"record\": {\n            \"external_job_id\": \"your_job_id\",\n            \"suggested_times\": [\n                {\n                    \"start_time\": \"2022-06-13T12:00:00.000Z\",\n                    \"end_time\": \"2022-06-13T16:00:00.000Z\"\n                },\n                {\n                    \"start_time\": \"2022-06-14T12:00:00.000Z\",\n                    \"end_time\": \"2022-06-15T16:00:00.000Z\"\n                }\n            ]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Use this include suggested times on your jobs.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"4257f959-5f0f-4884-903a-9bf01e1e8e4d"},{"name":"Job Attribution/Sources","id":"b14ed28d-f8b9-4a52-ad41-8be8ffee3dd1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"admin\": true,\n            \"record_type\": \"job_attribution\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_attribution_id\",\n            \"external_organization_id\": \"your_external_org_id\",\n            \"name\": \"Cold Call\"\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Add your company’s job sources. When you create a job, you’ll be able to attribute it to a source from this list.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"b14ed28d-f8b9-4a52-ad41-8be8ffee3dd1"}],"id":"3f0583c1-2600-4607-9349-65ee7e194b67","event":[{"listen":"prerequest","script":{"id":"5f4e7f24-0518-4201-9136-130a742e8b87","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"0c28df90-0583-4d97-b2e1-0dab690758be","type":"text/javascript","exec":[""]}}],"_postman_id":"3f0583c1-2600-4607-9349-65ee7e194b67","description":""},{"name":"Organizations","item":[{"name":"Configuration Settings","item":[{"name":"Configuration Settings","id":"4175422f-7151-4893-9734-4fe040ea4822","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\r\n    \"header\": {\r\n        \"record_type\": \"config\",\r\n        \"version\": \"v1\"\r\n    },\r\n    \"record\": {\r\n        \"external_organization_id\": \"your_external_org_id\",\r\n        \"organization_customer\": {\r\n            \"app\": {\r\n                \"profileBuilderEnabled\": true,\r\n                \"profileBuilderV2\": [\r\n                    {\r\n                        \"brand\": \"google\",\r\n                        \"link\": \"http://google2\",\r\n                        \"text\": \"Please leave a review on Google!\"\r\n                    },\r\n                    {\r\n                        \"brand\": \"facebook\",\r\n                        \"link\": \"http://facebook2\",\r\n                        \"text\": \"Please like us on Facebook!\"\r\n                    }\r\n                ]\r\n            }\r\n        },\r\n        \"organization_dispatcher\": {\r\n            \"app\": {\r\n                \"canSeeInbox\": true,\r\n                \"canSeeMobileInbox\": true,\r\n                \"canSeeQuickbooks\": true,\r\n                \"integrations\": {\r\n                    \"remove\": [\r\n                        \"Free Booking Page\"\r\n                    ]\r\n                }\r\n            }\r\n        },\r\n        \"organization_reminders\": [\r\n            {\r\n                \"name\": \"test reminder\",\r\n                \"type\": \"customer_pre_appointment\",\r\n                \"min_hours_out\": 15,\r\n                \"max_hours_out\": 33,\r\n                \"include_weekends\": true,\r\n                \"reminder_schedules\": [\r\n                    {\r\n                        \"timezone\": \"America/New_York\"\r\n                    }\r\n                ],\r\n                \"local_hour\": \"12\",\r\n                \"local_minute\": \"0\",\r\n                \"schedule\": \"0 12 * * SUN,MON,TUE,WED,THU,FRI,SAT\",\r\n                \"days_of_week\": \"SUN,MON,TUE,WED,THU,FRI,SAT\"\r\n            }\r\n        ]\r\n    }\r\n}"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Speak to your Dispatch rep about what settings you wish to apply defaults for and they will supply you with the list of relevant notifications settings as part of the project. The payload will resemble the example provided.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"4175422f-7151-4893-9734-4fe040ea4822"}],"id":"05d675b1-776f-49d4-a8b4-72744b992e70","event":[{"listen":"prerequest","script":{"id":"7f485883-a546-48ce-9189-caeab4213903","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"137c9d46-04e5-4731-8167-8fdfbd82ef8a","type":"text/javascript","exec":[""]}}],"_postman_id":"05d675b1-776f-49d4-a8b4-72744b992e70","description":""},{"name":"Service Areas","item":[{"name":"Service Area (Tracts)","id":"bc1239d0-fd24-49d5-b49a-7d777e6a1000","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"service_area\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_service_area_external_id\",\n            \"external_organization_id\": \"your_external_org_id\",\n            \"service_area_type\": \"tract\",\n            \"name\": \"recommend setting this to your company name\",\n            \"census_tracts\": [\n                \"41017000800\",\n                \"41017000900\",\n                \"41017001001\"\n            ]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Using tract/fips codes</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"bc1239d0-fd24-49d5-b49a-7d777e6a1000"},{"name":"Service Area (Postal Codes)","id":"1f6fe2cf-151b-4802-995f-be559225f32a","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"service_area\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_service_area_external_id\",\n            \"external_organization_id\": \"your_external_org_id\",\n            \"service_area_type\": \"zcta5\",\n            \"name\": \"recommend setting this to your company name\",\n            \"postal_codes\": [\n                {\n                    \"postal_code\": \"02446\"\n                },\n                {\n                    \"postal_code\": \"02447\"\n                },\n                {\n                    \"postal_code\": \"02488\"\n                }\n            ]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Using US Postal Codes</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"1f6fe2cf-151b-4802-995f-be559225f32a"},{"name":"Service Area (Canadian Postal Codes)","id":"c619a8fb-d02b-4d3d-bd1f-b87af0d854c5","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"service_area\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_service_area_external_id\",\n            \"external_organization_id\": \"your_external_org_id\",\n            \"service_area_type\": \"fsaldu\",\n            \"name\": \"recommend setting this to your company name\",\n            \"canadian_postal_codes\": [\n                \"H7M 6J3\",\n                \"P9A 8M7\"\n            ]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Using Canadian Postal Codes</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"c619a8fb-d02b-4d3d-bd1f-b87af0d854c5"}],"id":"7dddabb0-534b-4b94-8d7e-0d6533b38d41","description":"<p>Define your geographic service areas based on:</p>\n<ul>\n<li>Tract (or fips) codes</li>\n<li>US zip codes</li>\n<li>Canadian postal codes</li>\n</ul>\n<p>An example of each is provided below.</p>\n<p>If you only have a single service area per organization (usually the case), you should set the <code>external_id</code> to the same value as the <code>external_organization_id</code></p>\n","event":[{"listen":"prerequest","script":{"id":"2f904d1a-a8b6-4f1e-ad22-e7a6a8f84b04","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"fd4f4350-1fe1-4b71-8b53-685e3181b858","type":"text/javascript","exec":[""]}}],"_postman_id":"7dddabb0-534b-4b94-8d7e-0d6533b38d41"},{"name":"Org Trades","id":"06a1c0f9-5107-40f3-b109-bac92a8bcc5f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"trade_account_org\"\n        },\n        \"record\": {\n            \"external_id\": \"your_external_trade_id\",\n            \"external_organization_id\": \"your_external_org_id\",\n            \"trades\": [\"Trade 1\", \"Trade 2\"]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Use this to specify the trades assigned to organizations. These can be used as assignment filters.</p>\n<p>Please note that before you can use these APIs you will need to provide Dispatch with the master list of trades you intend to use (at the moment we don't have a publicly exposed API to set up the master list). This master list is what you will reference in the <code>trades</code> list and therefore you should:</p>\n<ul>\n<li>Make sure to provide us the list exactly as you will be passing it in (exact spelling)</li>\n<li>Pass in values as friendly names as these will be visible on the Dispatch front end</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"06a1c0f9-5107-40f3-b109-bac92a8bcc5f"}],"id":"0314bc39-8a37-49ea-8584-dab821c4a719","_postman_id":"0314bc39-8a37-49ea-8584-dab821c4a719","description":""},{"name":"Users","item":[{"name":"Service Areas","item":[{"name":"Service Area (Tracts)","id":"5e927083-1006-46a5-a7cb-d6a4404da42c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"service_area\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_service_area_external_id-your_user_id\",\n            \"name\": \"recommend setting to user name\",\n            \"service_area_type\": \"tract\",\n            \"census_tracts\": [\n                \"41017000800\",\n                \"41017000900\",\n                \"41017001001\"\n            ]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Using tract/fips codes</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"5e927083-1006-46a5-a7cb-d6a4404da42c"},{"name":"Service Area (Postal Codes)","id":"77285d5e-850c-4922-9089-7fde67f5d2fc","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"service_area\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_service_area_external_id-your_user_id\",\n            \"name\": \"recommend setting to user name\",\n            \"service_area_type\": \"zcta5\",\n            \"postal_codes\": [\n                {\n                    \"postal_code\": \"02446\"\n                },\n                {\n                    \"postal_code\": \"02447\"\n                },\n                {\n                    \"postal_code\": \"02488\"\n                }\n            ]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Using US Postal Codes</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"77285d5e-850c-4922-9089-7fde67f5d2fc"},{"name":"Service Area (Canadian Postal Codes)","id":"05827888-f6cc-4f12-a27b-4866ab10c2d3","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"service_area\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_service_area_external_id-your_user_id\",\n            \"name\": \"recommend setting to user name\",\n            \"service_area_type\": \"fsaldu\",\n            \"canadian_postal_codes\": [\n                \"H7M 6J3\",\n                \"P9A 8M7\"\n            ]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Using Canadian Postal Codes</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"05827888-f6cc-4f12-a27b-4866ab10c2d3"}],"id":"ab32546d-2dac-4d4b-9176-01202daea230","description":"<p>Define your geographic service areas based on:</p>\n<ul>\n<li>Tract (or fips) codes</li>\n<li>US zip codes</li>\n<li>Canadian postal codes</li>\n</ul>\n<p>An example of each is provided below.</p>\n<p>If you only have a single service area per organization (usually the case), you should set the <code>external_id</code> to the same value as the <code>external_organization_id</code></p>\n","event":[{"listen":"prerequest","script":{"id":"2f904d1a-a8b6-4f1e-ad22-e7a6a8f84b04","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"fd4f4350-1fe1-4b71-8b53-685e3181b858","type":"text/javascript","exec":[""]}}],"_postman_id":"ab32546d-2dac-4d4b-9176-01202daea230"},{"name":"User Photos","id":"26e7239b-42f0-4264-9292-e22defbc3172","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","name":"Content-Type","type":"text","value":"application/json"}],"body":{"mode":"raw","raw":"[{\r\n    \"header\": {\r\n      \"record_type\": \"profile_picture\",\r\n      \"version\": \"v3\"\r\n    },\r\n    \"record\": {\r\n      \"external_id\": \"your_userid\",\r\n      \"external_organization_id\": \"your_enterprise_id\",\r\n      \"file_name\": \"your_file_name.jpg\"\r\n    },\r\n    \"attachment\": \"base64string\"\r\n  }\r\n]","options":{"raw":{"language":"json"}}},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Use this to add a photo for the user. Please include a file name with extension so we know how to render.</p>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"26e7239b-42f0-4264-9292-e22defbc3172"},{"name":"User Tags","id":"418e11ad-c6a6-4ffd-b830-dc8c9c3b08de","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"user_tag\",\n            \"version\": \"v1\"\n        },\n        \"record\": {\n            \"external_id\": \"your_external_user_id\",\n            \"external_user_id\": \"your_external_user_id\",\n            \"key\": \"ranking_score\",\n            \"value\": \"44\"\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"418e11ad-c6a6-4ffd-b830-dc8c9c3b08de"},{"name":"User Trades","id":"e5915a1c-089d-4fa6-a55d-61ada3206b7e","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"[\n    {\n        \"header\": {\n            \"record_type\": \"trade_account_user\"\n        },\n        \"record\": {\n            \"external_id\": \"your_external_user_id\",\n            \"trades\": [\n                \"Trade 1\",\n                \"Trade 2\",\n                \"Trade 3\"\n            ]\n        }\n    }\n]"},"url":"https://connect-sbx.dispatch.me/agent/in","description":"<p>Use this to specify the trades assigned to users. These can be used as assignment filters.</p>\n<p>Please note that before you can use these APIs you will need to provide Dispatch with the master list of trades you intend to use (at the moment we don't have a publicly exposed API to set up the master list). This master list is what you will reference in the <code>trades</code> list and therefore you should:</p>\n<ul>\n<li>Make sure to provide us the list exactly as you will be passing it in (exact spelling)</li>\n<li>Pass in values as friendly names as these will be visible on the Dispatch front end</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","in"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"e5915a1c-089d-4fa6-a55d-61ada3206b7e"}],"id":"5afd58c6-ee4d-4ed0-903b-17cabb57c65a","description":"<p>Tags are used to tag users with attributes. For example, you add a ranking via tags to find preferred technicians via the availability algorithm</p>\n","event":[{"listen":"prerequest","script":{"id":"b33765f2-cdd2-4b6c-8dc8-1a881241cfa3","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"2e099808-4adc-4a2e-8738-f2e0a39f2b19","type":"text/javascript","exec":[""]}}],"_postman_id":"5afd58c6-ee4d-4ed0-903b-17cabb57c65a"}],"id":"92fbd710-4a4a-448a-80c8-24abb790b612","event":[{"listen":"prerequest","script":{"id":"5007f813-77a2-4493-9dd4-70c24ae848bd","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"dc507a1a-af78-4f9d-894f-cdd583bbda3a","type":"text/javascript","exec":[""]}}],"_postman_id":"92fbd710-4a4a-448a-80c8-24abb790b612","description":""},{"name":"From Dispatch","item":[{"name":"Ack/Error","item":[{"name":"Acks","id":"34a8e4dd-e86f-4b76-a241-f2c3e912e399","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>If you wish to receive acks of transactions successfully sent to the Dispatch Platform you can subscribe to this event. By default this is not sent back into the event stream so please let us know if you want this enabled.</p>\n<p><code>msg_id</code> will contain the value in the \"MessageId\" header when sending to the inbound endpoint (see code samples) so you're able to correlate the ack with a specific inbound transaction.</p>\n<p>This event indicates an ack that a transaction got processed successfully on the Dispatch side. It <strong>does not</strong> indicate that the Dispatcher acknowledged the job.</p>\n<p>And just like any other event you'll need send an update to <code>agent/out</code> to remove this from the queue (yes you'll need to acknowledge the acknowledgement!)</p>\n<h1 id=\"event-processing\">Event Processing</h1>\n<p>These will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">  \"Payload\": {\n    \"Actions\": [{\n      \"ID\": \"some_id\",\n      \"Put\": {\n        \"ack\": {\n            \"id\": 555,\n            \"external_id\": \"your_id\",\n            \"msg_id\": \"your_message_id\",\n            \"action\": \"inbound_ack\",\n            \"model\": \"job\",\n            \"data\": {\n              \"organization_id\": 11789,\n              \"external_id\": \"enterprise_system_id\"\n            }\n        }\n      }\n    }]\n  }    \n\n</code></pre>\n<p>Where:</p>\n<ul>\n<li><code>id</code> - the corresponding ID of the created entity in Dispatch in case you wish to store it (optional)</li>\n<li><code>external_id</code> - the id in your system</li>\n<li><code>model</code> - <code>job</code> for job, <code>organization</code> for organization etc.</li>\n</ul>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"34a8e4dd-e86f-4b76-a241-f2c3e912e399"},{"name":"Errors","id":"eb00efba-c837-4f29-a6fa-f36505e59d84","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>If you wish to receive notification of transactions that errored out you can subscribe to this event. By default this is not sent back into the event stream so please let us know if you want this enabled.</p>\n<p>We attempt to only send \"fixable\" errors to this endpoint. That is, errors that occurred due to bad data to this endpoint. These generally tend to be errors in the 400 range.</p>\n<p><code>msg_id</code> will contain the value in the \"MessageId\" header when sending to the inbound endpoint (see code samples) so you're able to correlate the err with a specific inbound transaction.</p>\n<p>As a general rule, the Dispatch Platform does everything to avoid transactions being rejected. As long as the minimal amout of data for a transaction is available the transaction will succeed. As such, we believe that errors are likely to occur during the testing phase of the project and thereafter should be very few and far between.</p>\n<h1 id=\"event-processing\">Event Processing</h1>\n<p>These will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n        \"Actions\": [\n            {\n                \"ID\": \"some_id\",\n                \"Put\": {\n                    \"err\": {\n                        \"payload\": {\n                            \"err\": {\n                                \"data_type\": \"job\",\n                                \"external_id\": \"your_id\",\n                                \"msg_id\": \"your_message_id\",\n                                \"message\": \"Problem writing job ({\\\"errors\\\":{\\\"status\\\":[\\\"is not included in the list\\\"],\\\"workflow\\\":[\\\"Job status is not in given workflow\\\"]}})\"\n                            }\n                        }\n                    }\n                }\n            }\n        ]\n    }\n\n</code></pre>\n<p>StartFragment</p>\n<ul>\n<li><code>external_id</code> - the id in your system</li>\n<li><code>data_type</code> - <code>job</code> for job, <code>organization</code> for organization etc.</li>\n</ul>\n<p>EndFragment</p>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"eb00efba-c837-4f29-a6fa-f36505e59d84"}],"id":"f4658708-f3a1-4cf5-bd32-2b452d2b2acf","description":"<p>The processing mentioned in this section is optional.</p>\n","event":[{"listen":"prerequest","script":{"id":"8ec37094-07f7-4927-a352-65e2de578f25","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"56c17ef4-2948-437e-a43e-f6b57814aa96","type":"text/javascript","exec":[""]}}],"_postman_id":"f4658708-f3a1-4cf5-bd32-2b452d2b2acf"},{"name":"Auto Assign Fail","item":[{"name":"Auto Assign Tech","id":"fde46862-b2ec-4017-abb1-acf7bd42adce","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>If a technician auto assign action was unsuccessful, you will receive the following response:</p>\n<h1 id=\"event-processing\">Event Processing</h1>\n<p>These will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">  \"Payload\": {\n    \"Actions\": [{\n      \"ID\": \"some_id\",\n      \"Put\": {\n        \"ack\": {\n            \"external_id\": \"external_job_id\",\n            \"external_appointment_id\": \"external_job_or_appointment_id\",\n            \"msg_id\": \"your_message_id\",\n            \"action\": \"inbound_ack\",\n            \"model\": \"auto_assign_technician\",\n            \"ack_message\": \"No technicians found for availability window\",\n            \"api_response\": {\n                \"matches\": null\n            }\n        }\n      }\n    }]\n  }    \n\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"fde46862-b2ec-4017-abb1-acf7bd42adce"},{"name":"Auto Assign Org","id":"439dea2b-6cae-4d1f-9464-3bbda42ace0d","request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>If org auto assign action was unsuccessful, you will receive the following response:</p>\n<h1 id=\"event-processing\">Event Processing</h1>\n<p>These will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">  \"Payload\": {\n    \"Actions\": [{\n      \"ID\": \"some_id\",\n      \"Put\": {\n        \"ack\": {\n            \"id\": 555,\n            \"data\": {\n                 \"external_id\": \"external_offer_id\"\n            },\n            \"msg_id\": \"your_message_id\",\n            \"action\": \"inbound_ack\",\n            \"model\": \"auto_assign_org\",\n            \"ack_message\": \"No matching organizations found\",\n            \"api_response\": {\n                \"matches\": null\n            }\n        }\n      }\n    }]\n  }    \n\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"439dea2b-6cae-4d1f-9464-3bbda42ace0d"}],"id":"e06fa0fe-4029-4a59-a7ab-7688111d94a2","_postman_id":"e06fa0fe-4029-4a59-a7ab-7688111d94a2","description":""},{"name":"Billing","item":[{"name":"Estimate Events","id":"7b85d11e-1fc5-4fb3-9472-37b79242d0b6","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Estimate</em> events. These events are wrapped in an <code>estimate</code> key.</p>\n<p>Valid values for the <code>status</code> fields are:</p>\n<ul>\n<li><code>draft</code></li>\n<li><code>won</code></li>\n<li><code>lost</code></li>\n</ul>\n<p>These events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n          \"Actions\": [\n            {\n              \"ID\": \"a9ce6d53-dc32-51f8-81b4-3a00f47c5bdf\",\n              \"Put\": {\n                \"estimate\": {\n                  \"description\": null,\n                  \"discount_amount\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$30.00\",\n                    \"value\": \"30.00\"\n                  },\n                  \"discount_percent\": null,\n                  \"doc_type\": \"Estimate\",\n                  \"external_id\": \"your_estimate_id\",\n                  \"id\": 4697,\n                  \"invoice_id\": null,\n                  \"job\": {\n                    \"external_id\": \"your_enterprise_id\"\n                  },\n                  \"job_id\": 383147,\n                  \"lines\": [\n                    {\n                      \"billing_item_id\": null,\n                      \"id\": \"d9d0016b-554b-4748-9b00-0cf6aa7ff02c\",\n                      \"billing_item\": {\n                          \"external_id\": \"your_catalog_id\"\n                      }\n                      \"markup\": 0,\n                      \"price\": {\n                        \"currency\": \"USD\",\n                        \"text\": \"$3.33\",\n                        \"value\": \"3.33\"\n                      },\n                      \"price_with_markup\": {\n                        \"currency\": \"USD\",\n                        \"text\": \"$3.33\",\n                        \"value\": \"3.33\"\n                      },\n                      \"qty\": 2,\n                      \"taxable\": true,\n                      \"title\": \"\",\n                      \"total\": {\n                        \"currency\": \"USD\",\n                        \"text\": \"$6.66\",\n                        \"value\": \"6.66\"\n                      }\n                    }\n                  ],\n                  \"number\": \"1005\",\n                  \"paid\": false,\n                  \"po_number\": \"asfdfdasdf\",\n                  \"status\": \"draft\",\n                  \"subtotal\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$6.66\",\n                    \"value\": \"6.66\"\n                  },\n                  \"tax_amount\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$0.00\",\n                    \"value\": \"0.00\"\n                  },\n                  \"title\": null,\n                  \"total\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$-23.34\",\n                    \"value\": \"-23.34\"\n                  },\n                  \"total_paid\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$0.00\",\n                    \"value\": \"0.00\"\n                  },\n                  \"updated_at\": \"2020-06-04T16:49:18+0000\"\n                }\n              }\n            }\n          ]\n        }\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"7b85d11e-1fc5-4fb3-9472-37b79242d0b6"},{"name":"Invoice Events","id":"6803e812-6e8d-492a-837e-bd7a5894752c","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Invoice</em> events. These events are wrapped in an <code>invoice</code> key.</p>\n<p>Valid values for the <code>status</code> fields are:</p>\n<ul>\n<li><code>draft</code></li>\n<li><code>balance_outstanding</code> (when this is 0 the invoice is fully paid)</li>\n</ul>\n<p>These events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">    \"Payload\": {\n          \"Actions\": [\n            {\n              \"ID\": \"a9ce6d53-dc32-51f8-81b4-3a00f47c5bdf\",\n              \"Put\": {\n                \"invoice\": {\n                  \"description\": null,\n                  \"discount_amount\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$30.00\",\n                    \"value\": \"30.00\"\n                  },\n                  \"discount_percent\": null,\n                  \"doc_type\": \"Estimate\",\n                  \"external_id\": \"your_estimate_id\",\n                  \"id\": 4697,\n                  \"job\": {\n                    \"external_id\": \"your_enterprise_id\"\n                  },\n                  \"job_id\": 383147,\n                  \"lines\": [\n                    {\n                      \"billing_item_id\": null,\n                      \"id\": \"d9d0016b-554b-4748-9b00-0cf6aa7ff02c\",\n                      \"billing_item\": {\n                          \"external_id\": \"your_catalog_id\"\n                      }\n                      \"markup\": 0,\n                      \"price\": {\n                        \"currency\": \"USD\",\n                        \"text\": \"$3.33\",\n                        \"value\": \"3.33\"\n                      },\n                      \"price_with_markup\": {\n                        \"currency\": \"USD\",\n                        \"text\": \"$3.33\",\n                        \"value\": \"3.33\"\n                      },\n                      \"qty\": 2,\n                      \"taxable\": true,\n                      \"title\": \"\",\n                      \"total\": {\n                        \"currency\": \"USD\",\n                        \"text\": \"$6.66\",\n                        \"value\": \"6.66\"\n                      }\n                    }\n                  ],\n                  \"number\": \"1005\",\n                  \"paid\": false,\n                  \"po_number\": \"asfdfdasdf\",\n                  \"status\": \"draft\",\n                  \"subtotal\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$6.66\",\n                    \"value\": \"6.66\"\n                  },\n                  \"tax_amount\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$0.00\",\n                    \"value\": \"0.00\"\n                  },\n                  \"title\": null,\n                  \"total\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$-23.34\",\n                    \"value\": \"-23.34\"\n                  },\n                  \"total_paid\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$0.00\",\n                    \"value\": \"0.00\"\n                  },\n                  \"updated_at\": \"2020-06-04T16:49:18+0000\"\n                }\n              }\n            }\n          ]\n        }\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"6803e812-6e8d-492a-837e-bd7a5894752c"},{"name":"Payment Events","id":"4235bca8-6d10-413e-bb26-1f9caabb19c4","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Payment</em> events. These events are wrapped in an <code>payment</code> key.</p>\n<p>These events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">            \"Payload\": {\n          \"Actions\": [\n            {\n              \"ID\": \"884a38c7-087c-5d50-a1e6-6f943c18bd7b\",\n              \"Put\": {\n                \"payment\": {\n                  \"amount\": {\n                    \"currency\": \"USD\",\n                    \"text\": \"$1.11\",\n                    \"value\": \"1.11\"\n                  },\n                  \"billing_document_id\": 4699,\n                  \"billing_document\": {\n                    \"external_id\": \"your_external_id\"\n                  },\n                  \"card_name\": null,\n                  \"card_number\": null,\n                  \"card_type\": null,\n                  \"id\": 514,\n                  \"payment_method\": \"check\",\n                  \"reference\": null,\n                  \"result\": \"success\",\n                  \"transaction_id\": \"xxxx\",\n                  \"updated_at\": \"2020-06-04T17:40:52+0000\"\n                }\n              }\n            }\n          ]\n        }\n      }\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"4235bca8-6d10-413e-bb26-1f9caabb19c4"}],"id":"5fd2d2fa-dfec-45a9-873b-2bcd447b397a","description":"<p><strong>This section is only relevant if you are integrating with Dispatch's billing model</strong></p>\n<p>These are the typical API calls you will need to make to process billing requests to the Dispatch platform.</p>\n<p>In Dispatch we refer to both <em>Estimates</em> and <em>Invoices</em> as <strong>Billing Documents</strong>. This is because Estimates and Invoices are two sides of the same coin and are structurely very similar. We differentiate between them use the <code>doc_type</code> attribute on the Billing Document.</p>\n<p>A Billing Document consists of a header and details section:</p>\n<ul>\n<li>Header - this contains standard billing information such as the document number and customer info.</li>\n<li>Details - The details consists of one or more \"line items\". The line item is essentially a <code>product</code> or <code>service</code> that you are selling and every line item must be linked to a master \"billing item\".</li>\n</ul>\n<p>To illustrate the difference between a <em>line item</em> and <em>billing item</em> consider the following:</p>\n<ul>\n<li>You sell <em>hammers</em> - so you add <em>hammer</em> to your product catalog and put them in your inventory. We refer to the product catalog as <strong>billing items</strong> and you can think of this as your <em>product definition</em>.</li>\n<li>From now on you can add <em>hammers</em> as line items to your billing documents. In other words the <strong>line item</strong> is your <em>product instance</em>.</li>\n</ul>\n<p>The typical flow for billing documents is as follows:</p>\n<ul>\n<li>Estimate: draft ==&gt; sent ==&gt; won/lost</li>\n<li>When an estimate is <em>won</em> a corresponding Invoice is created</li>\n<li>Invoice: draft ==&gt; sent ==&gt; balance_outstanding ==&gt; paid </li>\n<li>An invoice can be created without first starting out as estimate</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"7f282b0f-a36e-4ad9-981d-888729fbd620","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"7fdfe78e-d992-4928-84cb-a3b70f24d401","type":"text/javascript","exec":[""]}}],"_postman_id":"5fd2d2fa-dfec-45a9-873b-2bcd447b397a"},{"name":"Calendar Events","item":[{"name":"Calendar Events","id":"1b3cd716-e06c-4307-87ad-7062741f3640","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Calendar Event</em> events. These events are wrapped in an <code>calendar_event</code> element.</p>\n<p>These events will have the following payload structure:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>    {\n        \"Payload\": {\n            \"Actions\": [\n                {\n                    \"ID\": null,\n                    \"Put\": {\n                        \"calendar_event\": {\n                          \"uuid\" : \"317133c0-1a9d-41c9-a548-08bddabdf79\",\n                          \"title\": \"Event title\",\n                          \"started_at\" : \"2019-10-21T08:30:00Z\",\n                          \"completed_at\": \"2019-10-21T09:30:00Z\",\n                          \"external_id\": \"your_id\"\n                        }\n                    }\n                }\n            ]\n        }\n    }\n</code></pre>","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"1b3cd716-e06c-4307-87ad-7062741f3640"}],"id":"ebfaf899-0b21-4f7f-915b-5c29cfc6670e","description":"<p><strong>This section is only relevant if you wish to consume updates for Calendar Events</strong></p>\n","event":[{"listen":"prerequest","script":{"id":"7f282b0f-a36e-4ad9-981d-888729fbd620","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"7fdfe78e-d992-4928-84cb-a3b70f24d401","type":"text/javascript","exec":[""]}}],"_postman_id":"ebfaf899-0b21-4f7f-915b-5c29cfc6670e"},{"name":"Custom Forms","item":[{"name":"Custom Form","id":"382b29f3-8f96-42ed-89c2-10e72a485635","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>This describes the use cases for processing <em>Custom Form</em> events. These events are wrapped in an <code>customForm</code> element.</p>\n<p>Use the <code>form_name</code> to determine which custom form data this is for.</p>\n<h1 id=\"event-processing\">Event Processing</h1>\n<h2 id=\"custom-form-submitted\">Custom Form Submitted</h2>\n<p>These events will have the following payload structure (this example is incomplete):</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">        \"Payload\": {\n          \"Actions\": [\n            {\n              \"ID\": \"some_id\",\n              \"Put\": {\n                \"customform\": {\n                  \"form_data\": {\n                    \"cash_amount\": \"1222\",\n                    \"mileage\": \"1232\"\n                  },\n                  \"form_name\": \"wfm_custom_form_close_out\",\n                  \"job\": {\n                    \"external_id\": \"your_id\"\n                  },\n                  \"job_id\": 383147\n                }\n              }\n            }\n          ]\n        }\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"382b29f3-8f96-42ed-89c2-10e72a485635"}],"id":"e565b74d-9319-4feb-aeb7-b052c924e9d3","description":"<p>Custom forms are used to gather additional data from the field. One or more custom forms can be defined and the information gathered can be sent back when submitted.</p>\n","event":[{"listen":"prerequest","script":{"id":"7f485883-a546-48ce-9189-caeab4213903","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"137c9d46-04e5-4731-8167-8fdfbd82ef8a","type":"text/javascript","exec":[""]}}],"_postman_id":"e565b74d-9319-4feb-aeb7-b052c924e9d3"},{"name":"Rendering Images","item":[{"name":"Get File","id":"f3f11bce-b781-4713-a09d-e8b8628fa9f7","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Content-Type","value":"application/json"}],"url":"https://files-api-sandbox.dispatch.me/v1/datafiles/{{file_token}}/{{format}}","description":"<p><strong>Request</strong></p>\n<p>where:</p>\n<ul>\n<li><code>file_token</code> - that you obtained from Dispatch</li>\n<li><code>format</code> - this tells the API how to render the file. Valid values are:<ul>\n<li>square_50</li>\n<li>square_100</li>\n<li>square_250</li>\n<li>proportional_50</li>\n<li>proportional_100</li>\n<li>proportional_250</li>\n<li>vertical_50</li>\n<li>vertical_100</li>\n<li>vertical_250</li>\n</ul>\n</li>\n</ul>\n<p><strong>Response</strong></p>\n<p>The file in the format you specified. You will need to look at the <code>Content-Type</code> header in order to know how to render the file. This will contain the <a href=\"https://www.iana.org/assignments/media-types/media-types.xhtml\">mime type</a>.</p>\n<p>See <a href=\"https://github.com/Nahis/dispatchme/blob/master/dispatch-connect/samples/DispatchOutbound/Python/download_attachment.py\">this python example</a> for working with files.</p>\n","urlObject":{"protocol":"https","path":["v1","datafiles","{{file_token}}","{{format}}"],"host":["files-api-sandbox","dispatch","me"],"query":[],"variable":[]}},"response":[{"id":"125a4fb7-88b8-4dee-ac3d-5bc1add11deb","name":"Sample Response","originalRequest":{"method":"GET","header":[{"key":"Content-Type","value":"application/json","enabled":true,"description":"The mime type of this content"}],"url":"https://files-{{server}}.dispatch.me/v1/datafiles/{{file_token}}/square_50"},"status":"OK","code":200,"_postman_previewlanguage":"html","header":[{"name":"Accept-Ranges","key":"Accept-Ranges","value":"bytes","description":""},{"name":"Cache-Control","key":"Cache-Control","value":"max-age=315576000","description":""},{"name":"Content-Encoding","key":"Content-Encoding","value":"","description":""},{"name":"Content-Length","key":"Content-Length","value":"1567","description":""},{"name":"Content-Type","key":"Content-Type","value":"image/jpeg","description":""},{"name":"Date","key":"Date","value":"Thu, 21 Apr 2016 12:27:31 GMT","description":""},{"name":"ETag","key":"ETag","value":"\"789baa92be25f5607b053402bc88f6d2\"","description":""},{"name":"Last-Modified","key":"Last-Modified","value":"Thu, 21 Apr 2016 12:27:13 GMT","description":""},{"name":"Server","key":"Server","value":"AmazonS3","description":""},{"name":"x-amz-id-2","key":"x-amz-id-2","value":"vRD1qTjm55cG3piNZNQAdQL8oHe9hEULUqIGPd+GUts+wbanVWB4V8gmuzTgVD+6GBWrNRniecA=","description":""},{"name":"x-amz-request-id","key":"x-amz-request-id","value":"E0F998ADA0809811","description":""}],"cookie":[],"responseTime":null,"body":""},{"id":"7860978f-1424-491e-8f2d-1d59ec9f301d","name":"Example Response","originalRequest":{"method":"GET","header":[{"key":"Content-Type","value":"application/json","enabled":true,"description":"The mime type of this content"},{"key":"Accept","value":"application/json","enabled":true},{"key":"Authorization","value":"Bearer 5a1c04b962cfd5971f2b23f00ce8481d4c9fce5ead7beaa5878dc90c3a0050e9","enabled":true},{"key":"Cache-Control","name":"Cache-Control","value":"no-cache"},{"key":"Postman-Token","name":"Postman-Token","value":"5d3933de-b936-101c-69be-d394fd070e71"}],"url":{"raw":"https://api-sandbox.dispatch.me/v1/organizations?filter[by_external_ids][]=JOJ001","protocol":"https","host":["api-sandbox","dispatch","me"],"path":["v1","organizations"],"query":[{"key":"filter[by_external_ids][]","value":"JOJ001"}]}},"status":"OK","code":200,"_postman_previewlanguage":"javascript","header":[{"name":"Cache-Control","key":"Cache-Control","value":"max-age=0, private, must-revalidate","description":""},{"name":"Connection","key":"Connection","value":"keep-alive","description":""},{"name":"Content-Encoding","key":"Content-Encoding","value":"gzip","description":""},{"name":"Content-Type","key":"Content-Type","value":"application/json; charset=utf-8","description":""},{"name":"Date","key":"Date","value":"Wed, 16 Mar 2016 18:31:14 GMT","description":""},{"name":"Server","key":"Server","value":"nginx","description":""},{"name":"Transfer-Encoding","key":"Transfer-Encoding","value":"chunked","description":""},{"name":"Vary","key":"Vary","value":"Accept-Encoding, Origin","description":""},{"name":"X-Content-Type-Options","key":"X-Content-Type-Options","value":"nosniff","description":""},{"name":"X-Frame-Options","key":"X-Frame-Options","value":"SAMEORIGIN","description":""},{"name":"X-Request-Id","key":"X-Request-Id","value":"477baf2d-dd55-4d5c-92dd-f2232842944f","description":""},{"name":"X-Runtime","key":"X-Runtime","value":"0.026263","description":""},{"name":"X-XSS-Protection","key":"X-XSS-Protection","value":"1; mode=block","description":""}],"cookie":[],"responseTime":null,"body":"{\"organizations\":[{\"id\":469,\"created_at\":\"2016-03-03T15:47:55+0000\",\"updated_at\":\"2016-03-15T15:52:16+0000\",\"name\":\"Joe's Plumbing\",\"email\":\"devs+joj001@dispatch.me\",\"email_from\":null,\"phone_number\":\"+15559626103\",\"twilio_phone_number\":null,\"line_item_level_tax\":false,\"logo_token\":null,\"tracker_logo_token\":null,\"url\":null,\"about\":null,\"accepted_payment_options\":[\"cash\",\"check\"],\"is_configured\":false,\"working_hours\":{\"0\":[],\"1\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"2\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"3\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"4\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"5\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"6\":[]},\"service_types\":{},\"is_allowed_notifications\":true,\"is_available_for_job_offers\":true,\"timezone\":null,\"country\":\"United States\",\"currency\":\"USD\",\"signup_source\":\"cchs\",\"reporting_enabled\":true,\"max_job_drive_time\":0,\"auto_generate_service_fee_invoice\":false,\"version\":\"v1\",\"updated_by\":\"account:c138f261-6d5b-4fc2-ac5b-ddef29d01470\",\"external_ids\":[\"demo:JOJ001\",\"demo:test_add1\",\"demo:test_add2\"],\"address\":null}]}"},{"id":"d581124d-430d-4620-88ce-ca9ffefa9c51","name":"Example Response","originalRequest":{"method":"GET","header":[{"key":"Content-Type","value":"application/json","enabled":true,"description":"The mime type of this content"},{"key":"Accept","value":"application/json","enabled":true},{"key":"Authorization","value":"Bearer 5a1c04b962cfd5971f2b23f00ce8481d4c9fce5ead7beaa5878dc90c3a0050e9","enabled":true},{"key":"Cache-Control","name":"Cache-Control","value":"no-cache"},{"key":"Postman-Token","name":"Postman-Token","value":"5d3933de-b936-101c-69be-d394fd070e71"}],"url":{"raw":"https://api-sandbox.dispatch.me/v1/organizations?filter[by_external_ids][]=JOJ001","protocol":"https","host":["api-sandbox","dispatch","me"],"path":["v1","organizations"],"query":[{"key":"filter[by_external_ids][]","value":"JOJ001"}]}},"status":"OK","code":200,"_postman_previewlanguage":"javascript","header":[{"name":"Cache-Control","key":"Cache-Control","value":"max-age=0, private, must-revalidate","description":""},{"name":"Connection","key":"Connection","value":"keep-alive","description":""},{"name":"Content-Encoding","key":"Content-Encoding","value":"gzip","description":""},{"name":"Content-Type","key":"Content-Type","value":"application/json; charset=utf-8","description":""},{"name":"Date","key":"Date","value":"Wed, 16 Mar 2016 18:31:14 GMT","description":""},{"name":"Server","key":"Server","value":"nginx","description":""},{"name":"Transfer-Encoding","key":"Transfer-Encoding","value":"chunked","description":""},{"name":"Vary","key":"Vary","value":"Accept-Encoding, Origin","description":""},{"name":"X-Content-Type-Options","key":"X-Content-Type-Options","value":"nosniff","description":""},{"name":"X-Frame-Options","key":"X-Frame-Options","value":"SAMEORIGIN","description":""},{"name":"X-Request-Id","key":"X-Request-Id","value":"477baf2d-dd55-4d5c-92dd-f2232842944f","description":""},{"name":"X-Runtime","key":"X-Runtime","value":"0.026263","description":""},{"name":"X-XSS-Protection","key":"X-XSS-Protection","value":"1; mode=block","description":""}],"cookie":[],"responseTime":null,"body":"{\"organizations\":[{\"id\":469,\"created_at\":\"2016-03-03T15:47:55+0000\",\"updated_at\":\"2016-03-15T15:52:16+0000\",\"name\":\"Joe's Plumbing\",\"email\":\"devs+joj001@dispatch.me\",\"email_from\":null,\"phone_number\":\"+15559626103\",\"twilio_phone_number\":null,\"line_item_level_tax\":false,\"logo_token\":null,\"tracker_logo_token\":null,\"url\":null,\"about\":null,\"accepted_payment_options\":[\"cash\",\"check\"],\"is_configured\":false,\"working_hours\":{\"0\":[],\"1\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"2\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"3\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"4\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"5\":[\"08:00:00 - 11:59:59\",\"12:00:00 - 15:59:59\"],\"6\":[]},\"service_types\":{},\"is_allowed_notifications\":true,\"is_available_for_job_offers\":true,\"timezone\":null,\"country\":\"United States\",\"currency\":\"USD\",\"signup_source\":\"cchs\",\"reporting_enabled\":true,\"max_job_drive_time\":0,\"auto_generate_service_fee_invoice\":false,\"version\":\"v1\",\"updated_by\":\"account:c138f261-6d5b-4fc2-ac5b-ddef29d01470\",\"external_ids\":[\"demo:JOJ001\",\"demo:test_add1\",\"demo:test_add2\"],\"address\":null}]}"}],"_postman_id":"f3f11bce-b781-4713-a09d-e8b8628fa9f7"}],"id":"69e45945-4c05-4702-a5e9-fc0fd625b428","description":"<p>See this <a href=\"https://github.com/Nahis/dispatchme/blob/master/dispatch-connect/samples/DispatchOutbound/Python/download_attachment.py\">python sample</a></p>\n","event":[{"listen":"prerequest","script":{"id":"7935511b-5009-4dcf-ad53-a80b31fd94f8","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"cf8f4f57-b045-49b5-a06d-8044ac6d4899","type":"text/javascript","exec":[""]}}],"_postman_id":"69e45945-4c05-4702-a5e9-fc0fd625b428"},{"name":"Availability","item":[{"name":"Whitespace","id":"783107dd-0dcc-4095-aa6f-e9ba90cf2a10","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer {{token}}"}],"url":"https://api-sandbox.dispatch.me/v1/availability/slots?user_external_id[]=a013900001Zc9FkAAJ&user_external_id[]=a013900001aPXO1AAO&start_time=2022-10-24T04:00:00Z&end_time=2022-10-25T03:59:59Z&duration=60","description":"<p>Also see <a href=\"#165792c2-df72-44b6-b863-a3a258eecbee\">Match Technicians</a> for a more general purpose approach for matching technicians to a given job.</p>\n<p>The whitespace API looks at the technician schedules and returns slots that have enough availability for the estimated appointment duration passed in.</p>\n<p>So for example, given an appointment of 1 hour duration and the following schedule for these two techs on Oct 24:</p>\n<img src=\"https://content.pstmn.io/62324604-8be7-45ab-87fb-b95eb18079cd/d2hpdGVzcGFjZS5wbmc=\" />\n\n<p>It will return 4 slots (see sample response) - each of these slots contain enough time for the appointment.</p>\n<p><strong>URL Parameters:</strong></p>\n<ul>\n<li>user_external_id - these are the IDs for the users in your system</li>\n<li>start time - start period for search</li>\n<li>end time - end period for search</li>\n<li>duration - duration in minutes required for appointment</li>\n</ul>\n","urlObject":{"protocol":"https","path":["v1","availability","slots"],"host":["api-sandbox","dispatch","me"],"query":[{"key":"user_external_id[]","value":"a013900001Zc9FkAAJ"},{"key":"user_external_id[]","value":"a013900001aPXO1AAO"},{"key":"start_time","value":"2022-10-24T04:00:00Z"},{"key":"end_time","value":"2022-10-25T03:59:59Z"},{"key":"duration","value":"60"}],"variable":[]}},"response":[{"id":"53feabb2-5ddf-40c0-bf5b-0aa7508d6181","name":"Whitespace Response","originalRequest":{"method":"GET","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer {{token}}"}],"url":{"raw":"https://api-sandbox.dispatch.me/v1/availability/slots?5298user_external_id[]=a013900001Zc9FkAAJ&user_external_id[]=a013900001aPXO1AAO&start_time=2022-10-24T04:00:00Z&end_time=2022-10-25T03:59:59Z&duration=60","protocol":"https","host":["api-sandbox","dispatch","me"],"path":["v1","availability","slots"],"query":[{"key":"5298user_external_id[]","value":"a013900001Zc9FkAAJ"},{"key":"user_external_id[]","value":"a013900001aPXO1AAO"},{"key":"start_time","value":"2022-10-24T04:00:00Z"},{"key":"end_time","value":"2022-10-25T03:59:59Z"},{"key":"duration","value":"60"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 25 Oct 2022 10:32:40 GMT"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"591"},{"key":"Connection","value":"keep-alive"}],"cookie":[],"responseTime":null,"body":"{\n    \"slots\": [\n        {\n            \"entity_type\": \"user\",\n            \"entity_id\": 3231,\n            \"external_id\": \"a013900001Zc9FkAAJ\",\n            \"start_time\": \"2022-10-24T12:00:00Z\",\n            \"end_time\": \"2022-10-24T13:00:00Z\"\n        },\n        {\n            \"entity_type\": \"user\",\n            \"entity_id\": 3231,\n            \"external_id\": \"a013900001Zc9FkAAJ\",\n            \"start_time\": \"2022-10-24T17:30:00Z\",\n            \"end_time\": \"2022-10-24T21:00:00Z\"\n        },\n        {\n            \"entity_type\": \"user\",\n            \"entity_id\": 5298,\n            \"external_id\": \"a013900001aPXO1AAO\",\n            \"start_time\": \"2022-10-24T12:00:00Z\",\n            \"end_time\": \"2022-10-24T16:00:00Z\"\n        },\n        {\n            \"entity_type\": \"user\",\n            \"entity_id\": 5298,\n            \"external_id\": \"a013900001aPXO1AAO\",\n            \"start_time\": \"2022-10-24T20:00:00Z\",\n            \"end_time\": \"2022-10-24T21:00:00Z\"\n        }\n    ]\n}"}],"_postman_id":"783107dd-0dcc-4095-aa6f-e9ba90cf2a10"},{"name":"Block Times","id":"7577e70a-b5f1-4fbf-b568-e21215daed67","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer {{token}}"}],"url":"https://api-sandbox.dispatch.me/v1/availability/schedule?user_external_id[]=a013900001Zc9FkAAJ&user_external_id[]=a013900001aPXO1AAO&start_time=2022-10-24T04:00:00Z&end_time=2022-10-25T03:59:59Z&duration=60","description":"<p>This returns the inverse of the whitespace API. So while the whitespace shows all of the available slots, this API returns:</p>\n<ul>\n<li>Start and End Time for techs' work days</li>\n<li>Blocks - time that is taken up by periods of unavailability</li>\n</ul>\n<p>So assuming this schedule:</p>\n<img src=\"https://content.pstmn.io/80178449-96b9-4c2d-8a62-c61b967b6d4a/c2NoZWR1bGUucG5n\" />\n\n<p>The response (see example) returns:</p>\n<ul>\n<li>The <code>day_start</code> and <code>day_end</code> indicated by the section highlighted in yellow</li>\n<li>The times period that are blocked indicated by the red rectangles</li>\n</ul>\n<p><strong>URL Parameters:</strong></p>\n<ul>\n<li>user_external_id - these are the IDs for the users in your system</li>\n<li>start time - start period for search</li>\n<li>end time - end period for search</li>\n<li>duration - duration in minutes required for appointment</li>\n</ul>\n","urlObject":{"protocol":"https","path":["v1","availability","schedule"],"host":["api-sandbox","dispatch","me"],"query":[{"key":"user_external_id[]","value":"a013900001Zc9FkAAJ"},{"key":"user_external_id[]","value":"a013900001aPXO1AAO"},{"key":"start_time","value":"2022-10-24T04:00:00Z"},{"key":"end_time","value":"2022-10-25T03:59:59Z"},{"key":"duration","value":"60"}],"variable":[]}},"response":[{"id":"d5316323-08ba-4710-8033-acb01493a1bf","name":"Block Time Response","originalRequest":{"method":"GET","header":[{"key":"Content-Type","value":"application/json"},{"key":"Accept","value":"application/json"},{"key":"Authorization","value":"Bearer {{token}}"}],"url":{"raw":"https://api{{env}}.dispatch.me/v1/availability/schedule?user_external_id[]=a013900001Zc9FkAAJ&user_external_id[]=a013900001aPXO1AAO&start_time=2022-10-24T04:00:00Z&end_time=2022-10-25T03:59:59Z&duration=60","protocol":"https","host":["api{{env}}","dispatch","me"],"path":["v1","availability","schedule"],"query":[{"key":"user_external_id[]","value":"a013900001Zc9FkAAJ"},{"key":"user_external_id[]","value":"a013900001aPXO1AAO"},{"key":"start_time","value":"2022-10-24T04:00:00Z"},{"key":"end_time","value":"2022-10-25T03:59:59Z"},{"key":"duration","value":"60"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 25 Oct 2022 10:47:45 GMT"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"779"},{"key":"Connection","value":"keep-alive"}],"cookie":[],"responseTime":null,"body":"{\n    \"days\": [\n        {\n            \"user_id\": 3231,\n            \"external_id\": \"a013900001Zc9FkAAJ\",\n            \"day_start\": \"2022-10-24T12:00:00Z\",\n            \"day_end\": \"2022-10-24T21:00:00Z\",\n            \"blocks\": [\n                {\n                    \"start\": \"2022-10-24T13:00:00Z\",\n                    \"end\": \"2022-10-24T17:30:00Z\"\n                }\n            ]\n        },\n        {\n            \"user_id\": 3231,\n            \"external_id\": \"a013900001Zc9FkAAJ\",\n            \"day_start\": \"2022-10-25T12:00:00Z\",\n            \"day_end\": \"2022-10-25T21:00:00Z\",\n            \"blocks\": []\n        },\n        {\n            \"user_id\": 5298,\n            \"external_id\": \"a013900001aPXO1AAO\",\n            \"day_start\": \"2022-10-24T12:00:00Z\",\n            \"day_end\": \"2022-10-24T21:00:00Z\",\n            \"blocks\": [\n                {\n                    \"start\": \"2022-10-24T16:00:00Z\",\n                    \"end\": \"2022-10-24T20:00:00Z\",\n                    \"data\": {\n                        \"job_id\": 700040,\n                        \"customer_id\": 281712,\n                        \"source_id\": 54,\n                        \"customer_full_name\": \"Ron Sher\",\n                        \"job_title\": \"06_29_22_18\"\n                    }\n                }\n            ]\n        },\n        {\n            \"user_id\": 5298,\n            \"external_id\": \"a013900001aPXO1AAO\",\n            \"day_start\": \"2022-10-25T12:00:00Z\",\n            \"day_end\": \"2022-10-25T21:00:00Z\",\n            \"blocks\": []\n        }\n    ]\n}"}],"_postman_id":"7577e70a-b5f1-4fbf-b568-e21215daed67"},{"name":"Match Technicians","id":"165792c2-df72-44b6-b863-a3a258eecbee","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{token}}","type":"text"}],"url":"https://api-sandbox.dispatch.me/v3/search/contractors?postal_code=98004&availability_start_time=2020-08-15T00:00:00-04:00&availability_end_time=2020-08-19T12:00:00-04:00&appointment_duration_minutes=90&address=3000 Landerholm Cir SE, Bellevue, WA 98007&trades=hvac,cooling","description":"<p>The results returned by Match Technicians is similar to that returned by the <a href=\"#783107dd-0dcc-4095-aa6f-e9ba90cf2a10\">whitespace</a> API in that it returns a list of users that have the availability to work the appointment.</p>\n<p>However with this API, you pass in an address (along with some other parameters) and the API will determine which users can perform the job based on proximity (and other factors).</p>\n<p><strong>URL Parameters:</strong></p>\n<ul>\n<li>postal_code - zip code within which to search</li>\n<li>address - address where the job is to be performed (used for proximity calculations)</li>\n<li>appointment_duration_minutes - duration required for the appointment</li>\n<li>availability_start_time - start date/time from when to search for availability</li>\n<li>availability_end_time - end date/time until when to search for availlability</li>\n<li>trades (optional) - list of trades that technicians must have in order to be returned by the search (see <a href=\"#e5915a1c-089d-4fa6-a55d-61ada3206b7e\">here</a> for more information about trades)</li>\n</ul>\n","urlObject":{"protocol":"https","path":["v3","search","contractors"],"host":["api-sandbox","dispatch","me"],"query":[{"key":"postal_code","value":"98004"},{"key":"availability_start_time","value":"2020-08-15T00:00:00-04:00"},{"key":"availability_end_time","value":"2020-08-19T12:00:00-04:00"},{"key":"appointment_duration_minutes","value":"90"},{"key":"address","value":"3000 Landerholm Cir SE, Bellevue, WA 98007"},{"key":"trades","value":"hvac,cooling"}],"variable":[]}},"response":[{"id":"1dc0eb8b-8720-41f1-be87-efd95a82cd4c","name":"Match Users Response","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{token}}","type":"text"}],"url":{"raw":"http://api{{env}}.dispatch.me/v3/search/contractors?postal_code=98004&availability_start_time=2020-08-15T00:00:00-04:00&availability_end_time=2020-08-19T12:00:00-04:00&appointment_duration_minutes=90&address=3000 Landerholm Cir SE, Bellevue, WA 98007","protocol":"http","host":["api{{env}}","dispatch","me"],"path":["v3","search","contractors"],"query":[{"key":"postal_code","value":"98004"},{"key":"availability_start_time","value":"2020-08-15T00:00:00-04:00"},{"key":"availability_end_time","value":"2020-08-19T12:00:00-04:00"},{"key":"appointment_duration_minutes","value":"90"},{"key":"address","value":"3000 Landerholm Cir SE, Bellevue, WA 98007"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Tue, 01 Nov 2022 18:24:16 GMT"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Transfer-Encoding","value":"chunked"},{"key":"Connection","value":"keep-alive"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Allow-Headers","value":"Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Transaction-ID, X-Analytics-Tags, Analytics-Client-Id, X-Account-ID, X-API-Version, Client-Id"},{"key":"Access-Control-Allow-Methods","value":"DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Expose-Headers","value":"Content-Length"},{"key":"Access-Control-Max-Age","value":"86400"}],"cookie":[],"responseTime":null,"body":"{\n    \"matches\": [\n        {\n            \"entity\": {\n                \"id\": 13136628,\n                \"full_name\": \"Winthrop Sargent\",\n                \"external_ids\": [\n                    \"WinthropSargent98406\"\n                ],\n                \"organization_id\": 784868,\n                \"organization\": {\n                    \"id\": 784868,\n                    \"external_ids\": [\n                        \"275239\"\n                    ]\n                }\n            },\n            \"entity_type\": \"user\",\n            \"entity_id\": 13136628,\n            \"slots\": [\n                {\n                    \"start\": \"2020-08-15T08:00:00-07:00\",\n                    \"end\": \"2020-08-15T18:00:00-07:00\",\n                    \"ranking_score\": 0,\n                    \"miles_from_start\": 39.370613,\n                    \"miles_to_end\": 41.077026,\n                    \"miles_added\": 80.44763\n                },\n                {\n                    \"start\": \"2020-08-16T08:00:00-07:00\",\n                    \"end\": \"2020-08-16T18:00:00-07:00\",\n                    \"ranking_score\": 0,\n                    \"miles_from_start\": 39.370613,\n                    \"miles_to_end\": 41.077026,\n                    \"miles_added\": 80.44763\n                },\n                {\n                    \"start\": \"2020-08-17T08:00:00-07:00\",\n                    \"end\": \"2020-08-17T18:00:00-07:00\",\n                    \"ranking_score\": 0,\n                    \"miles_from_start\": 39.370613,\n                    \"miles_to_end\": 41.077026,\n                    \"miles_added\": 80.44763\n                },\n                {\n                    \"start\": \"2020-08-18T08:00:00-07:00\",\n                    \"end\": \"2020-08-18T18:00:00-07:00\",\n                    \"ranking_score\": 0,\n                    \"miles_from_start\": 39.370613,\n                    \"miles_to_end\": 41.077026,\n                    \"miles_added\": 80.44763\n                }\n            ]\n        },\n        {\n            \"entity\": {\n                \"id\": 13301276,\n                \"full_name\": \"Ted Fung\",\n                \"external_ids\": [\n                    \"tedfungevprod\"\n                ],\n                \"organization_id\": 1069976,\n                \"organization\": {\n                    \"id\": 1069976,\n                    \"external_ids\": [\n                        \"1069976\"\n                    ]\n                }\n            },\n            \"entity_type\": \"user\",\n            \"entity_id\": 13301276,\n            \"slots\": [\n                {\n                    \"start\": \"2020-08-15T08:00:00-07:00\",\n                    \"end\": \"2020-08-15T18:00:00-07:00\",\n                    \"ranking_score\": 0,\n                    \"miles_from_start\": 4.6367455,\n                    \"miles_to_end\": 4.609716,\n                    \"miles_added\": 9.246462\n                },\n                {\n                    \"start\": \"2020-08-16T08:00:00-07:00\",\n                    \"end\": \"2020-08-16T18:00:00-07:00\",\n                    \"ranking_score\": 0,\n                    \"miles_from_start\": 4.6367455,\n                    \"miles_to_end\": 4.609716,\n                    \"miles_added\": 9.246462\n                },\n                {\n                    \"start\": \"2020-08-17T08:00:00-07:00\",\n                    \"end\": \"2020-08-17T18:00:00-07:00\",\n                    \"ranking_score\": 0,\n                    \"miles_from_start\": 4.6367455,\n                    \"miles_to_end\": 4.609716,\n                    \"miles_added\": 9.246462\n                },\n                {\n                    \"start\": \"2020-08-18T08:00:00-07:00\",\n                    \"end\": \"2020-08-18T18:00:00-07:00\",\n                    \"ranking_score\": 0,\n                    \"miles_from_start\": 4.6367455,\n                    \"miles_to_end\": 4.609716,\n                    \"miles_added\": 9.246462\n                }\n            ]\n        }\n    ]\n}"}],"_postman_id":"165792c2-df72-44b6-b863-a3a258eecbee"},{"name":"Match Orgs","id":"7e79741c-3c7f-48fe-bb3c-60d8989fe377","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://api-sandbox.dispatch.me/v3/search/oms?postal_code=80207","description":"<p>This API returns orgs (providers/vendors) that match the criteria input. For example, if you pass in a zip code of <code>80207</code> it returns the list of orgs that service this zip code.</p>\n<p>Additional match parameters for match are supported however not yet updated in this documentation.</p>\n","urlObject":{"protocol":"https","path":["v3","search","oms"],"host":["api-sandbox","dispatch","me"],"query":[{"key":"postal_code","value":"80207"}],"variable":[]}},"response":[{"id":"5d86973f-8f22-41ba-904c-342d1e14208e","name":"Match Orgs","originalRequest":{"method":"GET","header":[{"key":"Authorization","value":"Bearer {{token}}","type":"text"}],"url":{"raw":"http://api.dispatch.me/v3/search/oms?postal_code=80207","protocol":"http","host":["api","dispatch","me"],"path":["v3","search","oms"],"query":[{"key":"postal_code","value":"80207"}]}},"status":"OK","code":200,"_postman_previewlanguage":"json","header":[{"key":"Date","value":"Sun, 12 Feb 2023 13:49:17 GMT"},{"key":"Content-Type","value":"application/json; charset=utf-8"},{"key":"Content-Length","value":"1640"},{"key":"Connection","value":"keep-alive"},{"key":"Access-Control-Allow-Credentials","value":"true"},{"key":"Access-Control-Allow-Headers","value":"Origin, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, X-Transaction-ID, X-Analytics-Tags, Analytics-Client-Id, X-Account-ID, X-API-Version, Client-Id"},{"key":"Access-Control-Allow-Methods","value":"DELETE, GET, HEAD, OPTIONS, PATCH, POST, PUT"},{"key":"Access-Control-Allow-Origin","value":"*"},{"key":"Access-Control-Expose-Headers","value":"Content-Length"},{"key":"Access-Control-Max-Age","value":"86400"}],"cookie":[],"responseTime":null,"body":"{\n    \"account_organizations\": [\n        {\n            \"organization_id\": 200383,\n            \"external_ids\": [\"org_external_id\"]\n        }\n    ]\n}"}],"_postman_id":"7e79741c-3c7f-48fe-bb3c-60d8989fe377"}],"id":"d184cc9a-674a-44ad-ab40-1858ec734225","description":"<p>The availability APIs are by definition real time and therefore need to use the <a href=\"#47fc3b18-adf8-40dd-a2be-6f192bafa18b\">oauth authentication method.</a></p>\n<p>Please request oauth keys from Dispatch if you don't already have them.</p>\n<p>The following APIs can be used to determine availability</p>\n<ul>\n<li>Whitespace - show times available</li>\n<li>Block Times - show times not available</li>\n<li>Match Technicians - show available using matching techniques (advanced)</li>\n</ul>\n<p>Choosing which one to use is at your discretion depending on what better suits your requirement.</p>\n<p>All APIs take into account the following to determine availability:</p>\n<ul>\n<li>Start/End Time of Work Days</li>\n<li>Existing appointments on schedule</li>\n<li>Existing events on schedule</li>\n</ul>\n","_postman_id":"d184cc9a-674a-44ad-ab40-1858ec734225"},{"name":"Inbox Messages","item":[{"name":"Inbox Messages","id":"f6f5581a-f3d3-473a-9bbe-6cf7a8f9fbbb","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"formdata","formdata":[]},"url":"https://connect-sbx.dispatch.me/agent/out","description":"<h1 id=\"overview\">Overview</h1>\n<p>Messages will have the following format. The <code>sender</code> will either be <code>customer</code> (sent from customer) or <code>organization</code> sent from provider.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"Type\": \"inbox_message\",\n    \"Payload\": {\n        \"Data\": {\n            \"external_customer_id\": \"1850562-10797934\",\n            \"external_organization_id\": \"9229ADAM\",\n            \"sender\": \"customer\",\n            \"message_content\": \"Stop texting me!!\"\n        }\n    }\n}\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["agent","out"],"host":["connect-sbx","dispatch","me"],"query":[],"variable":[]}},"response":[],"_postman_id":"f6f5581a-f3d3-473a-9bbe-6cf7a8f9fbbb"}],"id":"e27c2091-878b-4076-bbe7-a146ef928658","event":[{"listen":"prerequest","script":{"id":"7f485883-a546-48ce-9189-caeab4213903","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"137c9d46-04e5-4731-8167-8fdfbd82ef8a","type":"text/javascript","exec":[""]}}],"_postman_id":"e27c2091-878b-4076-bbe7-a146ef928658","description":""}],"id":"d3bae626-b827-45bf-a713-bdb25357011a","description":"<h1 id=\"payload-structure\">Payload Structure</h1>\n<p>Every payload that you pick up from the <code>agent/out</code> endpoint will include the following payload wrapper. The details inside the <code>Payload</code> key will contain the relevant updates for your system. The wrapper elements - specifically <code>ProcedureID</code>and <code>Receipt</code> are used to mark the payload as having been received and will remove the payload from the queue. The technical steps for doing so are best illustrated in the <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/DispatchOutbound\">outbound code samples</a>.</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">[\n   {\n    \"Message\": {\n      \"Request\": {\n        \"ProcedureID\": \"b332b621-f7ef-405d-8075-7332aef9bba7\",\n        \"Type\": \"some_type\",\n        \"Payload\": {\n          \"some_payload\": \"either the canonical described in this document or an agreed upon custom format\"\n        }\n      },\n      \"ID\": \"ed172c8b-aba0-4f1b-b477-6dc9c487fcbd\",\n      \"Receipt\": \"AQEBQ4Uw8YrVICgfZjXqtQhK6/PBodouACu8J4P0z27ysnHLTi7rC0r7cueMFnq9CuDpG6lXtCTKdXrjjrUM0GTi3PCY/tjCAd8uC77KN3tTLGFwiSKRUHoni4wLqRjyvNYnJFv2Y1sHn8DSgSIzB8kx5Zv6krK17jvzwhxom0+nM5g99iuavW+TtrDdnQVwc5lPw5/q+AuxSVzkWQS3eyP1AVXpXUpRUuDutvPggo8890HPPO6p+BfPZ1STxB1bN62PXuRRgG1RMu+O3vfP78kGR+DWkJSUr4kDuX3LLhztNtTgyPY6BQbcF7SZBMNExGkf+B1LbUlDmXtd33U5QjAXzw==\"\n    }\n  }\n]\n</code></pre>\n<p>The following conventions apply to all event processing:</p>\n<ul>\n<li><code>external_id</code> - This is the Enterprise's record ID</li>\n<li><code>updated_at</code> - Use this to mark the time the event occured</li>\n</ul>\n<h1 id=\"design-considerations\">Design Considerations</h1>\n<p>The structures defined in this section are our default. If you already have your own preferred structure and/or format in which you prefer to receive the data, please let us know - there's a good chance we'll be able to accomodate you.</p>\n<p>Please be aware that we may put additional events in the stream as our product evolves. Although we will not <em>change</em> the names of attributes in the payload, it is possible that we'll add <em>new</em> attributes to the payload. Therefore make sure that your payload consumption will not break if a new attribute starts being included.</p>\n<h1 id=\"polling-design-best-practices\">Polling Design Best Practices</h1>\n<ul>\n<li><p>Each time you poll the agent/out endpoint you should pull down using a <code>maxNumberOfMessages</code> of 10 (this is currently the highest number of messages you can request at a time). If the messages returned is equal to <code>maxNumberOfMesssages</code> you should poll again. Repeat until the queue is empty. In this way, you will clear out the queue each time you poll which ensures that your updates will be timely and the queue will remain low. The <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/DispatchOutbound\">code samples</a> incorporate this logic in them - be sure to follow this guidance! </p>\n</li>\n<li><p>Make sure to \"ack\" each message directly after downloading it. That is, you should NOT poll for 10 messages, process them all and then ack each message. Instead you should poll for 10 messages, process the first and then ack it, process the second and ack it and so on. This is important because there is an expiration (typically 30 seconds) to ack a polled message and if you do it after that time, the ack will be rejected and the message will stay in the queue until you poll it again. Again the <a href=\"https://github.com/Nahis/dispatchme/tree/master/dispatch-connect/samples/DispatchOutbound\">code samples</a> incorporate this logic in them, so if you follow the pattern shown you'll be in good shape.</p>\n</li>\n<li><p>Separate polling the endpoint from the business logic to update your business system. Often business logic (including multiple API interplay steps) can be involved and slow the system down. You should instead download the messages into a local store (e.g. sql table) and \"ack\" immediately after which lets us know that you received the message. From there you can process into your business systems as necessary. Needless to say, if you process directly to your business system and that takes \"too long\", you will run into the expiration issue mentioned above.</p>\n</li>\n<li><p>Only have a single process that polls the endpoint. If you have multiple processes polling the endpoint they can interfere with one another (as SQS makes messages invisible to other processes from the process being polled in order to prevent a message from being processed more than once). If you wish to employ multiple processes to poll the endpoint, then you should ensure that they are timed to alternate with one another and you should reach out Dispatch as we may need to tune the queue based on your polling strategy.</p>\n</li>\n<li><p>If for some reason you get an exception while locally storing a message, do not ack the message. If you do, the message will disappear from the queue and there will be data loss. By not acking it, you are ensuring that the message remains on the queue for processing the next time you poll. However, please be aware that if you are repeatedly getting exceptions while locally storing a message, the queue will grow and will block processing due to the FIFO nature of the queue. Therefore you should be sure to research this event should it occur to prevent a backlog (which will have the affect of delaying the timely processing of messages sent from Dispatch)</p>\n</li>\n</ul>\n","event":[{"listen":"prerequest","script":{"id":"23eb8622-9e76-4d04-98f9-9f6be63fcdbe","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"23d2589f-cdec-4f55-8a3c-2f48ffd3bdea","type":"text/javascript","exec":[""]}}],"_postman_id":"d3bae626-b827-45bf-a713-bdb25357011a"}],"id":"39c4cc81-2e84-487d-b1f4-a3e98204916d","description":"<p>The sections above describe the \"Quick Start\" connector integration scenarios. </p>\n<p>Beyond that, there may be other scenarios for your use case. The intention of this section is to document these. Please note that this section will use the API canonical format for documenting inbound and outbound requests. However, as mentioned in other sections of this document, we are not limited to that and if you have a format for integration that is more native to your platform - that is not a problem. Just describe those to us and we'll work on mapping them to/from the Dispatch Platform.</p>\n","event":[{"listen":"prerequest","script":{"id":"f3187ada-257c-4d30-b112-bd5e56959f98","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"bfe58c9c-de01-4765-a4e7-381457b10d4b","type":"text/javascript","exec":[""]}}],"_postman_id":"39c4cc81-2e84-487d-b1f4-a3e98204916d"}],"event":[{"listen":"prerequest","script":{"id":"17ea7d55-6ce5-46a9-97fe-8c077f5076e1","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"6d43753b-2e7c-4452-98de-0d65efb3a44a","type":"text/javascript","exec":[""]}}]}