{"info":{"_postman_id":"c24855b4-ee38-47a5-9de5-4c795020bba0","name":"[public] Octolis data API","description":"<html><head></head><body><p><strong>This is the doc for the usage of the Octolis data API.</strong></p>\n<p>Using this API, you can send/retrieve data to/from <em>Datasets</em>, and send data to our <em>Webhooks</em>.<br>Please refer to our <a href=\"https://help.octolis.com/#82ad9bed6e134af581dc9f341391a5fe\">concepts docs</a> if needed.</p>\n<p><strong>Authentification</strong></p>\n<p>Authentification works using a simple <code>api-key</code> query parameter.<br>If creating API keys is not available in your account, please reach out to your account manager.</p>\n<p><strong>How to use this doc?</strong></p>\n<p>This doc is built on Postman, you can click on \"Run in Postman\" in the top right corner to clone it and start using it directly!</p>\n</body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[],"owner":"4058140","collectionId":"c24855b4-ee38-47a5-9de5-4c795020bba0","publishedId":"Uyr5neCQ","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"4F33FA"},"publishDate":"2022-04-16T09:38:59.000Z"},"item":[{"name":"Datasets Data API","item":[{"name":"Upsert record (by deduplication key)","id":"cbd634a2-2f35-439f-8c25-a30aefb99770","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n    \"email\": \"jeannerenard1183@gmail.com\",\n    \"firstname\": \"Jeanne\",\n    \"consent_sms\": false\n}","options":{"raw":{"language":"json"}}},"url":"https://api.octolis.cloud/v1/data/datasets/{{datasetId}}/records?api-key={{dataApiKey}}","description":"<p><strong>This endpoints enables you to perform real-time deduplication of your record over the</strong> <em><strong>Dataset</strong></em><strong>'s ones, using your</strong> <strong>Dataset's</strong> <strong>deduplication keys.</strong></p>\n<p>The payload should be a JSON object containing:</p>\n<ol>\n<li>Mandatorily your <em>Dataset</em>'s deduplication key column(s).</li>\n<li>The other column(s) of your record that you want to populate/update.<br /> If you have some Dataset column(s) with default values and you want your record to take that default value, don't include those column(s) as variables of the object (any value you would supply would otherwise be taken into account, including null).</li>\n<li>The variables' names of this object should be the exact ones as your <em>Dataset</em>'s columns.</li>\n</ol>\n<p>The response will be a <code>record</code> object containing all the <em>Dataset</em> base columns (before any preparation), including the <em>Dataset</em>'s default columns (that you might not have supplied in the payload) and <a href=\"https://help.octolis.com/faq/faq/what-is-deduplication-and-how-does-it-work\">system columns</a>.</p>\n<p>NB: If your upsert triggered a deduplication between several already existing records, you will find the masterids of those (now deleted) records in the <strong><code>__all_masterids__</code></strong> variable.</p>\n<p>Response example:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"record\": {\n        \"email\": \"jeannerenard1183@gmail.com\",\n        \"firstname\": \"Jeanne\",\n        \"consent_sms\": false,\n        \"__modified_at__\": \"2022-05-10T12:44:53.278Z\",\n        \"__masterid__\": \"28d912a6-e6c5-40c8-8ec6-9803498d86f0\",\n        \"__all_masterids__\": [\n            \"a79ac906-5f91-1e53-9c77-d7d0600aaa9c\",\n            \"0547d332-f605-6641-0339-d377757f59ae\"\n        ]\n        \"__created_at__\": \"2022-05-10T12:44:53.501Z\",\n        \"__updated_at__\": \"2022-05-10T12:44:53.501Z\"\n    }\n}\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["v1","data","datasets","{{datasetId}}","records"],"host":["api","octolis","cloud"],"query":[{"description":{"content":"<p>Your API key (mandatory).</p>\n","type":"text/plain"},"key":"api-key","value":"{{dataApiKey}}"}],"variable":[]}},"response":[],"_postman_id":"cbd634a2-2f35-439f-8c25-a30aefb99770"},{"name":"Batch Upsert records (by deduplication key)","id":"c60f8baf-8fec-453b-ba4e-ad6a19083dbe","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"POST","header":[],"body":{"mode":"raw","raw":"[\n    {\n        \"email\": \"jeannerenard1183@gmail.com\",\n        \"firstname\": \"Jeanne\",\n        \"consent_sms\": false\n    },\n    {\n        \"email\": \"teodupont1186@gmail.com\",\n        \"firstname\": \"Théo\",\n        \"consent_sms\": false\n    }\n]","options":{"raw":{"language":"json"}}},"url":"https://api.octolis.cloud/v1/data/datasets/{{datasetId}}/records/batch?api-key={{dataApiKey}}","description":"<p><strong>This endpoints enables you to perform batch real-time deduplication of up to 500 records over the</strong> <em><strong>Dataset</strong></em><strong>'s ones, using your</strong> D<strong>ataset's deduplication keys.</strong></p>\n<p>All rules from the unitary Upsert endpoint apply.</p>\n<p>The response will look like the following:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"results\": [\n        {\n            \"written\": true,\n            \"record\": {\n                \"email\": \"jeannerenard1183@gmail.com\",\n                \"phone\": null,\n                \"firstname\": \"ee\",\n                \"lastname\": null,\n                \"other\": null,\n                \"created_at\": null,\n                \"__modified_at__\": \"2022-09-14T16:12:24.073Z\",\n                \"__masterid__\": \"6692c38b-c8fe-b69a-11c2-67a3e95b2b39\",\n                \"__all_masterids__\": [\n                    \"6692c38b-c8fe-b69a-11c2-67a3e95b2b39\"\n                ],\n                \"__created_at__\": \"2022-09-14T16:00:33.364Z\",\n                \"__updated_at__\": \"2022-09-14T16:12:24.248Z\"\n            },\n            \"warnings\": {\n                \"protected_columns\": [\n                    \"lastname\"\n                ]\n            }\n        },\n        {\n            \"written\": false,\n            \"error\": {\n                \"title\": \"Missing mandatory columns from the upsertion data\",\n                \"detail\": \"Missing the following mandatory columns: firstname\",\n                \"status\": 400,\n                \"missing\": [\n                    \"firstname\"\n                ]\n            }\n        }\n    ]\n}\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["v1","data","datasets","{{datasetId}}","records","batch"],"host":["api","octolis","cloud"],"query":[{"description":{"content":"<p>Your API key (mandatory).</p>\n","type":"text/plain"},"key":"api-key","value":"{{dataApiKey}}"}],"variable":[]}},"response":[],"_postman_id":"c60f8baf-8fec-453b-ba4e-ad6a19083dbe"},{"name":"Update record (by masterId)","id":"8c7c4099-3fc0-4b29-8ef1-ff9a9800fff4","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"PATCH","header":[],"body":{"mode":"raw","raw":"{\n    \"firstname\": \"Jeanne\",\n    \"consent_sms\": false\n}","options":{"raw":{"language":"json"}}},"url":"https://api.octolis.cloud/v1/data/datasets/{{datasetId}}/records/{{recordMasterId}}?api-key={{dataApiKey}}","description":"<p><strong>This endpoints enables you to perform real-time update of a record inside of the</strong> <em><strong>Dataset</strong></em><strong>,</strong> ** using its Octolis masterId.**</p>\n<p>The payload should be a JSON object the column(s) of your record that you want to update. All the same formatting rules as the upsert endpoint apply here.</p>\n<p>The response will be a <code>record</code> object containing all the Dataset base columns (before any preparation), including the <em>Dataset</em>'s default columns (that you might not have supplied in the payload) and <a href=\"https://help.octolis.com/faq/faq/what-is-deduplication-and-how-does-it-work\">system columns</a>.</p>\n<p>Nb: if you update a key column, please pay attention that it does not violate their uniqueness constraint. If so, you will get an error. Please rather use the Upsert deduplication endpoint in that case.</p>\n<p>Response example:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"record\": {\n        \"email\": \"jeannerenard1183@gmail.com\",\n        \"firstname\": \"Jeanne\",\n        \"consent_sms\": false,\n        \"__modified_at__\": \"2022-05-10T12:44:53.278Z\",\n        \"__masterid__\": \"28d912a6-e6c5-40c8-8ec6-9803498d86f0\",\n        \"__created_at__\": \"2022-05-10T12:44:53.501Z\",\n        \"__updated_at__\": \"2022-05-10T12:44:53.501Z\"\n    }\n}\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["v1","data","datasets","{{datasetId}}","records","{{recordMasterId}}"],"host":["api","octolis","cloud"],"query":[{"description":{"content":"<p>Your API key (mandatory).</p>\n","type":"text/plain"},"key":"api-key","value":"{{dataApiKey}}"}],"variable":[]}},"response":[],"_postman_id":"8c7c4099-3fc0-4b29-8ef1-ff9a9800fff4"},{"name":"Batch Update records (by masterId)","id":"d26ef4e2-d7bf-494a-86d3-343531f496cc","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"PATCH","header":[],"body":{"mode":"raw","raw":"[\n    {\n        \"firstname\": \"Jeanne\",\n        \"consent_sms\": false,\n        \"__masterid__\": \"a1912b0b-c9c4-4385-a7ff-c37fa07d400e\"\n    },\n    {\n        \"firstname\": \"Alex\",\n        \"consent_sms\": true,\n        \"__masterid__\": \"000d657b-2e34-48cd-8c3a-61cc938b3ab7\"\n    }\n]","options":{"raw":{"language":"json"}}},"url":"https://api.octolis.cloud/v1/data/datasets/{{datasetId}}/records/batch?api-key={{dataApiKey}}","description":"<p><strong>This endpoints enables you to perform real-time batch update of up to 500 record inside of the</strong> <em><strong>Dataset</strong></em><strong>,</strong> <strong>using their Octolis masterId.</strong></p>\n<p>All rules from the unitary Update endpoint apply (except the <code>__masterid__</code> must be included inside of each record).</p>\n<p>The response will look like the \"Batch Upsert records\" one.</p>\n","urlObject":{"protocol":"https","path":["v1","data","datasets","{{datasetId}}","records","batch"],"host":["api","octolis","cloud"],"query":[{"description":{"content":"<p>Your API key (mandatory).</p>\n","type":"text/plain"},"key":"api-key","value":"{{dataApiKey}}"}],"variable":[]}},"response":[],"_postman_id":"d26ef4e2-d7bf-494a-86d3-343531f496cc"},{"name":"Get a prepared record (by masterId)","id":"872ffbaa-bd20-4c0f-85c0-a81eb808aca2","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"GET","header":[],"url":"https://api.octolis.cloud/v1/data/datasets/{{datasetId}}/records/{{recordMasterId}}?api-key={{dataApiKey}}","description":"<p><strong>This endpoint enables you to get an</strong> <em><strong>Dataset</strong></em> <strong>prepared record by its masterId.</strong></p>\n<p>The response will be a \"record\" object containing all the <em>Dataset</em> final columns (after preparation), including <a href=\"https://help.octolis.com/faq/faq/what-is-deduplication-and-how-does-it-work\">Octolis system columns</a>.</p>\n<p>NB: If your record results from the deduplication between several records, you will find the masterids of those (now deleted) records in the <strong><code>__all_masterids__</code></strong> variable of the record object. In that case, you will also find an additional isMerged property next to the <code>record</code> object.</p>\n<p>Response example:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"record\": {\n        \"email\": \"jeannerenard1183@gmail.com\",\n        \"firstname\": \"Jeanne\",\n        \"consent_sms\": false,\n        \"__modified_at__\": \"2022-05-10T12:44:53.278Z\",\n        \"__masterid__\": \"28d912a6-e6c5-40c8-8ec6-9803498d86f0\",\n        \"__all_masterids__\": [\n            \"a79ac906-5f91-1e53-9c77-d7d0600aaa9c\",\n            \"0547d332-f605-6641-0339-d377757f59ae\"\n        ],\n        \"__created_at__\": \"2022-05-10T12:44:53.501Z\",\n        \"__updated_at__\": \"2022-05-10T12:44:53.501Z\"\n    },\n    \"isMerged\": true\n}\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["v1","data","datasets","{{datasetId}}","records","{{recordMasterId}}"],"host":["api","octolis","cloud"],"query":[{"description":{"content":"<p>Your API key (mandatory).</p>\n","type":"text/plain"},"key":"api-key","value":"{{dataApiKey}}"}],"variable":[]}},"response":[],"_postman_id":"872ffbaa-bd20-4c0f-85c0-a81eb808aca2"},{"name":"Get prepared records (by filters)","id":"4826acf0-6cd7-406e-9e8c-29a35dc5a227","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"GET","header":[],"url":"https://api.octolis.cloud/v1/data/datasets/{{datasetId}}/records?api-key={{dataApiKey}}&format=csv&header=false&filter=firstname:Marc,firstName:Jeanne,consent_sms:true&selection=email,firstname,__masterid__&page=1&pageSize=10&order=asc","description":"<p><strong>This endpoint enables you to export all or part of your</strong> <em><strong>Dataset</strong></em><strong>'s prepared records, either in JSON or CSV format.</strong></p>\n<p>You can also additionally supply filters and a selection of the columns to include in the export.</p>\n<p>The response will be a \"records\" array of objects (for the default JSON format, otherwise it's a simple CSV file with one line per record), each one of them containing all the <em>Dataset</em> final columns (after preparation), including <a href=\"https://help.octolis.com/faq/faq/what-is-deduplication-and-how-does-it-work\">Octolis system columns</a>.</p>\n<p>Response example:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"records\": [{\n        \"email\": \"jeannerenard1183@gmail.com\",\n        \"firstname\": \"Jeanne\",\n        \"consent_sms\": true,\n        \"__modified_at__\": \"2022-05-10T12:44:53.278Z\",\n        \"__masterid__\": \"28d912a6-e6c5-40c8-8ec6-9803498d86f0\",\n        \"__created_at__\": \"2022-05-10T12:44:53.501Z\",\n        \"__updated_at__\": \"2022-05-10T12:44:53.501Z\"\n    }]\n}\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["v1","data","datasets","{{datasetId}}","records"],"host":["api","octolis","cloud"],"query":[{"description":{"content":"<p>Your API key (mandatory).</p>\n","type":"text/plain"},"key":"api-key","value":"{{dataApiKey}}"},{"description":{"content":"<p>Export format (optional): \"csv\" or \"json\" (default).</p>\n","type":"text/plain"},"key":"format","value":"csv"},{"description":{"content":"<p>Export headers for CSV format (optional): \"true\" (default) or \"false\".</p>\n","type":"text/plain"},"key":"header","value":"false"},{"description":{"content":"<p>Equality filters applied on the records (optional). \nUsing several filters on the same column will result in an OR condition.\ne.g. (firstname = Marc OR firstName = Jeanne) AND consent_sms IS true</p>\n","type":"text/plain"},"key":"filter","value":"firstname:Marc,firstName:Jeanne,consent_sms:true"},{"description":{"content":"<p>Selection of columns that should be retrieved (optional).</p>\n","type":"text/plain"},"key":"selection","value":"email,firstname,__masterid__"},{"description":{"content":"<p>Results page number (optional): positive integer (\"1\" by default).</p>\n","type":"text/plain"},"key":"page","value":"1"},{"description":{"content":"<p>Results page size (optional): positive integer (\"50000\" by default, which also is the maximum size of a page).</p>\n","type":"text/plain"},"key":"pageSize","value":"10"},{"description":{"content":"<p>Sorting for the results (optional): \"asc\" or \"desc\" (default), done on our system modified_at column.</p>\n","type":"text/plain"},"key":"order","value":"asc"}],"variable":[]}},"response":[],"_postman_id":"4826acf0-6cd7-406e-9e8c-29a35dc5a227"},{"name":"Count records","id":"7a21046c-eeeb-42e4-8e7a-35a606d07d3d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"auth":{"type":"noauth","isInherited":false},"method":"GET","header":[],"url":"https://api.octolis.cloud/v1/data/datasets/{{datasetId}}/records/count?api-key={{dataApiKey}}&format=csv&header=false&filter=firstname:Marc,firstName:Jeanne,consent_sms:true","description":"<p><strong>This endpoint enables you to get a count for all or part of your</strong> <em><strong>Dataset</strong></em><strong>'s records, either in JSON or CSV format.</strong></p>\n<p>You can also additionally supply filters and a selection of the columns to include in the export.</p>\n<p>The response will be an object with a \"count\" variable.</p>\n<p>Response example:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"count\": 741\n}\n\n</code></pre>\n","urlObject":{"protocol":"https","path":["v1","data","datasets","{{datasetId}}","records","count"],"host":["api","octolis","cloud"],"query":[{"description":{"content":"<p>Your API key (mandatory).</p>\n","type":"text/plain"},"key":"api-key","value":"{{dataApiKey}}"},{"description":{"content":"<p>Export format (optional): \"csv\" or \"json\" (default).</p>\n","type":"text/plain"},"key":"format","value":"csv"},{"key":"header","value":"false"},{"description":{"content":"<p>Equality filters applied on the records (optional). \nUsing several filters on the same column will result in an OR condition.\ne.g. (firstname = Marc OR firstName = Jeanne) AND consent_sms IS true</p>\n","type":"text/plain"},"key":"filter","value":"firstname:Marc,firstName:Jeanne,consent_sms:true"}],"variable":[]}},"response":[],"_postman_id":"7a21046c-eeeb-42e4-8e7a-35a606d07d3d"}],"id":"5e39bae3-8e32-482a-9464-8cb7d9f8be44","description":"<p><strong>This API enables you to send/retrieve data to/from one of your</strong> <em><strong>Datasets</strong></em><strong>.</strong></p>\n<p>Octolis Data API integrates with the <em>Datasets</em> in three steps:<br />1. Synchronously deduplicate records and get a masterId: see the Upsert record(s) endpoint.<br />2. Asynchronously prepare the deduplicated records using the <em>Dataset</em>'s preparation steps: done behind the scenes each time you upsert/update something.<br />3. Get the final shape of each record: see the Get record(s) endpoints.</p>\n<p>All endpoints always refer to an <em>Dataset</em> by its Id and require an API key. If you don't know your <em>Dataset</em> Id or API key, please reach out to your account manager.</p>\n<p>NB:<br />- you can also update a record by its masterid, see the Update record(s) endpoint.<br />- you can't write to a SQL Dataset, only read from it.</p>\n<p><strong>Guidelines for better performance</strong></p>\n<p>Always prefer the use of batch Upsert &amp; Update endpoints over the unitary ones, and concurrent requests over sequential ones.</p>\n<p>Please pay attention to the fact that for high volumes (especialy for orders), implementing batch method will be mandatory to respect our rate limiting.</p>\n<p><strong>Headers</strong></p>\n<p>For all requests <code>Accept</code> and <code>Content-Type</code> headers are mandatory.</p>\n<p>Use the following values :</p>\n<ul>\n<li>Accept : */*</li>\n<li>Content-Type : application/json</li>\n</ul>\n<p><strong>Errors handling</strong></p>\n<p>On top of usual errors (401, 403, 404...), errors you might get are of two types:</p>\n<p>1. Error 400: Your payload is invalid.</p>\n<p>2. Error 423 (only applies to Upsert/Update enpoints): The <em>Dataset</em> is busy due to a user action. Usually either because a user is updating the structure of the Dataset (e.g. adding a column), or one of the other <em>Sources</em> is currently executing (we can't allow concurrent writes from the Data API and another <em>Source</em> in order to ensure the unicity of the deduplication). In such a case, please wait a few seconds before retrying (usually 5s).</p>\n<p>For your information, all errors you might get will be in the following format:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"title\": \"Validation failed for the provided data\",\n    \"detail\": \"Validation for upsertion request failed\",\n    \"status\": 400,\n    \"values\": {\n        \"email\": \"jeannerenard1183@gmail.com\",\n        \"firstname\": \"Jeanne\",\n        \"consent_sms\": 25\n    },\n    \"errors\": [\n        \"consent_sms (#/properties/consent_sms/type) - must be boolean\"\n    ]\n}\n\n</code></pre>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"title\": \"Missing mandatory columns from the upsertion data\",\n    \"detail\": \"Missing the following mandatory columns: firstname\",\n    \"status\": 400,\n    \"missing\": [\n        \"firstname\"\n    ]\n}\n\n</code></pre>\n<p><strong>Reporting errors</strong></p>\n<p>If you encounter an error you don't understand and you want to open a ticket on our end, please include in your ticket: the exact time of your request, its payload, the answer (including the headers and especially the <code>apigw-requestid</code> &amp; <code>traceparent</code> if they are there).</p>\n<p><strong>Warnings</strong></p>\n<p>On top of errors you might also get some warnings, usually because you tried to write to a column that does not accept writes from the Dataset Data API (they are ignored).</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code class=\"language-json\">{\n    \"record\": {\n        \"my_key\": \"email@test.com\"\n        \"my_column\": \"some_value\"\n    },\n    \"warnings\": {\n        \"protected_columns\": [\n            \"my_column\"\n        ]\n    }\n}\n\n</code></pre>\n<p><strong>Data format</strong></p>\n<ul>\n<li>Dates and timestamps must be quoted date-time: <code>\"1978-06-23 00:00:00\"</code></li>\n<li>Booleans must be <code>true</code>, <code>false</code> or <code>null</code></li>\n<li>Text must be quoted: <code>\"text\"</code></li>\n<li>All numbers must be between <code>-2147483648</code> and <code>2147483647</code> inclusively.<br />  Floats must have a maximum of 6 digits.</li>\n</ul>\n<p>If you don't know the value of a column, omit the column.<br />If you want to erase a value / send an explicit empty value, send a <code>null</code> value, e.g. <code>\"column\": null</code></p>\n<p><strong>Rate limiting</strong></p>\n<p>We want to provide the best possible experience when you integrate into our platform.</p>\n<p>In order to ensure this service for all customers, we have put in place some limits to the number of requests that you are allowed to execute in a period of time.</p>\n<p>Rate limiting for the <em>Dataset</em> Data API applies the following rules:</p>\n<ul>\n<li>The following limits apply per API key, throughout all <em>Datasets</em> of your <em>Account</em>: 25 points per second plus 150 points per minute.</li>\n<li>The following limits apply per <em>Account</em>, throughout all <em>Datasets</em> of the <em>Account</em>: 2000 points per minute.</li>\n<li>Both limits are applied to each request: as soon as one limit is reached, the request is rejected.</li>\n<li>Each read (GET) request costs 1 point.</li>\n<li>Each write (POST/PUT) request costs 10 points.</li>\n<li>This allows for bursts with cool-down periods:<ul>\n<li>e.g. up to 17 (= (25 + 150) / 10) write requests in a single second, then up to 2 (= 25 / 10) write requests per second for the next 59 seconds</li>\n</ul>\n</li>\n<li>All in all, it allows a maximum of 135 (= (25 / 10) * 60 + (150 / 10)) requests per minute for the first API key (= 135 * 500 = 67500 records written per minute with the batch endpoints).</li>\n<li>For additional API keys, the account limits will restrict the throughput.</li>\n</ul>\n<p>When a request gets rate-limited, you will get a <code>429 Too Many Requests</code> response, with a <code>Retry-After</code> header indicating how many seconds you should wait before sending a new request.</p>\n","auth":{"type":"noauth","isInherited":false},"event":[{"listen":"prerequest","script":{"id":"076a676b-da34-4fdc-bff0-afa1dfe8031f","type":"text/javascript","exec":[""]}},{"listen":"test","script":{"id":"65f40f85-9401-443a-b0d4-e95ed49d1728","type":"text/javascript","exec":[""]}}],"_postman_id":"5e39bae3-8e32-482a-9464-8cb7d9f8be44"},{"name":"Webhooks Data API","item":[],"id":"16683a38-9fc3-475e-808a-4b40b768714c","description":"<p><em>Webhooks</em> are widely used nowadays as they are key to allowing multiple systems to interconnect and keep actions consistent among them. They're also known as \"URL Callbacks\" or \"HTTP push calls\".</p>\n<p>When an event or status change occurs in a system, an HTTP request is sent to the given URL in real time. This call contains information related to that specific event. <em>E.g Time it occured, name of the event, key identifiers.</em></p>\n<p>Our <em>Webhook</em> typically look like the following: <code>https://api.octolis.cloud/v1/data/webhook/{{webhookId}}?api-key={{apiKey}}</code>.</p>\n<p>Our <em>Webhook</em> have several security features, make sure to synchronize with your account manager to know about the following:</p>\n<ul>\n<li><em>Webhook</em> Id</li>\n<li>Api Key</li>\n<li>Method: POST and/or PUT</li>\n<li>IP address whitelist: list of autorized IP addresses that are alowed to send data to the <em>Webhook</em>.</li>\n<li>Headers whitelist: list of header entries that each request to the <em>Webhook</em> must contain.</li>\n</ul>\n<p>Any request to a <em>Webhook</em> that does not use the right <em>Webhook</em> id, api key, method, IP address or header will be discarded.</p>\n<p>You can send any JSON payload to a <em>Webhook</em>, just make sure to send the data that is expected by your business needs.</p>\n","_postman_id":"16683a38-9fc3-475e-808a-4b40b768714c"}],"event":[{"listen":"prerequest","script":{"id":"96929983-71f5-4b75-b945-8fb2ba46fd52","type":"text/javascript","exec":["/**"," * Pre-request script ran before every API request."," *"," * Used to notify users that their access token has expired"," * "," * Based on work by box.com: https://developer.box.com/guides/tooling/postman/"," * "," * If you are using a flow that required clientSecret then uncomment those sections and add an environmental variable"," */","","// Determine if accessTokenExpiry exists in the environment","const expiresAt = pm.environment.get('access_token_expiry')","if (!expiresAt) {","    console.log('access_token_expiry does not exist, creating a new environment variable and setting it to an old expired date time')","    pm.environment.set('access_token_expiry', Number(1637945308569))","}","// Determine if the Access Token has expired","const expired = Date.now() > Number(expiresAt)","// Determine if the user has auto-refresh enabled","if (!pm.environment.get('auth_token_enable_auto_refresh')) {","    console.log('auth_token_enable_auto_refresh does not exist, creating a new environment variable and setting it to false')","    pm.environment.set('auth_token_enable_auto_refresh', false)","}","","const autoRefresh = String(pm.environment.get('auth_token_enable_auto_refresh')) === 'true'","// Determine if we have all the client credentials needed in the environment","const hasClientId = String(pm.environment.get('auth_client_id')).length > 0","const hasClientSecret = String(pm.environment.get('auth_client_secret')).length > 0","const hasAllCredentials = hasClientId && hasClientSecret","","// Determine if autoRefresh is enabled and only continue if it is.","if (!autoRefresh) {","    console.log('Auto refresh is disabled')","}","// If the access token expired and auto refresh has been set, use the refresh","// token to create a new access token","else if (expired && autoRefresh && hasAllCredentials) {","    console.log('All prerequisites are met so getting new access tokens')","    // Send a new API request to refresh the access token","    pm.sendRequest({","        url: pm.environment.get('auth_token_endpoint'),","        method: 'POST',","        header: 'Content-Type:application/json',","        body: {","            mode: 'raw',","            raw: JSON.stringify({","                grant_type: \"client_credentials\",","                client_id: pm.environment.get('auth_client_id'),","                client_secret: pm.environment.get('auth_client_secret'),","                audience: pm.environment.get('auth_audience')","            })","        }","    }, function (error, response) {","        if (error || response.json().error) {","            // If an error occurred, log the error and raise a message to the user.","            console.log('Could not refresh the access token')","            console.log(error)","            console.log(response.json())","            throw new Error('Could not refresh the access token. Check the console for more details.')","        } else {","            // Otherwise, fetch the new access token and store it","            const data = response.json()","","            // Determine when this token is set to expire at","            const newAccessTokenExpiresAt = Date.now() + data.expires_in * 1000","            // Store the new variables in the environment","            pm.environment.set('access_token', data.access_token)","            pm.environment.set('access_token_expiry', newAccessTokenExpiresAt)","            console.log('New access token stored successfully')","        }","    })","}"]}},{"listen":"test","script":{"id":"524078ef-0afe-48a7-8921-ed66da36b025","type":"text/javascript","exec":[""]}}]}