Yoobic Webhooks API

You can create webhooks with HTTP targets to build integrations with the services or with your back-end system. Examples: - Alert your team in Slack when a mission is created - Pass mission to your docs team in Asana after a mission is completed - Update Salesforce when a new store is created An HTTP target lets you pass information to third-party services and REST APIs that accept JSON in HTTP requests. The list of topics supporting webhooks are: - campaigns - courses - events - files - lessons - mission-workflows - missions - mission-comments - mission-services - store-types - stores - users - visits - webhooks - For visits, the `delete` action is not supported. To receive deleted visit objects you need to subscribe to the `missions` topic. The deleted visits are sent as their corresponding `mission` object as a visit is a sub-type of missions. - For mission-comments, only `create` and `update` actions are supported. See example use case [here](https://yoobic.zendesk.com/hc/en-gb/articles/14909941328274-Ticketing-System-Integration-Setup-Guide-Synchronise-Requests-and-Comments-With-External-Tickets#h_01HEJEZ7VEZSGHBCZH7C569T8A). - For mission-services, only `create` and `update` actions are supported. See example use case [here](https://yoobic.zendesk.com/hc/en-gb/articles/14909941328274-Ticketing-System-Integration-Setup-Guide-Synchronise-Requests-and-Comments-With-External-Tickets#h_01HEJCJBH9B9G62R79FBGKA29N). - If the webhook has a filter, the webhook will fire only once per object when it matches the filter the first time. For example, if the webhook is on topic `missions` , operations `update` and the filter is `{"status": "finished"}`, then each mission will trigger a new message only when it is `finished`. If another update happens later, to validate the mission for example, it will not fire a new message. - To send multiple messages for the same object and operation, set `trigger_on_every_match` to true. For example if you want to track every update for `mission-workflows` for every step of the workflow. - On mission-workflows, possible to filter on `step_title` and `state`. Both can be used together to **only** fire the webhook when a step is reached. Otherwise, having only a filter on `step_title` results in the webhook firing twice when the step is reached due to the mission being updated when it is assigned to a user. - The object output of mission-workflows contains the same fields as for a regular mission, with an addition of `workflow_step_title`, `workflow_step_id` and `workflow_state`. #### Errors If a webhook fails it becomes inactive. In addition a failure object with the http status and reason are set on the webhook's object. ``` { "is_active": false", "error": { "status": 404, "message": "Not Found." } } ``` Once the webhook becomes active again, the error object will be cleared. i.e. a PATCH request to fix the broken webhook: ``` { "is_active": true, "url": "" } ``` #### Callback response body The callback url will have the following fields - - action: create/update/delete - topic: one of the supported topics i.e. store-types - data: the actual entity - updatedFields: list of fields that were updated ``` { "action": "update", "topic": "store-types", "data": { "store_type_id": "56b0c262e9a22a4e5f02be7d", "name": "ice-cream", "group_ids": ["managers"], "created_date": "2016-02-02T14:51:14.644Z", "updated_date": "2020-07-15T14:18:41.750Z" }, "updatedFields": [ "group_ids" ] } ``` #### Security Webhooks provide an additional security measure to verify that the webhook is genuine and has come from YOOBIC. This can be useful if you're looking to ensure only YOOBIC webhooks are being made to your endpoint and ensure the information is genuine and as the system expects. These signatures will also help prevent against replay attacks. Verifying the signing secret is optional. When registering a webhook you can set an additional `secret` field in the payload. Webhook requests will contain two headers which can be used to verify the request's authenticity: - `x-yoobic-webhook-signature` - the main signature - `x-yoobic-webhook-signature-timestamp` - the timestamp used to verify the signature This is used in conjunction with the payload of the request (if there is one). Verifying the signature Sign the body and signature timestamp with the webhook secret key using SHA256, then base64 encoding the resulting digest. Represented simply: base64(HMACSHA256(TIMESTAMP + BODY)) To verify the signature, create the same SHA256 HMAC signature and then compare it to the webhook payload to ensure that they match. If they match, then you can be sure that the webhook came from YOOBIC. If they don't, it may be a request from another source. Here is an example of a verification signature function in nodejs ```js const crypto = require('crypto'); const SIGNING_SECRET = function isValidSignature(signature, body, timestamp) { let hmac = crypto.createHmac('sha256', SIGNING_SECRET); let sig = hmac.update(timestamp + body).digest("base64"); return ( Buffer.compare( Buffer.from(signature), Buffer.from(sig.toString("base64")) ) === 0 ); } // assuming you have access to the HTTP request (req) object your webhook endpoint has been called with const signature = req.headers["x-yoobic-webhook-signature"]; const timestamp = req.headers["x-yoobic-webhook-signature-timestamp"]; const raw_body = JSON.stringify(req.body); const isValid = isValidSignature(signature, raw_body, timestamp) if (isValid) { console.log("HMAC signature is valid"); } else { console.log("HMAC signature is invalid"); } ``` #### Webhooks and sandbox You can create webhooks in the sandbox environment but they are automatically removed every week when the sandbox environment is refreshed. Active webhooks in production are not copied to the sandbox environment during the weekly sandbox refresh. ### Fields | Field | Type | Required | Readonly | OrderBy | Description | |----------------------|:--------------:|:--------:|:--------:|:-------:|---------------------------| |`webhook_id` | string | | x | | Unique webhook id | |`url` | string | x | | | Unique http target url | |`topics` | array | | | | A list of entities to listen for (default: all)| |`operations` | array | | | | A list of operations to listen for ["create", "update", "delete"] (default: all)| |`is_active` | boolean | | | | enable or disable this webhook (default: true) | |`trigger_on_every_match`| boolean | | | | Specifies if an object should trigger the webhook on every match or only once | |`has_secret` | boolean | | x | | True if secret has been provided | |`error` | object | | x | | A description object (http status, message) to the reason this webhook is inactive | |`secret` | string | | | | Encryption key | |`created_date` | date | | x | | Creation date | |`updated_date` | date | | x | x | Last update date |

OpenAPI Specification

yoobic-webhooks-api-openapi.yml Raw ↑
openapi: 3.0.0
info:
  title: YOOBIC Public Answers Webhooks API
  version: ''
  description: "Welcome to the **YOOBIC Public API** documentation.\n\nThe **YOOBIC Public API** is designed for developers and engineers who are interested in building custom applications or integrating with other systems or APIs.\nThe API allows you to manage resources in a simple, programmatic way using conventional HTTPS requests.\n\nThe endpoints are intuitive and powerful, allowing you to easily make calls to retrieve information or to execute actions.\n\nThe API documentation will start with a general overview about the design and technology that has been implemented, followed by reference information about specific endpoints.\n\n# Postman Collection\n\nA complete **YOOBIC Postman Collection** is available for download, containing all API endpoints organized by resource groups with pre-configured environments.\n\n**Download:** [YOOBIC Postman Collection](https://assets.yoobic.com/raw/upload/v1767016464/3c85c240-dd03-4981-9814-bc6e5e861fa0.zip)\n\nThis collection includes:\n\n- All API endpoints organized by resource groups\n\n- Pre-configured environments (sandbox, prod)\n\n- Automatic authentication handling\n\n- Example requests and responses\n\n- Ready-to-use test scripts\n\nImport the collection into Postman to quickly start testing the YOOBIC API endpoints.\n\n# What's new\n\nBelow is a list of recent enhancements/changes to the YOOBIC Public API.\n\n### July 21st, 2026\n\n* New [rate limit](#section-api-tech-requirements) for `DELETE` requests (120 per minute) across all endpoints, per client organization. See [Rate Limits](#section-api-tech-requirements).\n\n### June 3rd, 2026\n\n* Clarify `score` and `extra_scores` semantics in [missions](#group-missions) CSV import/export: the `score` column holds the numeric value only; `extra_scores` is export-only with one (translated) column per sub-score.\n\n### March 19th, 2026\n\n* Expand publish documentation on [campaigns](#group-campaigns): per-site/per-user mission creation, `user_ids` parameter, and request/response examples.\n\n* Document that a mission must be assigned before it can be booked on [missions](#group-missions).\n\n### March 4th, 2026\n\n* Document escaping of special characters in CSV import files using double quotes (see [Asynchronous Jobs](#section-async-jobs)).\n\n### January 25th, 2026\n\n* Clarify that `group_ids` on [files](#group-files) accepts an array of group ids, with an updated example.\n\n### December 29th, 2025\n\n* New automatic public api collections\n\n* Add [Bot Messages](#group-bot_messages) endpoint.\n\n* Add [Chats](#group-chats) endpoint.\n\n* Add [Upload file](#reference/files/single-file-api/create) on files.\n\n### April 10th, 2025\n\n* Add `folder_id` field on [`files`](#group-files).\n\n* Add `folder_name` field on [`files`](#group-files).\n\n### February 16th, 2025\n\n* Error messages now partially obscure usernames when relevant.\n\n### January 16th, 2025\n\n* Added support for [SCIM](#group-scim).\n\n### January 15th, 2025\n\n* Add [Communities](#group-communities) endpoint.\n\n* Add [Community Posts](#group-community-posts) endpoint.\n\n### January 1st, 2025\n\n* Add `address` field on [`events`](#group-events).\n\n* Add `virtual_event_link` field on [`events`](#group-events).\n\n* Add `total_users` field on [`events`](#group-events).\n\n### November 10th, 2024\n\n* Add `expires_in` field on [`login`](#reference/auth/group-security/Authentication) [auth](#group-security).\n\n### October 30th, 2024\n\n* Add [Export manager users](#reference/users/multiple-users-api/export-manager-users) endpoint.\n\n* Add [Import manager users](#reference/users/multiple-users-api/import-manager-users) endpoint.\n\n* Add `position` field on [users](#group-users).\n\n* Add `department` field on [users](#group-users).\n\n* Add `division` field on [users](#group-users).\n\n* Add `company` field on [users](#group-users).\n\n* Add `hiring_date` field on [users](#group-users).\n\n* Add `skills` field on [users](#group-users).\n\n* Add `cover` field on [users](#group-users).\n\n* Add `description` field on [users](#group-users).\n\n### August 1st, 2024\n\n* Add `trigger_on_every_match` field on [webhooks](#group-webhooks).\n\n### July 15, 2024\n\n* Add new type for import users `json` on [`import`](#reference/users/multiple-users-api/import) endpoint.\n\n### June 27, 2024\n\n* Add [Bots](#group-bots) endpoint.\n\n* Add `earned_points` field on [courses](#group-courses).\n\n* Add `duration` field on [courses](#group-courses).\n\n* Add `start_date` field on [courses](#group-courses).\n\n* Add `due_date` field on [courses](#group-courses).\n\n* Add `finished_date` field on [courses](#group-courses).\n\n### April 30, 2024\n\n* Add `notify` field on campaign [Publish](#reference/campaigns/single-campaign-api/publish).\n\n### April 17, 2024\n\n* New [rate limit](#section-api-tech-requirements) for `users` endpoint for POST, PATCH and DELETE requests\n\n### January 31, 2024\n\n* Add [Invite users](#reference/users/multiple-users-api/invite-users) endpoint.\n\n* Add [Export archived users](#reference/users/multiple-users-api/export-archived-users) endpoint. The exported file now includes custom fields.\n\n* Add [Export archived stores](#reference/stores/multiple-stores-api/export-archived-stores) endpoint. The exported file now includes custom fields.\n\n### November 3, 2023\n\n* Add [Mission-Comments](#group-mission_comments) endpoint.\n\n### October 23, 2023\n\n* Add `da`, `fi`, `nb` and `sv` fields on [translations](#group-translations).\n\n### August 15, 2023\n\n* Add [Import Users To Archive](#reference/users/multiple-users-api/import-users-to-archive) on users.\n\n* Add [Import Users To Un Archive](#reference/users/multiple-users-api/import-users-to-un-archive) on users.\n\n* Add [Import Stores To Archive](#reference/stores/multiple-stores-api/import-stores-to-archive) on stores.\n\n* Add [Import Stores To Un Archive](#reference/stores/multiple-stores-api/import-stores-to-un-archive) on stores.\n\n### July 26, 2023\n\n* Add extra security asymetric encryption for logins.\n\n### June 20, 2023\n\n* [webhooks](#group-webhooks) change in behavior on sandbox environment.\n\n### April 23, 2023\n\n* Add new supported topics to [webhooks](#group-webhooks).\n\n### April 18, 2023\n\n* Add [Invitees](#reference/events/single-events-api/invitees) endpoint on events.\n\n### March 2, 2023\n\n* Update `group_id` field on [groups](#group-groups).\n\n### February 7, 2023\n\n* Add `weekly_schedule` fields on [users](#group-users).\n\n* Add [Shifts](#group-shifts) endpoint.\n\n### December 20, 2022\n\n* Add `au`, `ido` and `vi` fields on [translations](#group-translations).\n\n### November 23, 2022\n\n* Add `images` field on [news](#group-news).\n\n* Removed `image` field on [news](#group-news) (deprecated).\n\n### October 31, 2022\n\n* Add [Roles](#group-roles) endpoint.\n\n### October 20, 2022\n\n* Add [Questions](#group-questions) endpoint.\n\n### October 13, 2022\n\n* Add [Answers](#group-answers) endpoint.\n\n### September 1, 2022\n\n* Add `client_ids` field on [users](#group-users).\n\n* Add `store_type_names` field on [users](#group-users).\n\n### June 26, 2022\n\n* [`Publish`](#reference/campaigns/single-campaign-api/publish) a campaign based on its current configured audience.\n\n### June 22, 2022\n\n* Add security for [webhooks](#group-webhooks).\n\n* Updated limit to the number of [`notifications`](#group-notifications) that can be sent at once to 50k.\n\n### June 14, 2022\n\n* Add [Events](#group-events) endpoint.\n\n### February 20, 2022\n\n* Add `custom_fields` field on [visits](#group-visits).\n\n### December 21, 2021\n\n* Add [Import audience](#reference/campaigns/single-campaign-api/import-audience) on campaigns.\n\n* Add [Import new campaigns from template](#reference/campaigns/single-campaign-api/import-new-campaigns-from-template) on campaigns.\n\n* Add [Get all archives](#reference/users/multiple-users-api/get-all-archives) on users.\n\n* Add [Get all archives](#reference/stores/multiple-stores-api/get-all-archives) on stores.\n\n### October 27, 2021\n\n* Add `active` field on [campaigns](#group-campaigns).\n\n* Add `archived` field on [campaigns](#group-campaigns).\n\n### September 9, 2021\n\n* Add [jobs](#group-jobs) fields' detail.\n\n* Updated the location of the file containing the errors to be under `error`.\n\n### August 15, 2021\n\n* Errors during an import job are now described in a file and returned as a `download_url` under `errors` in the job response.\n\n### May 12, 2021\n\n* Add [create question](#reference/campaigns/single-campaign-api/create-question) on campaigns.\n\n* Add [update question](#reference/campaigns/single-campaign-api/update-question) on campaigns.\n\n* Add [delete question](#reference/campaigns/single-campaign-api/delete-question) on campaigns.\n\n* Add [partial u pdate](#reference/campaigns/single-campaign-api/partial-update) on campaigns.\n\n### May 10, 2021\n\n* Add get and update a [missions](#reference/missions/single-mission-api/find-mission's-tasks) tasks.\n\n### April 7, 2021\n\n* Add ability to get the missions' answers [missions](#reference/missions/multiple-missions-api/get-all).\n\n### March 16, 2021\n\n* Add `out_of_stock` field on [products](#group-products).\n\n### March 1, 2021\n\n* Add [`Password History`](#reference/users/single-user-api/password-history) method for [users](#group-users)\n\n### January 17, 2021\n\n* Add `terms_of_acceptance_date` field on [users](#group-users).\n\n* Add [tenants](#group-tenants)\n\n### January 13, 2021\n\n* Add `vq_fields` object in [stores](#group-stores) description and endpoints to support virtual queuing\n\n### January 12, 2021\n\n* Add [webhooks](#group-webhooks) endpoint.\n\n### December 28, 2020\n\n* Add [custom-model-instances](#group-custom_model_instances)\n\n### December 7, 2020\n\n* Add `task_number` field on [missions](#group-missions) endpoint.\n\n### November 19, 2020\n\n* Add `capacity` field on [stores](#group-stores) endpoint.\n\n* Add `last_seen` field on [users](#group-users).\n\n* Add `mobile_version` field on [users](#group-users).\n\n* Add `desktop_version` field on [users](#group-users).\n\n### November 10, 2020\n\n* Add `group_ids` field on [inventory](#group-inventory).\n\n### October 26, 2020\n\n* Add [`unarchive`](#reference/stores/single-store-api/unarchive) method for [stores](#group-stores)\n\n* Add [`unarchive`](#reference/users/single-user-api/unarchive) method for [users](#group-users)\n\n### October 22, 2020\n\n* Add [`archive`](#reference/stores/single-store-api/archive) method for [stores](#group-stores)\n\n* Add [`archive`](#reference/users/single-user-api/archive) method for [users](#group-users)\n\n### October 14, 2020\n\n* Add `allow_local_login` field on [users](#group-news).\n\n### September 14, 2020\n\n* Add `tags` field on [news](#group-news).\n\n* Add POST, DELETE and PATCH endpoints for [news](#group-news).\n\n### September 10, 2020\n\n* Add `client_role_extension` field on [users](#group-users).\n\n### August 19, 2020\n\n* Add `action_plan_progress` field on [missions](#group-missions) table.\n\n### July 23, 2020\n\n* Add `available-slots` method on [waitlist-yoobic-visits](#group-waitlist-yoobic-visits) endpoint.\n\n* Update `waitlist-yoobic-visits` response to return store `client_id` and store `title` on [waitlist-yoobic-visits](#group-waitlist-yoobic-visits) endpoints.\n\n### July 05, 2020\n\n* Add [waitlist-yoobic-visits](#group-waitlist-yoobic-visits)\n\n### June 28, 2020\n\n* Add [waitlist-customers](#group-waitlist-customers)\n\n### May 18, 2020\n\n* Add BOOST endpoint ([incentives-kpi](#group-incentives-kpi))\n\n### May 11, 2020\n\n* Add `timezone` field on [stores](#group-stores) endpoint.\n\n### May 5, 2020\n\n* Add `page_titles` field on [campaigns](#group-campaigns) endpoint.\n\n### April 16, 2020\n\n* Add [`delete`](#reference/campaigns/single-campaign-api/delete) method for [campaigns](#group-campaigns)\n\n### February 19, 2020\n\n* Add to [campaigns](#group-campaigns) [`publish`](#reference/campaigns/single-campaign-api/publish) the ability to provide default answers.\n\n### February 13, 2020\n\n* Add [`assign`](#reference/plans/single-plan-api/assign) method for [plans](#group-plans)\n\n### February 5, 2020\n\n* Add `timezone` field on [stores](#group-stores) endpoint.\n\n### February 4, 2020\n\n* Add [`create`](#reference/visits/multiple-visits-api/create) method for [visits](#group-visits)\n\n* Add [`import`](#reference/visits/multiple-visits-api/import) method for [visits](#group-visits)\n\n### January 28, 2020\n\n* Add properties on [campaigns](#group-campaigns) [`publish`](#reference/campaigns/single-campaign-api/publish)\n\n### November 5, 2019\n\n* Add `create` method for [campaigns](#group-campaigns) endpoint.\n\n* Add `create` method for [photos](#group-photos) endpoint.\n\n### October 2, 2019\n\n* Add `store_id` field on [visit](#group-visits).\n\n* Add `user_id` field on [visit](#group-visits).\n\n* Add `creator_id` field on [visit](#group-visits).\n\n### September 5, 2019\n\n* Add [visit](#group-visits) endpoint.\n\n### September 3, 2019\n\n* Add `group_ids` field on [notifications](#group-notifications).\n\n### August 8, 2019\n\n* Add [inventory](#group-inventory) endpoint.\n\n### August 5, 2019\n\n* Add `scoring` field on [campaigns](#group-campaigns).\n\n* Add `recurring` field on [campaigns](#group-campaigns).\n\n* Add `body` field on [notifications](#group-notifications).\n\n* Add `user_ids` field on [notifications](#group-notifications).\n\n* Add `badge_type` field on [notifications](#group-notifications).\n\n* Add `manufacturer` field on [products](#group-products).\n\n* Add `brand` field on [products](#group-products).\n\n* Add `category` field on [products](#group-products).\n\n* Add `images` field on [products](#group-products).\n\n### July 9, 2019\n\n* Add `authorised_viewers` field on [news](#group-news).\n\n* Add `description` field on [news](#group-news).\n\n* Add `group_ids` field on [news](#group-news).\n\n### June 13, 2019\n\n* Add `available_on_book` field on [missions](#group-missions).\n\n* Add `available_on_finished` field on [missions](#group-missions).\n\n### June 3, 2019\n\n* Add `average_completed_lesson` field on [plans](#group-plans).\n\n* Add `photo` field on [stores](#group-stores).\n\n* Add `address` field on [users](#group-users).\n\n### May 16, 2019\n\n* Add `duration` field on [missions](#group-missions).\n\n* Add `duration` field on [lessons](#group-lessons).\n\n### May 8, 2019\n\n* Add `markup_url` field on [photos](#group-photos).\n\n### April 30, 2019\n\n* Add `catalog_title` field on [products](#group-products).\n\n### Mar 24, 2019\n\n* Add `vip` field on [stores](#group-stores).\n\n### Mar 11, 2019\n\n* Remove support for the replace (PUT) resource, in favor of partial update (PATCH).\n\n### Mar 6, 2019\n\n* Document [Current User API](#reference/users/current-user-api/get)\n\n* Document company name restriction on  `Groups` [`create`](#reference/groups/multiple-groups-api/create) and [`import`](#reference/groups/multiple-groups-api/import)\n\n### Feb 25, 2019\n\n* Add endpoint to get a store's [`Health Score`](#reference/stores/single-store-api/health-score-of-a-store-api)\n\n* Add BOOST endpoints ([plans](#group-plans), [courses](#group-courses), [lessons](#group-lessons))\n\n### API Resources Overview\n\n| Resource                                 | GET | POST | PATCH  | DELETE | IMPORT | EXPORT | COUNT |\n|------------------------------------------|:---:|:----:|:------:|:------:|:------:|:------:|:-----:|\n|[`auth`](#group-security)                 |     |  x   |        |        |        |        |       |\n|[`answers`](#group-answers)               |  x  |      |        |        |        |    x   |   x   |\n|[`badges`](#group-badges)                 |  x  |      |        |        |        |    x   |   x   |\n|[`bots`](#group-bots)                     |  x  |      |        |        |        |    x   |   x   |\n|[`bot-messages`](#group-bot_messages)     |     |      |        |        |        |    x   |       |\n|[`campaigns`](#group-campaigns)           |  x  |  x   |   x    |   x    |        |    x   |   x   |\n|[`catalogs`](#group-catalogs)             |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`chats`](#group-chats)                   |     |  x   |        |        |        |        |       |\n|[`comments`](#group-comments)             |  x  |      |        |        |        |    x   |   x   |\n|[`communities`](#group-communities)       |  x  |  x   |   x    |        |        |    x   |   x   |\n|[`community-posts`](#group-community-posts) |  x  |  x   |        |        |    x   |    x   |   x   |\n|[`competencies`](#group-competencies)     |  x  |      |        |        |        |    x   |   x   |\n|[`course-categories`](#group-course-categories)     |  x  |      |        |        |        |    x   |   x   |\n|[`courses`](#group-courses)               |  x  |      |        |        |        |    x   |   x   |\n|[`custom-model-instances`](#group-custom_model_instances)|  |   |    |   |   x    |    x   |       |\n|[`events`](#group-events)                 |  x  |  x   |   x    |   x    |   x    |    x   |   x   |\n|[`files`](#group-files)                   |  x  |  x   |        |        |        |    x   |   x   |\n|[`geofilters`](#group-geofilters)         |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`groups`](#group-groups)                 |  x  |  x   |        |   x    |   x    |    x   |   x   |\n|[`incentives-kpi`](#group-incentives-kpi) |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`inventory`](#group-inventory)           |  x  |      |        |        |        |    x   |   x   |\n|[`lessons`](#group-lessons)               |  x  |      |        |        |        |    x   |   x   |\n|[`missions`](#group-missions)             |  x  |      |    x   |   x    |   x    |    x   |   x   |\n|[`mission_comments`](#group-mission_comments)   |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`news`](#group-news)                     |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`notifications`](#group-notifications)   |  x  |  x   |        |        |        |    x   |   x   |\n|[`photos`](#group-photos)                 |  x  |  x   |        |        |        |    x   |   x   |\n|[`plans`](#group-plans)                   |  x  |      |        |        |        |    x   |   x   |\n|[`products`](#group-products)             |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`questions`](#group-questions)           |  x  |      |        |        |        |    x   |   x   |\n|[`roles`](#group-roles)                   |  x  |      |        |        |        |    x   |   x   |\n|[`salesdata`](#group-salesdata)           |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`shifts`](#group-shifts)                 |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`store-types`](#group-store_types)       |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`stores`](#group-stores)                 |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`tenants`](#group-tenants)               |  x  |      |        |        |        |        |       |\n|[`translations`](#group-translations)     |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`users`](#group-users)                   |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`visits`](#group-visits)                 |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`webhooks`](#group-webhooks)             |  x  |  x   |    x   |   x    |   x    |    x   |   x   |\n|[`jobs`](#group-jobs)                     |  x  |      |        |        |        |        |       |\n\n# Table of Contents\n\n- [API Help](#section-api-help) - We're here to help!\n\n- [API Access](#section-api-access) - API access authentication\n\n- [API Technical Requirements](#section-api-tech-requirements) - Technical requirements for communicating with the API - security protocols and rate limits\n\n- [API Requests](#section-api-requests) - Formatting of requests sent to the **RESTful** YOOBIC API\n    - [Filter](#section-api-requests-filter) - Filter the results using different criteria\n        - [Order](#section-api-requests-filter-order) - Ordering the results\n        - [Paging](#section-api-requests-filter-paging) - Paging through your results\n        - [Where](#section-api-requests-filter-where) - Matching your results\n        - [Fields](#section-api-requests-filter-fields) - including specific fields to your results\n    - [CRUD Requests](#section-api-requests-crud-requests) - Creating/updating/deleting resources\n\n- [API Responses](#section-api-responses) - The common response format of each request\n\n- [Asynchronous Jobs](#section-async-jobs) - How data is requested asynchronously for endpoints\n  - [Export file section](#section-export-jobs)\n  - [Import file section](#section-import-jobs)\n\n- [Endpoint Documentation](#section-endpoint-documentation) - Documentation specific for each endpoint. You may also use the links on the table on the sidebar to navigate to any endpoint.\n    - [Security](#group-security)\n    - [Answers](#group-answers)\n    - [Badges](#group-badges)\n    - [Bots](#group-bots)\n    - [Bot Messages](#group-bot_messages)\n    - [Campaigns](#group-campaigns)\n    - [Catalogs](#group-catalogs)\n    - [Chats](#group-chats)\n    - [Comments](#group-comments)\n    - [Communities](#group-communities)\n    - [Comments](#group-community-posts)\n    - [Competencies](#group-competencies)\n    - [Course-categories](#group-course-categories)\n    - [Courses](#group-courses)\n    - [Custom-model-instances](#group-custom_model_instances)\n    - [Events](#group-events)\n    - [Files](#group-files)\n    - [Geofilters](#group-geofilters)\n    - [Groups](#group-groups)\n    - [Incentives Kpi](#group-incentives-kpi)\n    - [Inventory](#group-inventory)\n    - [Lessons](#group-lessons)\n    - [Missions](#group-missions)\n    - [Missions](#group-mission_comments)\n    - [News](#group-news)\n    - [Notifications](#group-notifications)\n    - [Photos](#group-photos)\n    - [Plans](#group-plans)\n    - [Products](#group-products)\n    - [Questions](#group-questions)\n    - [Roles](#group-roles)\n    - [Salesdata](#group-salesdata)\n    - [SCIM](#group-scim)\n    - [Shifts](#group-shifts)\n    - [Store Types](#group-store_types)\n    - [Stores](#group-stores)\n    - [Tenants](#group-tenants)\n    - [Translations](#group-translations)\n    - [Users](#group-users)\n    - [Visits](#group-visits)\n    - [Webhooks](#group-webhooks)\n    - [Jobs](#group-async-jobs)\n\n<a id=\"section-api-help\"></a>\n\n## API Help\n\nHave questions or need support?\nEmail your YOOBIC Customer Success Manager or [support@yoobic.com](mailto:support@yoobic.com).\n\n<a id=\"section-api-access\"></a>\n\n## API Access\n\nAuthentication to the YOOBIC API uses JWT tokens. They are required for accessing API.    \nJWT tokens are set in the `Authorization` header for your requests as follows:\n\n```\nAuthorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c\n```\n\nTo obtain a valid token you can either:\n\n- Use the [`auth/login`](#group-security) endpoint\n\n- Contact your YOOBIC Customer Success Manager or [support@yoobic.com](mailto:support@yoobic.com) to obtain credentials to use in the /auth/login endpoint.\n\n- Please note that in the case you are using a reverse proxy you must set the parameter `proxy_ssl_server_name` to on to successfully connect to the prod environment.\n\n<a id=\"section-api-tech-requirements\"></a>\n\n## API Technical Requirements\n\n### Protocol and Communication\n\n- The api is only accessible via HTTPS, using TLS 1.2 or better. We forward secrecy and AES-GCM, and prohibit insecure connections using SSL 3.0 or RC4.\n\n- Environments    \n      We provide both a Sandbox and a Production environment. Every Friday at 21:55 UTC, Sandbox is refreshed by taking a snapshot of the Production environment. Since this refresh process takes several hours, please avoid using Sandbox during that time. It is available for testing purposes outside of the refresh period.\n\n- Template structure of a request:   \n    - Base url Production: **https://api.yoobic.com/public/api**\n    - Base url Sandbox: **https://api-sandbox.yoobic.com/public/api**\n    - The `<base_url>` variable in the example requests is either `api.yoobic.com` or `api-sandbox.yoobic.com`.\n    - Get all (GET): `/{endpoint}?filter={ \"where\": { \"property\": \"value\" }, \"skip\": 0, \"limit\": 100, \"order\": \"updated_date DESC\", \"fields\": [\"property\"] }`\n    - Count (GET):  `/{endpoint}?where={ \"property\": \"value\" }`\n    - Create (POST): `/{endpoint}` should include a valid JSON object as the body.\n    - Update (PATCH): `/{endpoint}/:id` should include a valid JSON object as the body.\n    - Delete (DELETE): `/{endpoint}/:id`\n\n### Rate Limits\n\nAll limits are applied per client organization. Exceeding a limit returns HTTP error `429 Too Many Requests (Rate Limit Exceeded)`; wait for the current one-minute window to pass and retry.\n\n- **Interval Limit**: 10 requests per second overall. Send requests serially (one at a time); bursts of concurrent requests may be rejected.\n\n- **Delete Limit**: 120 `DELETE` requests per minute across all endpoints.\n\n- **Users Write Limit**: 180 requests per minute (3 per second) for `POST`, `PATCH` and `DELETE` on the `/users` endpoint. These requests also count toward the limits above.\n\n- **Daily Limit**: 100,000 requests per day.\nIf you need higher limits to support your specific use case, please contact your YOOBIC Customer Success Manager or [support@yoobic.com](mailto:support@yoobic.com) — limits can be adjusted per organization.\n\n<a id=\"section-api-requests\"></a>\n\n## API Requests\n\nRequests for the YOOBIC API are all RESTful, with parameters following the endpoint path or in request body.\nEach request in the documentation is displayed with the appropriate HTTP method and sample parameters.\nData may be sent in as parameters or in the request body as JSON.\nThe requests on the YOOBIC API allow for ordering, paging and filtering on a per entity basis.\n\n<a id=\"section-api-requests-filter\"></a>\n\n### Filter\n\nA where filter specifies criteria for returning data.\nWe supports the following kind of filters:\n\n- [Order filter](#section-api-requests-filter-order)\n\n- [Paging filter](#section-api-requests-filter-paging)\n\n- [Where filter](#section-api-requests-filter-where)\n\n- [Fields filter](#section-api-requests-filter-fields)\n\nA filter must be a JSON encoded string (`{\"something\":\"value\"}`).    \nTo do this, simply use the following syntax:\n\n```\n?filter={ Stringified-JSON }\n```\n\nIn the JSON all text keys/strings must be enclosed in quotes (\").\n\n**Important**:     \nWhen using stringified JSON, you must use an equal sign after ?filter in the query string.    \nFor example:\n\n```\nGET /entity?filter={\"where\": { \"entity_id\": 1234 }, \"order\": \"updated_date DESC\", \"limit\": 100, \"fields\": [\"property\", \"property\"] }\n```\n\n<a id=\"section-api-requests-filter-order\"></a>\n\n#### Order Filter\n\nAn *order* filter specifies how to sort the results: ascending (ASC) or descending (DESC) based on the specified property.   \nOrder by one property:\n\n```json\n{ \"order\": \"property <ASC|DESC>\" }\n```\n\nOrder by two or more properties:\n\n```json\n{ \"order\": [\"property <ASC|DESC>\", \"property <ASC|DESC>\",...] }\n```\n\nWhere:\n\n- *property* is the name of the property (field) to sort by.\n\n- *<ASC|DESC>* signifies either ASC for ascending order or DESC for descending order.\n\n**Important**:     \nBy default ordering will be performed according to the *updated_date* property.    \nEach endpoint's table, contains information, to the properties ordering could be performed on.\n\n<a id=\"section-api-requests-filter-paging\"></a>\n\n#### Paging Filter\n\nPaging can be achieved by a combination of *limit* and *skip* parameters.\n\n* *limit* filter limits the number of records returned to the specified number (or less).    \n    The maximum number of records that could be fetched is `1000`.    \n    For anything above that, you might want to consider using the [export](#section-async-jobs) endpoint.    \n    ```json\n        { \"limit\": 5 }\n    ```\n\n* *skip* filter omits the specified number of returned records.\n    ```json\n        { \"skip\": 5 } \n    ```\n\n* If `paging.total > paging.limit` in the response of a request:\n\n    It is possible to use the *skip* filter. Here is an example on how to use it with the users endpoint:    \n    `https://api-sandbox.yoobic.com/public/api/users?filter={\"skip\": 1000}`    \n    The recommended solution is to add a condition to the API script to loop requests if there are too many elements until all of them are returned.    \n    The condition would monitor that `paging.total - paging.limit <= paging.skip` in the response of each request, and if not send another request with `newSkip = Skip + 1000` after receiving the last one.    \n    The other way to manage large requests is to use asynchronous requests. For example with Users, it is possible to export a CSV file of all or some users. See the [export](#section-async-jobs) section for this.\n\n<a id=\"section-api-requests-filter-where\"></a>\n\n#### Where Filter\n\nA *where* filter specifies a set of logical conditions to match, similar to a WHERE clause in a SQL query.\n\nUse the first form below to test equivalence, that is, whether property equals value. Use the second form below for all other conditions.\n\n```json\n{ \"where\": { \"property\": value } }\n```\n\n```json\n{ \"where\": { \"property\": { \"op\" : value } } }\n```\n\n```json\n{ \"where\": { \"and|or\": [{ \"property\": { \"op\" : value } }, { \"property\": { \"op\" : value } }] } }\n```\n\nWhere:\n\n- *property* is the name of a property (field) in the model being queried.\n\n- *value* is a literal value.\n\n- *op* is one of the operators listed below.\n\n| Operator      | Description                                                                                                |\n|---------------|------------------------------------------------------------------------------------------------------------|\n|gt, gte        | Numerical greater than (>); greater than or equal (>=). Valid only for numerical and date values.| \n|lt, lte        | Numerical less than (<); less than or equal (<=). Valid only for numerical and date values. |\n|between        | True if the value is between the two specified values: greater than or equal to first value and less than or equal to second value.| \n|inq, nin       | In / not in an array of values.|\n|neq            | Not equal (!=) |\n\n<a id=\"section-api-requests-filter-fields\"></a>\n\n#### Fields Filter\n\nA *fields* filter specifies properties (fields) to include from the results.\n\n```json\n{ \"fields\": [\"property\", \"property\", ...] }\n```\n\nWhere:\n\n- *property* is the name of the proeprty (field) to include.\n\nBy default, queries return all properties in results. However, if you specify at least one fields filter, then by default the query will include only those you specifically include with filters.\n\n**Important**:     \nThe *export* resource for all endpoints does not allow the *fields* filter.\n\n<a id=\"section-api-requests-crud-requests\"></a>\n\n## CRUD Requests\n\nCreate, update and delete requests follow standard RESTful practices. While some fields\nare available on a resource, you may not be able to set values for *readonly* fields such as `created_date` during\na CREATE, UPDATE or DELETE action (it would just be ignored). The allowed parameters are listed at the beginning of each CRUD section for a particular resource.\n\n<a id=\"section-api-responses\"></a>\n\n## API Responses\n\nThe Response format varies depending on the type of request:\n\n- Single API requests - simple hash, whether it be an error or not.\n\n- Multiple API requests - a hash containing two lists \n  - `data` for successfull requests.\n  - `error` for failed requests.\n\nThe two correspond to the order in the request.\n\n```json\n{\n     \"data\": [],\n     \"error\": []\n}\n```\n\nFor find requests an `error` **or** `data` with an additional `paging` hash -\n\n```json\n{\n    \"data\": [],\n    \"error\": [],\n    \"paging\": {

# --- truncated at 32 KB (64 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/yoobic/refs/heads/main/openapi/yoobic-webhooks-api-openapi.yml