{
  "openapi": "3.0.3",
  "info": {
    "version": "2.0.0",
    "title": "Cintoo Open API",
    "description": "Cintoo Open API 1.x documentation: https://aec.cintoo.com/api\n\n<span class='tag beta'>BETA</span>: API v2 endpoints tagged \"BETA\" are available in beta-version, meaning that changes may be done later on.\n\n# API Specification\n\nThe Cintoo API specification document you are viewing is compliant with the Open API Specification 3.0.3 and can be\nexported to json or yaml format that can be used by the API tool of your liking.\n\nIt also means the generated json/yaml will contain all the details present in this documentation about the\n\n* JSON Objects schema being returned\n* The status codes\n* The authentication\n* The verbs/paths/resources\n\n## Technical details\n\n* The API is **resource oriented**\n* The encoding is done in **utf-8**\n* Do not hesitate to click on the Download button on the top of this page to get the `openapi.json` or `openapi.yaml`\n  file generated and import in your favorite API client\n* Any Cintoo valid user can use the API\n\n- - -\n\n## Sandbox\n\nWith Cintoo Cloud API comes a Sandbox, which means a testing environment. This Sandbox is a separate tenant from the\nCintoo Cloud platform that you are already familiar with.\n\nThe Sandbox is at your disposal so that you can test and use the API with no consequence on your production data (no\nunfortunate deletion by mistake for example).\n\n### Sandbox restrictions\n\n* Scan capacity of 20 scans per user.\n* Company SSO (if any) is not applicable since the Sandbox uses a different account.\n* Please contact <support@cintoo.com> to get the invitation link to the Sandbox account.\n* You can use the same email but you will be asked to set a new password by clicking on the invitation link.\n* Please note that this is an experimental platform, so we reserve the right to refresh/delete the data (unlike the\n  production platform).\n* There is no limit in time for using the Sandbox.\n* The BIM & CAD Module (BCM) is activated in this Sandbox, so feel free to use your BIM or CAD model in this testing\n  environment.\n\nRegistering to the Sandbox / Cintoo Cloud API\n\nPlease contact our Support Team <support@cintoo.com> to be invited to the Sandbox and get all the documentation for\nCintoo Cloud API.\n\n- - -\n\n## Authentication\n\nThe Cintoo API relies on JWT Tokens for authenticating users with the standard combination `Access Token`+\n`Refresh Token`.\n\nNote that the first acquisition of the token pair requires a manual step (see below) for security reasons, then it can\nbe fully automated.\n\n### Access Tokens and Refresh Tokens\n\nThere are 2 kind of tokens:\n\n* Access token:\n    * is short lived (3h)\n    * is used to authenticate each query\n    * is personal and should not be shared, except for service users (see `Token management recipes` at the end of the\n      documentation)\n    * is a JWT and is stateless, ie. there is *NO* limit of Access Token being valid for a given user simultaneously,\n      and ***can*** be used in parallel.\n    * example of API call to list `accounts`:\n      `curl -H Authorization=\"Bearer $access_token\" https://aec.cintoo.com/api/accounts`\n\n> ***Note***: Calling the API with an already-used/expired token results in a response with status code `401`\n\n* Refresh token:\n    * is long lived (months)\n    * is used **once** to obtain a new `Access Token` + `Refresh Token` pair.\n    * **cannot** be used to make API calls.\n    * is personal and should not be shared, except for service users (see `Token management recipes` at the end of the\n      documentation)\n    * there ***IS*** a limit of 10 Refresh Token being valid for a given user simultaneously\n    * is stateful and ***CANNOT*** be used in parallel, as it is consumed when used\n    * example of refresh token call to get a new pair of \"Access Token\" and \"Refresh Token\":\n      `curl -X POST https://aec.cintoo.com/oauth/token -d \"grant_type=refresh_token&refresh_token=$refresh_token\"`\n\n> ***Note***: Calling the API with an already-used/expired token results in a response with status code `401`\n\n### The token flow\n\nThe Cintoo API follows the OAuth 2.0 Authorization Grant Type flow, and supports the PKCE extension which is recommended\nto provide better security (source: <https://oauth.net/2/grant-types/authorization-code/>)\n\nConcretely, users are supposed to acquire the token once with a manual step (they have to click on approve), to get a\nfirst pair of tokens.\n\nOnce this is done, they can script the refresh with\na [simple curl command](#refreshing-tokens-ie-generating-programmatically-a-new-access-token--refresh-token-pair).\n\n> ***Note:*** a refresh token is valid for 21 days. It can be used only once. The refreshing mechanism can be done **an\nunlimited number of times**\n\n### Generating Tokens\n\n* You are just starting with the Cintoo API and want to test it manually -> look that \"Generating the JWT Bearer Token\n  with the cintoo-login.exe\"\n* You are already familiar with oauth mechanisms/tools -> look at \"Using tools/3rd party to manage Tokens from Cintoo\n  Oauth Service\"\n\n### Generating the Access Token & Refresh Token pair with the cintoo-login.exe\n\nTo generate an Access Token with OAuth please use the following nice CLI\ntool [cintoo-login.exe](https://cintooprodstatic.blob.core.windows.net/api/cintoo-login-1.1.0-signed.exe) and double\nclick on it.\n\n**If you are on a dedicated tenant, please add the argument `--url`.**\n\n```powershell\n.\\cintoo-login-1.1.0-signed.exe --url https://aec.cintoo.com\n\nOpening OAuth page in browser.\nTo receive your JWT token:\n        * Ensure you are logged-in\n        * Click on the 'Allow' button\nINFO: You have 30s to complete these actions\n```\n\nWhich opens this page\n\n> Hint: if you wait more than 30s you will have to run the command again\n> Hint: you can change the timeout duration to another value with `--timeout 60`\n\n![allow-button](./assets/oauth.png#width=500px;height=350px;)\n\nOnce you click on `Allow` the page should lead you to:\n\n![success](./assets/success.png#width=500px;height=350px;)\n\n*AND* (most importantly) the **token** appears magically in your cmd output\n\n> Hint: Copy paste the `Bearer xxxxx` to avoid errors\n\n```powershell\nOpening OAuth page in browser.\nTo receive your JWT token:\n        * Ensure you are logged-in\n        * Click on the 'Allow' button\nINFO: You have 30s to complete these actions\nHere is your token: to use it put in the Authorization header (copy paste below):\n{\"Authorization\": \"Bearer <access_token>\"}\nIts validity is of 3h\nA new token can be-regenerated simply thanks to this refresh_token: <refresh_token>\nValidating token\nSuccess: API Token was successfully validated\n```\n\n### Refreshing tokens ie. Generating programmatically a new Access Token + Refresh Token pair\n\nWhile the Refresh Token is valid (within 21 days), you can consume it to get a new Access-Token + Refresh-Token pair.\n\n> ***Note:*** consuming the Refresh Token can be done before the expiration of the Access Token\n> ***Note:*** consuming the Refresh Token does **NOT** invalidate other **Access Token** as they are short lived\n\nUsing shell (Linux, OSX)\n\n```shell\nrefresh_token=\"<Your refresh token>\"\ncurl -X POST https://aec.cintoo.com/oauth/token -d \"grant_type=refresh_token&refresh_token=$refresh_token\"\n```\n\nWhich returns the following\n\n```json\n{\n  \"access_token\": \"{access_token}\",\n  \"refresh_token\": \"{refresh_token}\",\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 10800,\n  \"user_id\": \"{user_id}\"\n}\n```\n\nUsing powershell (Windows)\n\n```powershell\n$refresh_token = \"<Your refresh token>\"\n$params = @{\n    Uri         = 'https://aec.cintoo.com/oauth/token'\n    Method      = 'POST'\n    Body        = @{\n        grant_type     = 'refresh_token'\n        refresh_token  = $refresh_token\n    }\n    ContentType = 'application/x-www-form-urlencoded'\n}\nInvoke-RestMethod @params\n```\n\nWhich returns the following\n\n```powershell\naccess_token  : {access_token}\nrefresh_token : {refresh_token}\ntoken_type    : Bearer\nexpires_in    : 10800\nuser_id       : {user_id}\n```\n\n### Using tools/3rd party to manage Tokens from Cintoo Oauth Service\n\nThe Cintoo API follows the oauth\nprotocol [Authorization Code Grant](https://oauth.net/2/grant-types/authorization-code/) to generate the `access-tokens`\nand `refresh-tokens`.\n\nAs such, it is possible to use 3rd party libraries and tools that implement the Oauth2 Authorization Code protocol to\nmanage the tokens (and perform automatic refresh).\n\nThe important fields are the following and they match those defined by\nthe [authorization code request](https://www.oauth.com/oauth2-servers/access-tokens/authorization-code-request/), [authorization code request with PKCE](https://www.oauth.com/oauth2-servers/pkce/authorization-request/)\nand [refreshing access tokens](https://www.oauth.com/oauth2-servers/access-tokens/refreshing-access-tokens/) :\n\n| Field                                  | Value                                                                                                                                                                          |\n|----------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Grant Type                             | `Authorization Code` or `Authorization Code (With PKCE)`                                                                                                                       |\n| Callback URL                           | `localhost` or `127.0.0.1` or `/`                                                                                                                                              |\n| Auth URL                               | `https://aec.cintoo.com/oauth/authorize`                                                                                                                                     |\n| Access Token URL                       | `https://aec.cintoo.com/oauth/token`                                                                                                                                         |\n| Refresh Token URL                      | `https://aec.cintoo.com/oauth/token`                                                                                                                                         |\n| State                                  | use a random code made of `[a-z0-9]+` with a \"correct length\". More information about the [state-parameters](https://auth0.com/docs/secure/attack-protection/state-parameters) |\n| Code Challenge Method (only with PKCE) | `SHA-256` more info on [PKCE](https://www.oauth.com/oauth2-servers/pkce/)                                                                                                      |\n\n### The flow in detail for acquiring the first Token pair\n\nThis section is here in case you want to **build an oauth client for acquiring the first Token pair without the help of\nthe cintoo-login or without 3rd party software**.\n\nThe term \"Client\" is going to be described as the originator of the oauth token request.\n\n* Client calls the Cintoo `oauth/authorize` endpoint ***from the browser*** with the following query parameters:\n    * the `redirect_uri` (callback-url) it wants Cintoo to send the authorization code to\n    * the `state` uses a random code made of `[a-z0-9]+` with a \"correct length\". More information about\n      the [state-parameters](https://auth0.com/docs/secure/attack-protection/state-parameters)\n    * (optional) `code_challenge` a random code that has been hashed using the SHA256 algorithm. More info\n      on [PKCE](https://www.oauth.com/oauth2-servers/pkce/).\n  > code_verifier = high-entropy cryptographic random STRING using the\n  unreserved characters [A-Z] / [a-z] / [0-9] / \"-\" / \".\" / \"_\" / \"~\"\n  from Section 2.3 of [RFC3986], with a minimum length of 43 characters\n  and a maximum length of 128 characters.\n    * (optional but mandatory if `code_challenge` is set) `code_challenge_method` : \"SHA256\"\n* Cintoo API returns an html element with an `approve` button to be clicked by the user that started the action (the\n  same shown in the previous chapter)\n* Once the `approve` button is pressed there is a `Form Post URL redirect` that will target the `redirect_uri` provided\n  by the Client with the query parameters : `code` and `state` (+ `code_challenge` and `code_challenge_method` if\n  specified before)\n* The Client ***should check*** that the `state` sent and received are the same to avoid CSRF attacks.\n* If they are the same, the Client can then send a `POST` query to the `oauth/token` endpoint with the following payload\n  that contains the `code` it received on the previous steps.\n\n  ```json\n  {\n      \"code\": \"{code}\",\n      \"grant_type\": \"authorization_code\",\n      \"authorization_code\": \"{redirect_uri}\"\n  }\n  ```\n\n  or with PKCE\n\n  ```json\n  {\n      \"code\": \"{code}\",\n      \"grant_type\": \"authorization_code\",\n      \"authorization_code\": \"{redirect_uri}\",\n      \"code_verifier\": \"{code_verifier}\"\n  }\n  ```\n\n* Finally the Cintoo API answers the `oauth/token` with a json object that contains the `access_token` and\n  `refresh_token` pair:\n\n  ```json\n  {\n      \"access_token\": \"{access_token}\",\n      \"refresh_token\": \"{refresh_token}\",\n      \"token_type\": \"Bearer\",\n      \"expires_in\": 10800,\n      \"user_id\": \"{user_id}\"\n  }\n  ```\n\n- - -\n\n## Doing queries\n\nBelow you will find an example on how to use the token to do a query.\n\nA good endpoint to start with is the `isLogged` **resource** which simply returns `200` and `{\"success\": true}` if the\ntoken was recognized by the Cintoo API.\n\nWe highly recommend that you try it, then start changing the resource type (like `accounts` for instance) to get used to\nthe API.\n\n### Query example for Windows\n\n#### with cUrl\n\n```sh\nexport HOST=aec.cintoo.com\nexport TOKEN=...\n\ncurl --url \"https://{host}/api/2/accounts\" --header \"Authorization: Bearer $TOKEN\"\n```\n\n#### with Python\n\n```python\nimport requests\n\nhost = \"{host}\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts\" % host,\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n```\n\n#### with Powershell\n\nCopy the code below and try it in your Powershell terminal.\n\n> Hint: copy paste this while replacing the `xxxxxxx` with your token, and call as many `Invoke-RestMethod` as you want.\n> Note: the token is surrounded by `\"`\n\n```powershell\n$token = \"xxxxxxxxxxxxxxxxxx\"\n$headers = @{\n    Authorization=\"Bearer $token\"\n    Content='application/json'\n}\nInvoke-RestMethod -Headers $headers -Method Get -Uri \"https://aec.cintoo.com/api/isLogged\"\n```\n\nThe powershell command line should return this\n\n```powershell\nsuccess\n-------\n   True\n```\n\n## URNs\n\nURNs are standard [Uniform Resource Names](https://fr.wikipedia.org/wiki/Uniform_Resource_Name).\n\nOur NID is of course \"cintoo\", so they look like: ```urn:cintoo:{object type}:{object id}```.\n\nAll the endpoints that return an object or a list of objects include a field giving the URN of the object, that you can\nin turn use to reference this object whenever you need to mention it.\n\n## References\n\nThroughout the API, most endpoints need you to give *references* to existing objects,\nlike accounts, projects, roles, etc. For example, getting the details of an account will look like:\n\n```\nGET /api/2/accounts/{accountRef}\n```\n\nA *reference* can be any unambiguous identifier for the object. It typically is either:\n\n- the raw uuid or numerical id, depending on the type of the object:\n    - ```c41aec8b-3b85-4bdd-81e5-c2cfdb8980e8```\n    - ```5```\n- a URN (Uniform Resource Name), looking like: ``urn:cintoo:<object type>:<raw uuid or id>``. For example:\n    - ```urn:cintoo:account:c41aec8b-3b85-4bdd-81e5-c2cfdb8980e8```\n    - ```urn:cintoo:user:5```\n\nThe URN is the most durable option and should be preferred, each object returned by the API has an ```urn``` field\nholding it,\nwhereas at some point the raw id/uuid objects fields will be deprecated or removed from the objects content.\n\nIf your client needs to store identifiers for objects, **you should choose the URN**,\n\n- - -\n\n## Errors\n\nTo communicate errors, the Cintoo API\n\n* fills the HTTP status code defined by the\n  standard: [HTTP response status codes](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)\n\nIt is consensus in the industry that the ***status code is the source of truth*** on whether an API call was successful\nor not, the ***body is merely a BONUS***.\n\n### Error-body returned\n\nWe are following this [RFC](https://www.rfc-editor.org/rfc/rfc9457) whose content is the following\n\n> * The \"status\" member is a JSON number indicating The HTTP status code ([HTTP], Section 15) generated by the origin\n    server for this occurrence of the problem.\n    >\n    >   The \"status\" member, if present, is only advisory; it conveys the HTTP status code used for the convenience of\n    the consumer. Generators MUST use the same status code in the actual HTTP response, to assure that generic HTTP\n    software that does not understand this format still behaves correctly. See Section 5 for further caveats regarding\n    its use.\n    >\n    >   Consumers can use the status member to determine what the original status code used by the generator was when it\n    has been changed (e.g., by an intermediary or cache) and when a message's content is persisted without HTTP\n    information. Generic HTTP software will still use the HTTP status code.\n> * The \"title\" member is a JSON string containing a short, human-readable summary of the problem type.\n    >\n    >   It SHOULD NOT change from occurrence to occurrence of the problem, except for localization (e.g., using\n    proactive content negotiation; see [HTTP], Section 12.1).\n    >\n    >   The \"title\" string is advisory and is included only for users who are unaware of and cannot discover the\n    semantics of the type URI (e.g., during offline log analysis).\n> * \"detail\" (string) - The \"detail\" member is a JSON string containing a human-readable explanation specific to this\n    occurrence of the problem.\n    >\n    >   The \"detail\" string, if present, ought to focus on helping the client correct the problem, rather than giving\n    debugging information.\n    >\n    >   Consumers SHOULD NOT parse the \"detail\" member for information; extensions are more suitable and less\n    error-prone ways to obtain such information.\n\nIn addition, 2 extension fields are added:\n\n* `errorCode`: detailed code describing the error, can be used to map to a localized message\n* `errorValues`: values implied in the error, typically an input parameter, can be used to include in a localized\n  message\n\nThe mandatory fields that are always present are : `status` and `title`. Others are optional.\n\nExample:\n\n```json\n{\n  \"status\": 404,\n  \"title\": \"Not Found\",\n  \"detail\": \"Account 1234 not found\",\n  \"errorCode\": \"account-not-found\",\n  \"errorValues\": {\n    \"accountId\": \"1234\"\n  }\n}\n```\n\nSo the HTTP response status code is both in the HTTP header, and in the `status` attribute of the returned JSON object.\n\nFor a list of `errorCode` and `errorValues`, see the dedicated section [Errors List](#tag/errors_list)\n\n- - -\n\n## Permissions\n\nEach resource needs to have a permission to be accessed.\nPermissions are represented by three elements:\n\n* *domain*: the level on which the resource is: `tenant`, `account`, `project` or `workzone`\n* *resource*: the type of resource, for example `users` or `tags`\n* *right*: the right on the resource the permission is giving.\n  Most of the time it will be either `read` (get/list resource) or `write` (create, update, delete)\n  but can be another action when finer granularity is needed.\n\nThis is represented by a string containing those 3 elements separated by a colon: `<domain>:<resource>:<right>`.\nFor example `account:users:read` is the permission to *read* (view/list) users on the account level.\n\nHere is the list of the currently supported permissions:\n\n* `tenant:user-permissions:read`\n* `tenant:user-permissions:write`\n* `account:account:read`\n* `account:account:update-owner`\n* `account:administrators:read`\n* `account:administrators:write`\n* `account:integrations:read`\n* `account:integrations:write`\n* `account:project-listers:read`\n* `account:project-listers:write`\n* `account:project-managers:read`\n* `account:project-managers:write`\n* `account:projects:read` (implies `project:project:read` on all projects of the account)\n* `account:projects:create`\n* `account:projects:update` (implies `project:project:update-details` on all projects of the account)\n* `account:projects:delete` (implies `project:project:delete` on all projects of the account)\n* `account:roles:read`\n* `account:roles:write`\n* `account:subscriptions:read`\n* `account:subscriptions:update-name`\n* `account:users:read`\n* `account:users:write` (implies `workzone:members:write` on all workzones in the account)\n* `account:groups:read`\n* `project:project:read`\n* `project:project:delete`\n* `project:project:update-details`\n* `project:project:update-owner`\n* `project:project:update-subscription`\n* `project:members:list`\n* `project:annotations:create-integration-link`\n* `project:integrations:read`\n* `project:integrations:write`\n* `workzone:annotations:read`\n* `workzone:annotations:write`\n* `workzone:crops:read`\n* `workzone:crops:write`\n* `workzone:documents:read`\n* `workzone:documents:write`\n* `workzone:export-jobs-reality-data:read`\n* `workzone:export-jobs-reality-data:write`\n* `workzone:import-jobs-reality-data:write`\n* `workzone:measurements:read`\n* `workzone:measurements:write`\n* `workzone:members:write`\n* `workzone:share-links:read`\n* `workzone:share-links:write`\n* `workzone:own-share-links:read`\n* `workzone:own-share-links:write`\n* `workzone:reality-data:read`\n* `workzone:reality-data:write`\n* `workzone:reality-data:transform`\n* `workzone:savedviews:read`\n* `workzone:savedviews:write`\n* `workzone:tags:read`\n* `workzone:tags:write`\n* `workzone:workzones:read`\n* `workzone:workzones:write`\n* `workzone:progress-monitoring-jobs:read`\n* `workzone:progress-monitoring-jobs:write`\n* `workzone:own-progress-monitoring-jobs:read`\n* `workzone:own-progress-monitoring-jobs:write`\n* `workzone:model-reports:read`\n* `workzone:model-reports:write`\n* `workzone:cad-model:read`\n* `workzone:cad-model:write`\n* `workzone:cad-model:transform`\n* `workzone:own-import-jobs-cad-model:read`\n* `workzone:own-import-jobs-cad-model:write`\n* `workzone:import-jobs-cad-model:read`\n* `workzone:import-jobs-cad-model:write`\n* `workzone:video3d:read`\n* `workzone:video3d:write`\n* `workzone:import-video3d:write`\n\n### Roles\n\nA user is given permissions through roles. There are roles on the different levels detailed below.\n\n#### Roles at the account level\n\nRoles on an account are currently not modifiable, and are the following:\n\n* *Account Member* is any user invited to the account\n* *Account Owner*\n* *Account Administrator*\n* *Project Manager*\n* *Project Lister*\n\nAn *account member* has the following permissions:\n\n* `account:account:read` to view the account\n* `account:roles:read` to view roles on the account\n* `account:groups:read` to view groups on the account\n\nAn *account owner* or *account administrator* are account members, and have the following additional permissions:\n\n* `account:projects:read` to list and view all projects on the account\n* `account:projects:update` to update any project on the account\n* `account:roles:write` to create, edit and delete roles on the account\n* `account:users:read` to list users members of the account\n* `account:users:write` to invite or remove users on the account\n* `account:subscriptions:read` to view subscriptions of the account\n* `account:subscriptions:update-name` to rename a subscription of the account\n* `account:administrators:read` to list administrators on the account\n* `account:administrators:write` to invite or remove an administrator\n* `account:project-managers:read` to list project managers on the account\n* `account:project-managers:write` to invite or remove a project manager\n* `account:project-listers:read` to list project listers on the account\n* `account:project-listers:write` to invite or remove a project lister\n* `account:integrations:read` to list and view all integrations configured on the account\n* `account:integrations:write` to create, update and delete integrations on the account\n\nAn account owner has also the permission `account:account:update-owner` that an account administrator does not have,\nto set another user as the account owner\n\nA *project manager* is an account member with the following additional permissions:\n\n* `account:projects:read` to list and view all projects on the account\n* `account:projects:create` to create new projects\n* `account:projects:update` to update any project\n* `account:projects:delete` to delete any project\n* `account:roles:write` to create, edit and delete roles on the account\n* `account:users:read` to list users of the account\n* `account:users:write` to invite or remove users on the account\n* `account:subscriptions:read` to view subscriptions of the account\n* `account:project-managers:read` to list project managers on the account\n* `account:project-managers:write` to invite or remove a project manager\n\nA *project lister* is an account member with the following additional permission:\n\n* `account:projects:read` to list and view all projects of the account\n\n#### Roles at project and workzone levels\n\nRoles can be created on an account to give permissions on project and workzone levels.\n\nUsers and groups are invited to a project with a specific role, thus a user has the role assigned to him,\nbut also the roles of the groups he belongs to.\nA user's permissions are determined by adding the permissions of all his roles.\n\nCurrently the permissions given to a role are restricted to the following:\n\n* `project:project:update-details` + `project:project:delete`\n  allows the user to manage the project\n* `workzone:workzones:read` + `workzone:workzones:write`\n  allows the user to create, modify and delete work zones\n* `workzone:reality-data:read` + `workzone:crops:read` allows the user to view reality data\n* `workzone:reality-data:write` + `workzone:import-jobs-reality-data:write`\n  allows the user to import or delete scans\n* `workzone:reality-data:transform`\n  allows the user to modify the position and/or rotation of a scan\n* `workzone:export-jobs-reality-data:write`\n  allows the user to export and download reality data\n* `workzone:annotations:read` allows the user to view annotations\n* `workzone:annotations:read` + `workzone:annotations:write`\n  allows the user to create, edit and delete annotations, and assign notes to team members\n* `workzone:measurements:read` + `workzone:measurements:write` + `workzone:crops:write`\n  allows the user to add and view 3D measurements (and add/update crops)\n* `workzone:share-links:read` + `workzone:share-links:write`\n  allows the user to create, edit and delete share links\n* `workzone:own-share-links:read` + `workzone:own-share-links:write`\n  allows the user to create, edit and delete the share links they created\n* `workzone:documents:read` + `workzone:documents:write`\n  allows the user to upload and download documents\n* `workzone:tags:read` allows the user to view tags\n* `workzone:tags:write`\n  allows the user to import, create, edit and delete tags\n* `workzone:savedviews:read` allows the user to view saved views\n* `workzone:savedviews:read` + `workzone:savedviews:write`\n  allows the user to create, edit and delete saved views\n* `workzone:members:write` allows the user to add and remove team members\n* `workzone:progress-monitoring-jobs:read` + `workzone:progress-monitoring-jobs:write`\n    + `workzone:own-progress-monitoring-jobs:read` + `workzone:own-progress-monitoring-jobs:write`\n    + `workzone:model-reports:read` + `workzone:model-reports:write`\n      allows the user to create, edit, download and delete progress monitoring reports\n* `workzone:cad-model:read` + `workzone:cad-model:write` + `workzone:own-import-jobs-cad-model:read` +\n  `workzone:own-import-jobs-cad-model:write` + `workzone:import-jobs-cad-model:read` +\n  `workzone:import-jobs-cad-model:write` allow the user to create, edit, download and delete CAD Model and to import\n  them from different sources.\n* `workzone:cad-model:transform`\n  allows the user to modify the position and/or rotation of a 3D model\n* `workzone:video3d:write` + `workzone:import-video3d:write` allow the user to trigger the Add 360Video job\n\nAny member of a project also automatically has the following permissions:\n\n* `project:project:read` and `project:members:list` on the project\n* `workzone:workzones:read` on the workzone he is member and all its child workzones\n\nA project owner automatically has all permissions on the project and all its workzones.\n\nA member having permission `workzone:annotations:write` on the root work zone of a project,\nautomatically has the following permissions on the project:\n\n* `project:annotations:create-integration-link`\n* `project:integrations:read`\n* `project:integrations:write`\n\n- - -\n\n## API 1 and API 2\n\n### What to expect with API 2\n\n* Stage 1: API 2 provides features not covered by API 1.\\\n  Most of features are tagged `BETA` showing that they will continue to mature\n* Stage 2: API 2 `BETA` tags are removed, and API 2 starts covering API 1 features\n* Stage 3: API 2 fully covers API 1 scope\n* Stage 4: API 1 will have a end of life support date communicated\n* Stage 5: API 1 will be decommissioned\n\n### Similarities\n\n* Authentication system is the same. Tokens used on API 1 can be used in API 2.\n* Do follow the same kind of path ex: `/accounts/{accountRef}/projects/{projectRef}/...`\n\n### Differences\n\n* Reference system is different: API 2 handles new Reference types (URNs), classic references (UUID) and \"legacy\n  references\" coming from API 1.\\\n  API 1 supports UUID and \"legacy references\" only.\n* Error messages in API 2 follow\n  the [RFC 9457 (Problem Details for HTTP APIs)](https://www.rfc-editor.org/rfc/rfc9457).\\\n  In short `{\"code\": ...,  \"message\": ...}` becomes `{\"status\": ...,  \"title\": ...}`.\n* All resources returned by API 2 have multiple ref types (always an URN + UUID or INT)\n* POST and PUT endpoints do return full objets (normally available with a GET)\n* Objects returned from API 1 and API 2 differ\n\n### Endpoints only in API 1\n\n* Report Projects Last Accessed Date\n* Report Users Last Activity Date",
    "license": {
      "name": "Apache 2.0",
      "url": "https://www.apache.org/licenses/LICENSE-2.0.html"
    },
    "contact": {
      "name": "API Support",
      "email": "support@cintoo.com"
    },
    "x-logo": {
      "url": "./assets/logo_api.svg",
      "altText": "Cintoo API"
    }
  },
  "servers": [
    {
      "url": "https://aec.cintoo.com"
    }
  ],
  "security": [
    {
      "oauth2": []
    }
  ],
  "tags": [
    {
      "name": "token_management",
      "x-displayName": "Token Management",
      "description": "## Good practices\n\n### Each user should have their own tokens\n\nTokens are personal and are bound to the person who generated them with all their roles and permissions.\n\nIn The Cintoo platform a subscription can hold an unlimited number of users. Furthermore, there are roles (Project Managers) to grant access users to resources with different levels of privileges (read, write, etc.).\n\nThere are only positive outcomes to use as many users as possible.\n\n### Single refresher, multiple accessors\n\nIf you absolutely need to have a single user do all the API calls, but multiple applications share the same tokens, you might very quickly hit the limit of simultaneous refresh tokens valid for a single user.\n\nRemember from the [Access Tokens and Refresh Tokens](#section/API-Specification/Authentication) section that\n\n* Access Tokens are JWT tokens, that are stateless and can be used in parallel\n* Refresh Tokens are stateful and ***cannot*** be used in parallel\n\nOur recommendation in that case would be to have\n\n* A 'refreshing process/app' which would be the only one to use the refresh token and store both Refresh Token and Access Token. The stored Access Token should remain available for other processes\n* Multiple processes/apps that would ask for the Access Tokens, which could be either in the DB **OR** from the 'refreshing process/app'. These requests should be performed intermittently to prevent Access Token expiration, so that the processes/apps can perform all the queries to the Cintoo API\n\n> ***Note:*** the Access Token is a JWT and can easily be decoded to check the expiration date\n\n### Race conditions risk without proper synchronization\n\nIn case that it is not possible to refresh the token from a single app, the client should at least handle race conditions in which a single refresh token is used twice by two concurrent processes. In this case the second refresh will fail. The first client should have stored the new Access-Token/Refresh-Token immediately after the refresh process.\n"
    },
    {
      "name": "errors_list",
      "x-displayName": "Errors List",
      "description": "## 400 Bad Request\n\n### Invalid reference\n\nAll resources including a reference, such as `accountRef` or `projectRef`\nwill return a status 400 when the reference is invalid.\n\n#### Malformed URN\n\n* `errorCode`: `invalid-xxx-urn` where `xxx` is the type of reference\n\nExample:\n\n```json\n{\n  \"status\": 400,\n  \"title\": \"Bad Request\",\n  \"detail\": \"ID type mismatch in Urn. Expected a 'user', found a 'role'\",\n  \"errorCode\": \"invalid-user-urn\"\n}\n```\n\n### Invalid input\n\nThe error code `invalid-input` is used when an element of the request is invalid,\nfor example updating a project with a too long name.\n\n### Specific cases\n\nEach endpoint may have more specific error cases for input validation,\nfor which you'll find the list and description in their dedicated section.\n\n## 401 Unauthorized\n\nAll endpoints, except authentication endpoints, need to be authenticated.\nThe status 401, with `errorCode` = `unauthorized` is returned if the request\nis done without authentication or with an invalid or expired authentication\n\n## 403 Forbidden\n\n### Action forbidden\n\nEntry points doing a creation, an update, or a deletion return a status\n403 when the action is forbidden for the user.\n\n* `errorCode`: `xxx-yyy-forbidden` where:\n  * `xxx` is the type of action, which is one of `create`, `update`, or `delete`\n  * `yyy` is the type of resource on which the action is requested,\n  for example `role`, `user`, ...\n* `errorValues`:\n  * `requiredPermissions`: list of permissions\n\nExample:\n\n```json\n{\n  \"status\": 403,\n  \"title\": \"Forbidden\",\n  \"detail\": \"You do not have the permission to delete project. It requires to have permission \\\"project:project:delete\\\" or \\\"account:projects:delete\\\"\",\n  \"errorCode\": \"delete-project-forbidden\",\n  \"errorValues\": {\n    \"requiredPermissions\": [\"project:project:delete\", \"account:projects:delete\"]\n  }\n}\n```\n\nIf the action is performed on a deleted element, for example create a new work zone on a deleted project,\nthe error code `deleted-xxx` is returned with xxx the type of element on which the action is performed.\n\nExample:\n\n```json\n{\n  \"status\": 403,\n  \"title\": \"Forbidden\",\n  \"detail\": \"Access forbidden because workzone is deleted\",\n  \"errorCode\": \"deleted-workzone\",\n  \"errorValues\": {\n    \"workzoneId\": \"12345\"\n  }\n}\n```\n\n\n### Specific cases\n\nThe following `errorCode` values can be returned with status 403:\n\n* `not-member-of-project` when a user tries to access to a project he is not a member of\n* `not-contributor-of-project` when a user tries to access to a work zone of a project he is not a contributor of\n* `list-*-forbidden` when trying to list resources without the related permissions\n* `view-*-forbidden` when trying to view a resource without needed permissions\n* `remove-contributor-from-work-zone-forbidden` when trying to remove a user as a contributor from a work zone\nwithout needed permissions\n\n## 404 Not Found\n\n### Reference not found\n\nAll resources including a reference, such as `accountRef` or `projectRef`\nwill return a status 404 when the reference is valid but does not exist.\n\n* `errorCode`: `xxx-not-found` where `xxx` is the type of reference\n* `errorValues`:\n  * `xxx`: the ID of the reference, where `xxx` is the type of reference\n\nExample:\n\n```json\n{\n    \"status\": 404,\n    \"title\": \"Not Found\",\n    \"detail\": \"Account 1234 not found\",\n    \"errorCode\": \"account-not-found\",\n    \"errorValues\": {\n        \"account\": \"1234\"\n    }\n}\n```\n\n### Specific cases\n\nThe following `errorCode` values can be returned with status 404:\n\n* `user-email-not-found` when referencing a user referenced by its email was not found in the database\n"
    },
    {
      "name": "tuto_upload_file",
      "x-displayName": "Upload a file into Cloud storage",
      "description": "Objective is to provide recipe on how to upload a file (document, cover...)\n\n### Behavior\nFor security purpose, the files are not going through Cintoo servers directly. \nThe Cintoo server will provide you a secured url to let you upload the file directly to the storage defined by the region of the selected project.\nAfter uploading the file to the cloud storage, you have to inform Cintoo platform that the file has been uploaded successfully, and it should be registered inside your project.\nNot performing this part will not guarantee that the uploaded file won't be deleted by background cleanup tasks.\n\n### Steps\n\n#### 1. Get a signed URL\nThe first step is to get from Cintoo Platform an url to which you can upload your file. The endpoint may differ regarding the type fo file you want to upload (since the permissions are not the same)\n\n* For a project cover (only one file per upload):\n[`POST /api/2/accounts/{accountRef}/projects/{projectRef}/cover`](#tag/Project/operation/signProjectCoverURL)\n\n* For a crop cover (only one file per upload): \n[`POST /api/2/accounts/{accountRef}/projects/{projectRef}/crops/{cropRef}/cover`](#tag/File/operation/signCropCoverURL)\n\n* For another file (many files upload is supported): \n[`POST /api/2/accounts/{accountRef}/projects/{projectRef}/workzones/{workzoneRef}/bulk-files`](#tag/File/operation/signUploadURL)\n\nIn the body of the response, you need to provide for each file you want to upload:\n* the name\n* the extension (not in the case of cover upload)\n* the size\n* the md5 sum-check of the content\n\nThis call will return an url attribute for each file to be used to upload the content on the cloud storage\n\n#### 2. Upload the file\nUse the provided url during previous step to upload the file\n\nThere are different ways to upload file to cloud storage. Here below to link to the different documentation:\n* [S3](https://docs.aws.amazon.com/AmazonS3/latest/userguide/upload-objects.html)\n* [Azure](https://learn.microsoft.com/en-us/azure/storage/blobs/storage-blobs-introduction)\n\n**Required headers to push the files**\n```\nContent-MD5: xxx with xxx being a base 64 encode of the md5sum in binary format.\nExample: MD5SUM=\"$(openssl md5 -binary < \"$FILENAME\" | base64)\"\nCache-Control: max-age=2592000\nx-ms-blob-type: BlockBlob mandatory if the storage type is Azure.\nNote: always adding the x-ms-blob-type could be a good idea as Aws ignores it anyway.\n```\n\n#### 3. Update the file status into Cintoo workzone\nThe last call is to propagate the upload status to Cintoo Platform. This is done by calling a specific endpoint regarding the type of file.\n\n* For a project cover (only one file per upload):\n[`PUT /api/2/accounts/{accountRef}/projects/{projectRef}/cover`](#tag/Project/operation/updateProjectCover)\n\n* For another file (many files upload is supported): \n[`POST /api/2/accounts/{accountRef}/projects/{projectRef}/workzones/{workzoneRef}/bulk-files`](#tag/File/operation/registerFiles)\n\nIn the body of this call, you need to provide the same data as for the 1st call (POST).\n\nThis call will return an id attribute for each file, which is an unique identifier for the file in the Cintoo platform."
    },
    {
      "name": "understand_tag_data",
      "x-displayName": "Understand Tag Data",
      "description": "There are two categories of tags:\n* Simple ones, that are composed of a single bounding box,\n  are usually used to tag something simple like a motor or a pump\n* Complex ones, that are composed of multiple bounding boxes,\n  are usually used to tag something with a complex shape or multiple elements,\n  like a pipeline or a conveyor belt\n\n### Simple Tag\n\n#### Axis-Aligned Bounding Box (AABB)\n\nThe simplest possible Tag, composed of a single bounding box, aligned with the world axis X, Y and Z.\nIt's data contains a `boundingBox` property:\n| Property | Type | Description |\n| -------- | ---- | ----------- |\n| `boundingBox` | 6 numbers | Coordinates of the min and max corners of the tag.<br/>In the order: `minX`, `minY`, `minZ`, `maxX`, `maxY`, `maxZ`, in meters. |\n\n#### Oriented Bounding Box (OBB)\n\nAnother simple tag, composed of two boxes:\n* `orientedBoundingBox` is the main one, defining the real volume of the tag\n* `boundingBox` is the AABB surrounding the OBB\n\n| Property | Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                        |\n| -------- | ---- |------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `orientedBoundingBox` | 10 numbers | Ten numbers representing an Oriented Bounding Box.<br>In the order:<ul><li>`posX`, `posY` and `posZ` represent the center of the bounding box<br>in meters</li><li>`quatX`, `quatY`, `quatZ` and `quatW` represent the quaternion<br>defining the rotation of the bounding box, using the center of<br>the box as a pivot point</li><li>`sizeX`, `sizeY` and `sizeZ` represent the size of the bounding<br>box in meters</li></ul> |\n| `boundingBox` | 6 numbers | Coordinates of the min and max corners of the Axis-Aligned Bounding Box<br>englobing the defined Oriented Bounding Box.<br>In the order: `minX`, `minY`, `minZ`, `maxX`, `maxY`, `maxZ`, in meters.                                                                                                                                                                                                                                |\n\n### Complex Tag\n\nThey have two properties: `boundingBox` and `model`.\n| Property | Type | Description |\n| -------- | ---- | ----------- |\n| `boundingBox` | 6 numbers | Coordinates of the min and max corners of the Axis-Aligned Bounding Box<br>englobing the whole Complex Tag.<br/>In the order: `minX`, `minY`, `minZ`, `maxX`, `maxY`, `maxZ`, in meters. |\n| `model` | `object` | Describe a list of bounding boxes defining the tag. It always contains a<br> `type` property, defining the type of complex tag. Other properties<br> depend on the value of this type and are described in the following sections. |\n\n#### Axis-Aligned Bounding Boxes only\n\nThis format is used if there are only Axis-Aligned Bounding Boxes composing the Complex tag.\n\n| Property | Type        | Description                                                                                                                                                                                                                  |\n| -------- |-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `type` | `String` | `AxisAlignedList`                                                                                                                                                                                                            |\n| `list` | `number[][]` | An array containing multiple sub-arrays. Each sub-array contains the coordinates of the<br> min and max corners of an Axis-Aligned Bounding Box.<br>In the order: `minX`, `minY`, `minZ`, `maxX`, `maxY`, `maxZ`, in meters. |\n\n#### Oriented Bounding Boxes\n\nTwo types are available to represent oriented bounding boxes, with the second type being an optimized version for storage purposes only.\n\n##### Independent Oriented Bounding Boxes\n\nThis format is used if there are only Oriented Bounding Boxes composing the Complex tag, with each of them having a different orientation. If an orientation is shared, see the next Shared Oriented Bounding Boxes section.\n\n| Property | Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |\n| -------- | ---- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `type` | `String` | `OrientedList`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |\n| `orientedBoundingBoxList` | `number[][]` | An array containing multiple sub-arrays. Each sub-array contains ten<br> numbers representing an Oriented Bounding Box.<br>In the order:<ul><li>`posX`, `posY` and `posZ` represent the center of the<br> bounding box in meters</li><li>`quatX`, `quatY`, `quatZ` and `quatW` represent the<br> quaternion defining the rotation of the bounding box,<br> using the center of the box as a pivot point</li><li>`sizeX`, `sizeY` and `sizeZ` represent the size of the<br> bounding box, in meters</li></ul> |\n\n##### Shared Oriented Bounding Boxes\n\nThis is an optimization of Independent Oriented Bounding Boxes, for boxes with a similar orientation.\n\n| Property | Type | Description                                                                                                                                                                                                                                                                                                                                                                                                     |\n| -------- | ---- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| `type` | `String` | `OrientedList`                                                                                                                                                                                                                                                                                                                                                                                                  |\n| `groupedOBBList` | `number[][]` | An array containing multiple sub-arrays. Each sub-array contains numbers, in order:<ul><li>`quatX`, `quatY`, `quatZ`, `quatW` is the shared rotation, represented<br> by a quaternion, with the pivot being the center of each box</li><li>the remaining numbers go 6 by 6: `posX`, `posY`, `posZ`, `sizeX`, `sizeY`, `sizeZ`<br> for each box, with the position and the size of each box, in meters</li></ul> |\n\n##### Mix of all\n\nApart from BinarizedBoundingBox, all interfaces under “Complex Tags” can be mixed together, under the OrientedList type.\n\n| Property | Type              |\n| -------- |-------------------|\n| `type` | `OrientedList`    |\n| `list` | `[number x 6][]`  |\n| `orientedBoundingBoxList` | `[number x 10][]` |\n| `groupedOBBList` | `number[][]`      |\n\n#### Binarized Axis-Aligned Bounding Boxes\n\nThis format is an internal format from Cintoo, intended for use within Cintoo only. It is only constituted by AABBs.\n\n\n"
    }
  ],
  "paths": {
    "/api/2/accounts": {
      "get": {
        "summary": "List accounts",
        "operationId": "getAccounts",
        "description": "<span class='tag beta'>BETA</span>List available accounts for the current user",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "List and content of the Accounts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Account"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts\" % host,\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}": {
      "get": {
        "summary": "Get account",
        "operationId": "getAccount",
        "description": "<span class='tag beta'>BETA</span>Get an account details\n\nRequires the permission `account:account:read` on the account (in other words to be a member of the account).\n",
        "tags": [
          "Account"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "responses": {
          "200": {
            "description": "Content of the requested Account",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Account"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID\" --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s\" % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/subscriptions": {
      "get": {
        "summary": "List subscriptions",
        "operationId": "getSubscriptions",
        "description": "<span class='tag beta'>BETA</span>List available subscriptions into this account.\n\nRequires the permission `account:subscriptions:read` on the account.\n\nThe `inviteAccountOwnerInNewProjects` property is only included when the caller is the account owner.\n\nThe `end` property is only included when the caller has the `account:subscriptions:read-sensitive-infos` permission (account owner or administrator).\n",
        "tags": [
          "Subscription"
        ],
        "parameters": [
          {
            "name": "accountId",
            "required": true,
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List and content of the Subscriptions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Subscription"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/subscriptions\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/subscriptions\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/subscriptions`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/subscriptions/{subscriptionRef}": {
      "get": {
        "summary": "Get subscription",
        "operationId": "getSubscription",
        "description": "<span class='tag beta'>BETA</span>Get a subscription details.\n\nRequires the permission `account:subscriptions:read` on the account.\n\nThe `inviteAccountOwnerInNewProjects` property is only included when the caller is the account owner.\n\nThe `end` property is only included when the caller has the `account:subscriptions:read-sensitive-infos` permission (account owner or administrator).\n",
        "tags": [
          "Subscription"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/subscriptionRef"
          }
        ],
        "responses": {
          "200": {
            "description": "Content of the requested Subscription",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subscription"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport SUBSCRIPTIONID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/subscriptions/$SUBSCRIPTIONID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nsubscriptionId = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/subscriptions/%s\"\n    % (host, accountUUID, subscriptionId),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst subscriptionId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/subscriptions/${subscriptionId}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/subscriptions/{subscriptionRef}/usage-report": {
      "get": {
        "summary": "Generate an Usage Report",
        "operationId": "getUsageReport",
        "description": "<span class='tag beta'>BETA</span>- Generate an Usage Report, listing actions done per day, per user, per project on a given subscription.",
        "tags": [
          "Usage Report"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/subscriptionRef"
          },
          {
            "in": "query",
            "name": "from",
            "schema": {
              "$ref": "#/components/schemas/date"
            },
            "description": "The date to start to retrieve usage report data from (included)"
          },
          {
            "in": "query",
            "name": "until",
            "schema": {
              "$ref": "#/components/schemas/date"
            },
            "description": "The date to start to retrieve usage report data from (included)"
          },
          {
            "in": "query",
            "name": "includeDeleted",
            "schema": {
              "type": "boolean"
            },
            "description": "Also export deleted (including permanently deleted) projects"
          }
        ],
        "responses": {
          "200": {
            "description": "Redirection to a pre-signed download link, in the Location header",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UsageReport"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport SUBSCRIPTIONUUID=...\n\ncurl --location \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/subscriptions/$SUBSCRIPTIONUUID/usage-report?from=2025-09-29&includeDeleted=true\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nsubscriptionUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/subscriptions/%s/usage-report?from=2025-09-29&includeDeleted=true\"\n    % (host, accountUUID, subscriptionUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst subscriptionUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/subscriptions/${subscriptionUUID}/usage-report?from=2025-09-29&includeDeleted=true`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/users/bulk-invite": {
      "post": {
        "summary": "Invite users",
        "operationId": "inviteUsers",
        "description": "<span class='tag beta'>BETA</span>Invite users to an account\n\nThis endpoint is *idempotent* which means it applies the state requested by the caller.\nIt can be used to invite users to an account with a set of accountRole\nor it can be used to grant new accountRoles to existing users.\n\nUsers that are new to the Cintoo cloud platform are expected to receive an invitation email where they will be able to define a password.\n\nRequires the caller:\n* to have permission `account:administrators:write` to invite users as administrators\n* to have permission `account:project-managers:write` to invite users as project managers\n* to have permission `account:project-listers:write` to invite users as project listers\n* to have permission `workzone:members:write` to invite users without specific account role\n\nIf any of the roles is invalid or if some roles are not allowed for the caller, then the whole request returns an error,\nno invitation are sent and no change is applied.\n",
        "tags": [
          "User"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "email"
                  ],
                  "properties": {
                    "email": {
                      "type": "string"
                    },
                    "roles": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/AccountRoles"
                      },
                      "uniqueItems": true
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "User(s) have been successfully invited with requested AccountRoles"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/users/bulk-invite\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '[\n    { \"email\":\"admin@example.com\", \"roles\": [\"administrator\"] },\n    { \"email\":\"manager@example.com\", \"roles\": [\"administrator\", \"projectManager\"] },\n    { \"email\":\"joe@example.com\" }\n  ]'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/users/bulk-invite\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [\n    { \"email\":\"admin@example.com\", \"roles\": [\"administrator\"] },\n    { \"email\":\"manager@example.com\", \"roles\": [\"administrator\", \"projectManager\"] },\n    { \"email\":\"joe@example.com\" }\n  ]\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/users/bulk-invite`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [\n        { \"email\":\"admin@example.com\", \"roles\": [\"administrator\"] },\n        { \"email\":\"manager@example.com\", \"roles\": [\"administrator\", \"projectManager\"] },\n        { \"email\":\"joe@example.com\" }\n      ]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/users": {
      "get": {
        "summary": "List users",
        "operationId": "getUsers",
        "description": "<span class='tag beta'>BETA</span>List available users into this account.\nData is anonymized for not confirmed users.\n\nRequires the caller to have one of following permissions: \n* `account:users:read`\n* `workzone:members:write` on any work zone inside the account\n",
        "tags": [
          "User"
        ],
        "parameters": [
          {
            "name": "accountRef",
            "required": true,
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List and content of the Users",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/User"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/users\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/users\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/users`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/users/{userRef}": {
      "get": {
        "summary": "Get user details",
        "operationId": "getUser",
        "description": "<span class='tag beta'>BETA</span>Details about a given user into this account.\nData is anonymized in case the user is not confirmed.\n\nRequires the caller to have one of following:\n* `account:users:read`\n* `workzone:members:write` on any work zone inside the account\n",
        "tags": [
          "User"
        ],
        "parameters": [
          {
            "name": "accountRef",
            "required": true,
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "name": "userRef",
            "required": true,
            "$ref": "#/components/parameters/userRef"
          }
        ],
        "responses": {
          "200": {
            "description": "Details about the user into this account.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/User"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport USERREF=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/users/$USERREF\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nuserRef = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/users/%s\"\n    % (host, accountUUID, userRef),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst userRef = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/users/${userRef}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/groups": {
      "get": {
        "summary": "List groups",
        "operationId": "getGroups",
        "description": "<span class='tag beta'>BETA</span>List available groups in this account.\n\nRequires the permission `account:groups:read` on the account.\n",
        "tags": [
          "Group"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List and content of the Groups",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Group"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/groups\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/groups\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/groups`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/groups/{groupRef}": {
      "get": {
        "summary": "Get group",
        "operationId": "getGroup",
        "description": "<span class='tag beta'>BETA</span>Get a group details.\n\nRequires the permission `account:groups:read` on the account.\n",
        "tags": [
          "Group"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/groupRef"
          }
        ],
        "responses": {
          "200": {
            "description": "Content of the requested Group",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Group"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport GROUPUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/groups/$GROUPUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ngroupUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/groups/%s\"\n    % (host, accountUUID, groupUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst groupUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/groups/${groupUUID}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/groups/{groupRef}/members": {
      "post": {
        "summary": "Add users to a group",
        "operationId": "addUsersToGroup",
        "description": "<span class='tag beta'>BETA</span>Add a list of users to a group",
        "tags": [
          "Group"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/groupRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UserRef"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "new state of the modified group",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Group"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport GROUPUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/groups/$GROUPUUID/members\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"[\\\"userRef1\\\", \\\"userRef2\\\"]\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ngroupUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/groups/%s/members\"\n    % (host, accountUUID, groupUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [\"userRef1\", \"userRef2\"]\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst groupUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/groups/${groupUUID}/members`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [\"userRef1\", \"userRef2\"]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Remove users from a group",
        "operationId": "removeUsersFromGroup",
        "description": "<span class='tag beta'>BETA</span>Removes a list of users from a group",
        "tags": [
          "Group"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/groupRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UserRef"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "new state of the modified group",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Group"
                }
              }
            }
          },
          "400": {
            "description": "users not in the group",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorBadRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `users-not-in-groups` some of the users were in not in the group\n"
                        },
                        "errorValues": {
                          "type": "object",
                          "properties": {
                            "users": {
                              "type": "string",
                              "description": "list of the users that were not in the group"
                            }
                          }
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport GROUPUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/groups/$GROUPUUID/members\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"[\\\"userRef1\\\", \\\"userRef2\\\"]\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ngroupUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/groups/%s/members\"\n    % (host, accountUUID, groupUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [\"userRef1\", \"userRef2\"]\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst groupUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/groups/${groupUUID}/members`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [\"userRef1\", \"userRef2\"]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/roles": {
      "get": {
        "summary": "List Roles",
        "operationId": "getRoles",
        "description": "<span class='tag beta'>BETA</span>List available roles into this account.\n\nRequires the permission `account:roles:read`.\n",
        "tags": [
          "Role"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List and content of the Roles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Role"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/roles\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/roles\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/roles`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Create Role",
        "operationId": "createRole",
        "description": "<span class='tag beta'>BETA</span>Create a custom role.\n\nRequires the permission `account:roles:write`.\n\nThe allowed combinations of permissions are documented [here](#section/API-Specification/Permissions)\n",
        "tags": [
          "Role"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/roleCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The role was successfully created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Role"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/roles\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"name\": \"Viewer\",\n    \"description\": \"Read only user\",\n    \"color\": \"#123456\",\n    \"permissions\": [\"view3d\", \"measure\", \"view_tag\"]\n}'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/roles\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"name\": \"Viewer\",\n    \"description\": \"Read only user\",\n    \"color\": \"#12345e\",\n    \"permissions\": [\"view3d\", \"measure\", \"view_tag\"]\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/roles`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"name\": \"Viewer\",\n        \"description\": \"Read only user\",\n        \"color\": \"#123456\",\n        \"permissions\": [\"view3d\", \"measure\", \"view_tag\"]\n    }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/members": {
      "delete": {
        "summary": "Remove users from an account",
        "operationId": "removeUsersFromAccount",
        "description": "<span class='tag beta'>BETA</span>Remove users from an account\n\nRequires to be either owner, administrator or manager of the account.\n\nNotes:\n  - The Account Owner cannot be removed from the account. An account cannot be orphaned.\n  - Project Owners cannot be removed from the account. Projects cannot be orphaned.\n",
        "tags": [
          "Account"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UserUrn"
                },
                "example": [
                  "userRef1",
                  "userRef2"
                ]
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "The users were successfully removed from the account"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorForbidden"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `remove-user-from-account-forbidden`\n"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "remove-user-from-account-forbidden": {
                    "value": {
                      "status": 403,
                      "title": "Forbidden",
                      "detail": "You do not have the permission to remove users from this account. It requires to be owner, administrator or manager of the account",
                      "errorCode": "remove-user-from-account-forbidden"
                    }
                  },
                  "remove-owner-from-account-forbidden": {
                    "value": {
                      "status": 403,
                      "title": "Forbidden",
                      "detail": "Account Owner cannot be removed from the account. An account must always have a owner.",
                      "errorCode": "delete-account-owner-forbidden",
                      "errorValues": [
                        {
                          "user": "ownerId"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTID=...\nexport USERID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTID/members\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '[ \"$USERID\" ]'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountID = \"...\"\nuserId = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/members\" % (host, accountID),\n  headers = { \"Authorization\": \"Bearer %s\" % token},\n  json = [ userId ]\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountId = \"...\";\nconst token = \"...\";\nconst userId = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountId}/members`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [ userId ]\n  ),\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/members/{userRef}/roles": {
      "post": {
        "summary": "Update the account roles of a user",
        "operationId": "updateUserAccountRoles",
        "description": "<span class='tag beta'>BETA</span>Update the account roles of a user\n\nRequires to be either owner or administrator of the account.\n\nTo grant/revoke an account role, the permissions are checked:\n- For administrator: `account:administrators:write`\n- For project manager: `account:project-managers:write`\n- For project lister: `account:project-listers:write`\n",
        "tags": [
          "Account"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/userRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/AccountRoles"
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "the roles have been correctly updated"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorForbidden"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `update-user-account-roles-forbidden`\n"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "update-user-account-roles-forbidden": {
                    "value": {
                      "status": 403,
                      "title": "Forbidden",
                      "detail": "You do not have the permission to update user-account-roles",
                      "errorCode": "update-user-account-roles-forbidden"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTID=...\nexport USERID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTID/members/$USERID/roles\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '[\"administrator\", \"projectManager\", \"projectLister\"]'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountID = \"...\"\nuserID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/members/%s/roles\" % (host, accountID, userID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [\"administrator\", \"projectManager\", \"projectLister\"]\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountId = \"...\";\nconst userId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountId}/members/${userId}/roles`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [\"administrator\", \"projectManager\", \"projectLister\"]\n  ),\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/roles/{roleRef}": {
      "get": {
        "summary": "Get Role",
        "operationId": "getRole",
        "description": "<span class='tag beta'>BETA</span>Get a role details.\n\nRequires the permission `account:roles:read`.\n",
        "tags": [
          "Role"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/roleRef"
          }
        ],
        "responses": {
          "200": {
            "description": "Content of the requested Role",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Role"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport ROLEID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/roles/$ROLEID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nroleId = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/roles/%s\"\n    % (host, accountUUID, roleId),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst roleId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/roles/${roleId}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete Role",
        "operationId": "deleteRole",
        "description": "<span class='tag beta'>BETA</span>Delete a Role.\n\nRequires the permission `account:roles:write`.\n",
        "tags": [
          "Role"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/roleRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The role was successfully deleted"
          },
          "400": {
            "description": "Cannot delete base role, or role is used in projects",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorBadRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `cannot-delete-base-role` if the role is a base role\n* `role-used` if the role is used in projects\n"
                        },
                        "errorValues": {
                          "type": "object",
                          "properties": {
                            "roleId": {
                              "type": "string",
                              "description": "role id for errorCode `role-used`"
                            },
                            "projectIds": {
                              "type": "string",
                              "description": "comma separated list of projects using the role for errorCode `role-used`"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "cannot-delete-base-role": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Base roles can't be deleted",
                      "errorCode": "cannot-delete-base-role"
                    }
                  },
                  "role-used": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Role 1234 is in use in projects projectId1, projectId2, projectId3",
                      "errorCode": "role-used",
                      "errorValues": {
                        "roleId": "1234",
                        "projectIds": "projectId1, projectId2, projectId3"
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport ROLEID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/roles/$ROLEID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nroleId = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/roles/%s\"\n    % (host, accountUUID, roleId),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst roleId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/roles/${roleId}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "put": {
        "summary": "Update Role",
        "operationId": "updateRole",
        "description": "<span class='tag beta'>BETA</span>Update a role.\n\n<span class='block' style='background-color: PapayaWhip;'><span class='icon' style='color: red; font-size:20px;'>&#9888;</span> Overwrites all fields. Missing fields will be considered as null and current values will be erased</span>\n\nPermissions:\n\nRequires the permission `account:roles:write`.\n\nThe allowed combinations of permissions are documented [here](#section/API-Specification/Permissions)\n",
        "tags": [
          "Role"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/roleRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/roleUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "New content of the updated Role",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Role"
                }
              }
            }
          },
          "400": {
            "description": "Cannot update base role",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorBadRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "`cannot-update-base-role` if the role is a base role"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "cannot-update-base-role": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Base roles can't be updated",
                      "errorCode": "cannot-update-base-role"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport ROLEID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/roles/$ROLEID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n      \"description\": \"Better description\",\n      \"color\": \"#E529B0\"\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nroleId = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/roles/%s\"\n    % (host, accountUUID, roleId),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"description\": \"Better description\",\n    \"color\": \"#E529B0\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst roleId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/roles/${roleId}`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n          \"description\": \"Better description\",\n          \"color\": \"#E529B0\"\n      }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/integrations": {
      "get": {
        "summary": "List integrations on the account",
        "operationId": "getAccountIntegrations",
        "description": "<span class='tag beta'>BETA</span>List all integrations on the account\n\nRequires the permission `account:integrations:read` automatically granted for account administrators and account owner.\n",
        "tags": [
          "Integrations"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List of integrations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountIntegrations"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/integrations\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/integrations\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/integrations`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/integrations/konekt": {
      "post": {
        "summary": "Create an account integration with Konekt",
        "operationId": "createAccountIntegrationKonekt",
        "description": "<span class='tag beta'>BETA</span>Configure an integration on the account with Newforma Konekt.\n\nRequires the permission `account:integrations:write` automatically granted for account administrators and account owner.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/accountIntegrationKonektCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The integration was successfully created or updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountIntegrationKonekt"
                }
              }
            }
          },
          "409": {
            "description": "A configuration already exists with the same Konekt Hub",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorConflict"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/integrations/konekt\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"token\\\":\\\"...\\\"}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/integrations/konekt\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"token\": \"...\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/integrations/konekt`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"token\":\"...\"}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/integrations/konekt/{integrationRef}": {
      "get": {
        "summary": "Get an account integration with Konekt",
        "operationId": "getKonektAccountIntegrationById",
        "description": "<span class='tag beta'>BETA</span>Get an integration with Newforma Konekt configured on the account\n\nRequires the permission `account:integrations:read` automatically granted for account administrators and account owner.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/accountIntegrationKonektRef"
          }
        ],
        "responses": {
          "200": {
            "description": "account integration to Konekt",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountIntegrationKonekt"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport INTEGRATIONUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/integrations/konekt/$INTEGRATIONUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nintegrationUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/integrations/konekt/%s\"\n    % (host, accountUUID, integrationUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst integrationUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/integrations/konekt/${integrationUUID}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      },
      "put": {
        "summary": "Update an account integration with Konekt",
        "operationId": "updateKonektAccountIntegration",
        "description": "<span class='tag beta'>BETA</span>Update the configuration for the integration with Newforma Konekt.\n\nRequires the permission `account:integrations:write` automatically granted for account administrators and account owner.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/accountIntegrationKonektRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/accountIntegrationKonektUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The integration was successfully updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountIntegrationKonekt"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport INTEGRATIONUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/integrations/konekt/$INTEGRATIONUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"options\\\":{\\\"allowCreateNewUsersOnHub\\\":false}}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nintegrationUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/integrations/konekt/%s\"\n    % (host, accountUUID, integrationUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"options\": {\"allowCreateNewUsersOnHub\": False}\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst integrationUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/integrations/konekt/${integrationUUID}`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"options\":{\"allowCreateNewUsersOnHub\":false}}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete an account integration with Konekt",
        "operationId": "deleteKonektAccountIntegration",
        "description": "<span class='tag beta'>BETA</span>Delete an integration with Newforma Konekt on the account.\n\nRequires the permission `account:integrations:write` automatically granted for account administrators and account owner.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/accountIntegrationKonektRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The integration was successfully deleted"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport INTEGRATIONUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/integrations/konekt/$INTEGRATIONUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nintegrationUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/integrations/konekt/%s\"\n    % (host, accountUUID, integrationUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst integrationUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/integrations/konekt/${integrationUUID}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/integrations/konekt/{integrationRef}/connection": {
      "post": {
        "summary": "Connect an account integration with Konekt",
        "operationId": "connectKonektAccountIntegration",
        "description": "<span class='tag beta'>BETA</span>Connect an integration previously disconnected.\n\nRequires the permission `account:integrations:write` automatically granted for account administrators and account owner.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/accountIntegrationKonektRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/accountIntegrationConnectionKonektCreate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The connection was successfully created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountIntegrationKonekt"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport INTEGRATIONUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/integrations/konekt/$INTEGRATIONUUID/connection\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"token\\\":\\\"...\\\"}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nintegrationUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/integrations/konekt/%s/connection\"\n    % (host, accountUUID, integrationUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"token\": \"...\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst integrationUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/integrations/konekt/${integrationUUID}/connection`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"token\":\"...\"}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Disconnect an account integration with Konekt",
        "operationId": "deleteKonektAccountIntegrationConnection",
        "description": "<span class='tag beta'>BETA</span>Disconnect an integration without removing it.\n\nRequires the permission `account:integrations:write` automatically granted for account administrators and account owner.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/accountIntegrationKonektRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The connection was successfully deleted"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport INTEGRATIONUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/integrations/konekt/$INTEGRATIONUUID/connection\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nintegrationUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/integrations/konekt/%s/connection\"\n    % (host, accountUUID, integrationUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst integrationUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/integrations/konekt/${integrationUUID}/connection`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects": {
      "get": {
        "summary": "List Projects",
        "operationId": "getProjects",
        "description": "<span class='tag beta'>BETA</span>List active and deleted projects into this account.",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/countScans"
          },
          {
            "$ref": "#/components/parameters/countTags"
          },
          {
            "$ref": "#/components/parameters/countWorkzones"
          }
        ],
        "responses": {
          "200": {
            "description": "List and content of the Projects",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Project"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\n# Default: statsInfo includes all statistics\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n\n# Disable all statistics for faster response\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects?countScans=false&countTags=false&countWorkzones=false\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\n# Default: statsInfo includes all statistics\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprojects = response.json()\nfor project in projects:\n    print(project[\"name\"], project[\"statsInfo\"])  # {\"scanCount\": ..., ...}\n\n# Disable all statistics for faster response\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token},\n  params = { \"countScans\": \"false\", \"countTags\": \"false\", \"countWorkzones\": \"false\" }\n)\nprojects = response.json()\nfor project in projects:\n    # statsInfo is null when all count* params are false\n    print(project[\"name\"], project[\"statsInfo\"])  # None\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\n// Default: statsInfo includes all statistics\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\nconst projects = await res.json();\nfor (const project of projects) {\n  console.log(project.name, project.statsInfo); // { scanCount, scanSize, tagCount, workzoneCount }\n}\n\n// Disable all statistics for faster response\nconst params = new URLSearchParams({\n  countScans: \"false\",\n  countTags: \"false\",\n  countWorkzones: \"false\",\n});\nconst urlFast = `${url}?${params}`;\nconst resFast = await fetch(urlFast, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\nconst projectsFast = await resFast.json();\nfor (const project of projectsFast) {\n  // statsInfo is null when all count* params are false\n  console.log(project.name, project.statsInfo); // null\n}\n"
          }
        ]
      },
      "post": {
        "summary": "Create Project",
        "operationId": "createProject",
        "description": "<span class='tag beta'>BETA</span>Create a project.\n\nRequires the permission `account:projects:create` on the account.\n",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "subscriptionId": {
                    "$ref": "#/components/schemas/SubscriptionUrn"
                  },
                  "region": {
                    "type": "string"
                  },
                  "location": {
                    "$ref": "#/components/schemas/Location"
                  },
                  "coverUrl": {
                    "type": "string"
                  },
                  "coverBlobName": {
                    "$ref": "#/components/schemas/BlobName"
                  },
                  "spatialReference": {
                    "type": "object",
                    "nullable": true,
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/SpatialReference"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The project was created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "400": {
            "description": "The subscription is not active",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorBadRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `subscription-not-active` if the subscription is not active\n* `region-not-found` if the supplied region name is not known\n"
                        },
                        "errorValues": {
                          "type": "object",
                          "properties": {
                            "subscriptionId": {
                              "type": "string",
                              "description": "Subscription ID for error code `subscription-not-active`"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "subscription-not-active": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Subscription is not active",
                      "errorCode": "subscription-not-active",
                      "errorValues": {
                        "subscriptionId": "1234"
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"name\": \"created with Wapi\",\n    \"subscriptionId\": 1,\n    \"description\": \"Hello !\",\n    \"region\": \"default\",\n    \"location\": {\n      \"lat\": 43.6554,\n      \"lng\": 7.25\n    }\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects\"\n    % (host, accountUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"name\": \"created with Wapi\",\n    \"subscriptionId\": 1,\n    \"description\": \"Hello !\",\n    \"region\": \"default\",\n    \"location\": {\n      \"lat\": 43.6554,\n      \"lng\": 7.25\n    }\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"name\": \"created with Wapi\",\n        \"subscriptionId\": 1,\n        \"description\": \"Hello !\",\n        \"region\": \"default\",\n        \"location\": {\n          \"lat\": 43.6554,\n          \"lng\": 7.25\n        }\n      }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}": {
      "get": {
        "summary": "Get Project",
        "operationId": "getProject",
        "description": "<span class='tag beta'>BETA</span>Get a project details.\n\nRequires the permission `project:project:read` on the project.\nIn other words, the requester MUST already be a member of the project at some level:\n- account owner, administrator, project manager or project lister\n- project creator or owner\n- be a contributor of the project, or be a member of a contributing group\n",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/countScans"
          },
          {
            "$ref": "#/components/parameters/countTags"
          },
          {
            "$ref": "#/components/parameters/countWorkzones"
          }
        ],
        "responses": {
          "200": {
            "description": "Content of the requested Project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\n# Default: statsInfo includes all statistics\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n\n# Disable scan statistics for faster response\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID?countScans=false\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\n# Default: statsInfo includes all statistics\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n\n# Disable all statistics for faster response\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token},\n  params = { \"countScans\": \"false\", \"countTags\": \"false\", \"countWorkzones\": \"false\" }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\n// Default: statsInfo includes all statistics\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\nconsole.log(res.status);\nconst data1 = await res.json();\nconsole.log(data1);\n\n// Disable all statistics for faster response\nconst params = new URLSearchParams({\n  countScans: \"false\",\n  countTags: \"false\",\n  countWorkzones: \"false\",\n});\nconst urlFast = `${url}?${params}`;\nconst resFast = await fetch(urlFast, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\nconsole.log(res.status);\nconst data2 = await res.json();\nconsole.log(data2);\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete Project",
        "operationId": "deleteProject",
        "description": "<span class='tag beta'>BETA</span>Delete a project.\n\nRequires the permission `project:project:delete` on the project.\n(Note that permission `account:projects:delete` on the account implies the permission\n`project:project:delete` on all projects of the account).\n",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/permanentProjectDelete"
          }
        ],
        "responses": {
          "204": {
            "description": "The project was deleted successfully"
          },
          "400": {
            "description": "The project is already deleted",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorBadRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `project-deleted` if the project is already deleted. Add permanent flag to completely delete it.\n* `project-not-deleted` if asking for a permanent delete on a not deleted project. Delete it first.\n"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "project-deleted": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Project is deleted",
                      "errorCode": "project-deleted",
                      "errorValues": {
                        "projectId": "1234"
                      }
                    }
                  },
                  "project-not-deleted": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Project is not deleted yet",
                      "errorCode": "project-not-deleted",
                      "errorValues": {
                        "projectId": "1234"
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      },
      "put": {
        "summary": "Update Project",
        "operationId": "updateProject",
        "description": "<span class='tag beta'>BETA</span>Update a Project. \n\n<span class='block' style='background-color: PapayaWhip;'><span class='icon' style='color: red; font-size:20px;'>&#9888;</span> Overwrites all fields. Missing fields will be considered as null and current values will be erased</span>\n\nPermissions:\n- To update everything: be the account owner, administrator, or project owner\n- To update everything EXCEPT the subscription and the owner: have the \"Update, delete or restore projects\" permission on the project\n- When updating the owner of a project, the new owner MUST be a project manager\n",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/countScans"
          },
          {
            "$ref": "#/components/parameters/countTags"
          },
          {
            "$ref": "#/components/parameters/countWorkzones"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "description",
                  "subscriptionId",
                  "ownerId",
                  "location",
                  "coverBlobName",
                  "spatialReference"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "example": "New name for my project",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 1000,
                    "example": "This is a really interesting project"
                  },
                  "subscriptionId": {
                    "$ref": "#/components/schemas/SubscriptionRef"
                  },
                  "ownerId": {
                    "$ref": "#/components/schemas/UserRef"
                  },
                  "location": {
                    "type": "object",
                    "nullable": true,
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/Location"
                      }
                    ]
                  },
                  "coverBlobName": {
                    "type": "string",
                    "nullable": true,
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/BlobName"
                      }
                    ]
                  },
                  "spatialReference": {
                    "type": "object",
                    "nullable": true,
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/SpatialReference"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The project was updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "400": {
            "description": "Cannot update subscription because capacity is exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorBadRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `capacity-exceeded-scan`, `capacity-exceeded-geoimage`, `capacity-exceeded-tag` if the target\nsubscription cannot accept the project due to a capacity exceeded, respectively of Scan,\nGeoImage, or Tag\n* `new-project-owner-not-manager` the new owner of a project needs to be a project manager\n"
                        },
                        "errorValues": {
                          "type": "object",
                          "properties": {
                            "subscriptionId": {
                              "type": "string",
                              "description": "target subscription ID for error codes `capacity-exceeded-xxx`"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "capacity-exceeded-scan": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "not enough Scan capacity to accept project on subscription 1234",
                      "errorCode": "capacity-exceeded-scan"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Update project ownership or subscription forbidden, or New owner must be a Project Manager",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorForbidden"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `update-project-ownership-or-subscription-forbidden`\n* `new-project-owner-not-manager`\n"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "update-project-ownership-or-subscription-forbidden": {
                    "value": {
                      "status": 403,
                      "title": "Forbidden",
                      "detail": "You do not have the permission to update project ownership or subscription. It requires to be Project Owner, or Administrator",
                      "errorCode": "update-project-ownership-or-subscription-forbidden"
                    }
                  },
                  "new-project-owner-not-manager": {
                    "value": {
                      "status": 403,
                      "title": "Forbidden",
                      "detail": "New owner must be a Project Manager",
                      "errorCode": "new-project-owner-not-manager"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"name\": \"Better name\",\n    \"description\": \"I love this name more\"\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"name\": \"Better name\",\n    \"description\": \"I love this name more\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"name\": \"Better name\",\n        \"description\": \"I love this name more\"\n      }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "patch": {
        "summary": "Patch Project",
        "operationId": "patchProject",
        "description": "<span class='tag beta'>BETA</span>Patch a Project. \n\n<span class='block' style='background-color: Lavender;'><span class='icon' style='color: blue; font-size:25px;'>&#9432;</span> Unlike the PUT operation (Update a project), the patch updates only the provided fields.</span>\n\nPermissions:\n- To update everything: be the account owner, administrator, or project owner\n- To update everything EXCEPT the subscription and the owner: have the \"Update, delete or restore projects\" permission on the project\n- When updating the owner of a project, the new owner MUST be a project manager\n",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/countScans"
          },
          {
            "$ref": "#/components/parameters/countTags"
          },
          {
            "$ref": "#/components/parameters/countWorkzones"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "example": "New name for my project",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "description": {
                    "type": "string",
                    "nullable": true,
                    "maxLength": 1000,
                    "example": "This is a really interesting project"
                  },
                  "subscriptionId": {
                    "$ref": "#/components/schemas/SubscriptionRef"
                  },
                  "ownerId": {
                    "$ref": "#/components/schemas/UserRef"
                  },
                  "location": {
                    "type": "object",
                    "nullable": true,
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/Location"
                      }
                    ]
                  },
                  "coverBlobName": {
                    "type": "string",
                    "nullable": true,
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/BlobName"
                      }
                    ]
                  },
                  "spatialReference": {
                    "type": "object",
                    "nullable": true,
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/SpatialReference"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The project was updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request PATCH --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"name\": \"Better name\",\n    \"description\": \"I love this name more\"\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.patch(\n  \"https://%s/api/2/accounts/%s/projects/%s\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"name\": \"Better name\",\n    \"description\": \"I love this name more\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}`;\nconst res = await fetch(url, {\n  method: \"PATCH\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"name\": \"Better name\",\n        \"description\": \"I love this name more\"\n      }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/cover": {
      "post": {
        "summary": "Get a signed URL for project cover file upload",
        "operationId": "signProjectCoverURL",
        "description": "<span class='tag beta'>BETA</span>Get a signed URL for project cover file upload\n\nRequires the permission `projects:project:update-details`.\n\nAfter this call, use the `url`s from the response to upload the cover file.\n\nRequired headers to push the files\n* `Content-MD5: xxx` with `xxx` being a base 64 encode of the md5sum in binary format.\\\n  Example: `MD5SUM=\"$(openssl md5 -binary < \"$FILENAME\" | base64)\"`\n* `Cache-Control: max-age=2592000`\n* `x-ms-blob-type: BlockBlob` mandatory if the storage type is Azure. \\\n  Note: always adding the `x-ms-blob-type` could be a good idea as Aws ignores it anyway.\n",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "extension",
                  "size",
                  "md5"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "extension": {
                    "type": "string",
                    "enum": [
                      "png",
                      "jpg",
                      "jpeg"
                    ]
                  },
                  "size": {
                    "type": "integer",
                    "description": "Size of the file (bytes)",
                    "minimum": 1,
                    "maximum": 10485760
                  },
                  "md5": {
                    "type": "string",
                    "description": "The md5 sum-check of the file"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The signing process succeeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "provider",
                    "expiresIn",
                    "file"
                  ],
                  "properties": {
                    "provider": {
                      "type": "string"
                    },
                    "expiresIn": {
                      "type": "integer",
                      "description": "After this amount of seconds, the upload link won't be available anymore"
                    },
                    "file": {
                      "type": "object",
                      "required": [
                        "name",
                        "extension",
                        "size",
                        "md5",
                        "url"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "extension": {
                          "type": "string"
                        },
                        "size": {
                          "type": "integer",
                          "description": "Size of the file (bytes)"
                        },
                        "md5": {
                          "type": "string",
                          "description": "The md5 sum-check of the file"
                        },
                        "url": {
                          "type": "string",
                          "description": "the url to which upload the file"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTID=...\nexport PROJECTID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTID/projects/$PROJECTID/cover\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n      \"name\":\"cover.gif\",\n      \"extension\":\"gif\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\"\n    }'\n\n# -- UPLOAD OF THE FILE --\n\n# the url received in the body of the response\nexport URL=...\nexport FILENAME=...\n\nMD5SUM=\"$(openssl md5 -binary < \"$FILENAME\" | base64)\"\ncurl --request PUT --url \"$URL\" --header \"Content-Type: application/json\" -T \"$FILENAME\" -H \"Content-MD5: ${MD5SUM}\" -H \"Cache-Control: max-age=2592000\" -H \"x-ms-blob-type: BlockBlob\" -i\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountID = \"...\"\nprojectID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/cover\"\n    % (host, accountID, projectID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n      \"name\":\"tumbleweed.gif\",\n      \"extension\":\"gif\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\"\n    }\n)\nprint(response.status_code)\nprint(response.json())\n\nimport base64\nimport hashlib\n\n# the url received in the body of the response\nexport url=...\nexport filename=...\n\nhash_md5 = hashlib.md5()\nwith open(filename, \"rb\") as fin:\n    for chunk in iter(lambda: fin.read(4096), b\"\"):\n        hash_md5.update(chunk)\ndigest = hash_md5.digest()\nmd5 = base64.b64encode(digest).decode(\"utf-8\")\n\nheaders = {\n  \"Content-MD5\": md5,\n  \"Cache-Control\": \"max-age=2592000\",\n  \"x-ms-blob-type\": \"BlockBlob\", # mandatory if storage type is azure\n}\ndata = open(filename, \"rb\")\nr = requests.put(url, data=data, headers=headers)\nprint(r.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountId = \"...\";\nconst projectId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountId}/projects/${projectId}/cover`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n          \"name\":\"cover.gif\",\n          \"extension\":\"gif\",\n          \"size\":448459,\n          \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\",\n        }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "put": {
        "summary": "Update cloud file as cover for project",
        "operationId": "updateProjectCover",
        "description": "<span class='tag beta'>BETA</span>Update the cover for the project\n\nRequires the permission `projects:project:update-details`\n\nThis actually adds an already uploaded file as cover for a project\n",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "extension",
                  "size",
                  "md5"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "extension": {
                    "type": "string",
                    "enum": [
                      "png",
                      "jpg",
                      "jpeg"
                    ]
                  },
                  "size": {
                    "type": "integer",
                    "description": "Size of the file (bytes)",
                    "minimum": 1,
                    "maximum": 10485760
                  },
                  "md5": {
                    "type": "string",
                    "description": "The md5 sum-check of the file"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the cover has been updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "name",
                    "extension",
                    "size",
                    "md5",
                    "id"
                  ],
                  "properties": {
                    "name": {
                      "type": "string"
                    },
                    "extension": {
                      "type": "string"
                    },
                    "size": {
                      "type": "integer",
                      "description": "Size of the file (bytes)"
                    },
                    "md5": {
                      "type": "string",
                      "description": "The md5 sum-check of the file"
                    },
                    "id": {
                      "$ref": "#/components/schemas/FileUrn",
                      "description": "the unique id of the file in the Cintoo Platform"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTID=...\nexport PROJECTID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTID/projects/$PROJECTID/cover\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n      \"name\":\"tumbleweed.gif\",\n      \"extension\":\"gif\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\"\n    }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountID = \"...\"\nprojectID = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/cover\"\n    % (host, accountID, projectID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n      \"name\":\"tumbleweed.png\",\n      \"extension\":\"png\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\"\n    }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountId = \"...\";\nconst projectId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountId}/projects/${projectId}/cover`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n          \"name\":\"tumbleweed.png\",\n          \"extension\":\"png\",\n          \"size\":448459,\n          \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\"\n        }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/restore": {
      "put": {
        "summary": "Restore project",
        "operationId": "restoreProject",
        "description": "<span class='tag beta'>BETA</span>Restore a deleted project.\n\nRequires the permission `project:project:delete` on the project.\n(Note that permission `account:projects:delete` on the account implies the permission\n`project:project:delete` on all projects of the account).\n\nError management:\nIf the subscription used by this project does not have enough capacity to restore it,\na 400 error is returned with a message,\nlike \"Target subscription <subscriptionId> does not have enough Scan capacity to accept project\"\n",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/countScans"
          },
          {
            "$ref": "#/components/parameters/countTags"
          },
          {
            "$ref": "#/components/parameters/countWorkzones"
          }
        ],
        "responses": {
          "200": {
            "description": "The project was restored successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "400": {
            "description": "The project is not deleted, or the subscription is not active, or subscription capacity exceeded",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorBadRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `project-active` if the project is not deleted\n* `subscription-not-active` if the subscription is not active\n* `capacity-exceeded-scan`, `capacity-exceeded-geoimage`, `capacity-exceeded-tag` if the target\nsubscription cannot accept the project due to a capacity exceeded, respectively of Scan,\nGeoImage, or Tag\n"
                        },
                        "errorValues": {
                          "type": "object",
                          "properties": {
                            "projectId": {
                              "type": "string",
                              "description": "Project ID for error code `project-active`"
                            },
                            "subscriptionId": {
                              "type": "string",
                              "description": "Subscription ID for error code `subscription-not-active` or `capacity-exceeded-xxx`"
                            }
                          }
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "project-active": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Project is active",
                      "errorCode": "project-active",
                      "errorValues": {
                        "projectId": "1234"
                      }
                    }
                  },
                  "subscription-not-active": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Subscription is not active",
                      "errorCode": "subscription-not-active",
                      "errorValues": {
                        "subscriptionId": "1234"
                      }
                    }
                  },
                  "capacity-exceeded-scan": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "not enough Scan capacity to accept project on subscription 1234",
                      "errorCode": "capacity-exceeded-scan",
                      "errorValues": {
                        "subscriptionId": "1234"
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/restore\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/restore\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/restore`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/workzones": {
      "get": {
        "summary": "List Workzones",
        "operationId": "getWorkzones",
        "description": "<span class='tag beta'>BETA</span>List work zones of a project",
        "tags": [
          "Workzone"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List of work zones",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Workzone"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/workzones\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/workzones\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/workzones`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Create a work zone",
        "operationId": "createWorkzone",
        "description": "<span class='tag beta'>BETA</span>Create a work zone in a project, under an existing one (possibly the root work zone of the project).\n\nThe new work zone automatically inherits the contributors (users and groups) from the parent work zone.\n\n**Requires** the permission `workzone` on the parent work zone.\n",
        "tags": [
          "Workzone"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/workzoneCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The work zone was successfully created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Workzone"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        }
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/members": {
      "get": {
        "summary": "Get Users member of a project",
        "operationId": "getProjectMembers",
        "description": "<span class='tag beta'>BETA</span>GetUsers member of a project.\n\nRequires the permission `project:members:list`.\n",
        "tags": [
          "Members"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List Users part of the Project",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/User"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/members\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/members\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/members`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Add members to project",
        "operationId": "addProjectMembers",
        "description": "<span class='tag beta'>BETA</span>Add members to a project.\n\n#### Role assignment\n * Each member is assigned to a role.\n * A member must not be already assigned to a different role on any work zone of the project.\n * If a member already has the same role, the role is extended to the provided work zones.\n * Each member must be unique in the request.\n * If a user does not exist yet, it will be automatically invited on the account\n   (equivalent to the [Invite users](#tag/User/operation/inviteUsers) end-point without account role).\n\n#### Work zones\n * Specific work zones can be provided to assign the roles only to those work zones **and their sub-workzones**.\n * If the field `workzones` is not provided or null, it is equivalent to provide the topmost work zone of the project,\n   in other words the roles are assigned to all work zones of the project.\n\n#### Permissions\n * Requires a role with \"Manage User\" permission on the topmost work zone of the project.\n * Requires to have at least all permissions of the provided roles, on the provided work zones.\n",
        "tags": [
          "Members"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "members"
                ],
                "properties": {
                  "workzones": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "$ref": "#/components/schemas/WorkzoneRef"
                    }
                  },
                  "members": {
                    "type": "object",
                    "additionalProperties": false,
                    "properties": {
                      "users": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "required": [
                            "user",
                            "role"
                          ],
                          "properties": {
                            "user": {
                              "type": "string",
                              "description": "User's Email"
                            },
                            "role": {
                              "$ref": "#/components/schemas/RoleRef"
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "The users were successfully added to the project"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/members\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"workzones\": [ \"urn:cintoo:workzone:...\", \"urn:cintoo:workzone:...\" ],\n    \"members\": {\n      \"users\": [\n        { \"user\": \"newuser@mycompany.com\", \"role\": \"urn:cintoo:role:...\" }\n      ]\n    }\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nworkzonesIds = [ \"...\", \"...\" ]\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/members\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token},\n  json = {\n    \"workzones\": workzonesIds,\n    \"members\": {\n      \"users\": [ { \"user\": \"newuser@mycompany.com\", \"role\": \"...\" } ]\n    }\n  }\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/members`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"workzones\": [ \"urn:cintoo:workzone:...\", \"urn:cintoo:workzone:...\" ],\n        \"members\": {\n          \"users\": [\n            { \"user\": \"newuser@mycompany.com\", \"role\": \"urn:cintoo:role:...\" }\n          ]\n        }\n      }\n  ),\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/members/bulk-remove": {
      "post": {
        "summary": "Bulk remove users and groups from project",
        "operationId": "removeMembersFromProject",
        "description": "<span class='tag beta'>BETA</span>Remove users and groups from the project.\n\nThis endpoint will ignore users or groups that are not really contributors of the project.\n\nPermissions:\nRequires a role with \"Manage User\" permission on the top most work zone of the project.\n",
        "tags": [
          "Members"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "properties": {
                  "users": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/UserRef"
                    }
                  },
                  "groups": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/GroupRef"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "The users and groups were successfully removed from the project"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "integer",
                      "enum": [
                        403
                      ]
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "Cannot remove users or groups. Need to have \"manage_user\" permission on the project"
                      ]
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/members/bulk-remove\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"users\": [ \"urn:cintoo:user:...\", \"urn:cintoo:user:...\" ],\n    \"groups\": [ \"urn:cintoo:group:...\", \"urn:cintoo:group:...\" ]\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nuserIds = [ \"...\", \"...\" ]\ngroupUUIDs = [ \"...\", \"...\" ]\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/members/bulk-remove\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token},\n  json = {\n    \"users\": userIds,\n    \"groups\": groupUUIDs\n  }\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/members/bulk-remove`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"users\": [ \"urn:cintoo:user:...\", \"urn:cintoo:user:...\" ],\n        \"groups\": [ \"urn:cintoo:group:...\", \"urn:cintoo:group:...\" ]\n      }\n  ),\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/members/users/{userRef}": {
      "delete": {
        "summary": "Remove user from project",
        "operationId": "removeUserFromProject",
        "description": "<span class='tag beta'>BETA</span>Remove a user from the project.\n\nRequires the permission `workzone:members:write` on the top most work zone of the project.\n\n**Note** can be invoked on self. Any user can remove himself from a project.\n",
        "tags": [
          "Members"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/userRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The user was successfully removed from the project"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorForbidden"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `remove-contributor-forbidden`\n"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "remove-contributor-forbidden": {
                    "value": {
                      "status": 403,
                      "title": "Forbidden",
                      "detail": "You do not have the permission to remove contributor. It requires to be targeting self, or to have permission \"manage_users\"",
                      "errorCode": "remove-contributor-forbidden"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport USERID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/members/users/$USERID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nuserId = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/members/users/%s\"\n    % (host, accountUUID, projectUUID, userId),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst userId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/members/users/${userId}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/members/groups/{groupRef}": {
      "delete": {
        "summary": "Remove group from project",
        "operationId": "removeGroupFromProject",
        "description": "<span class='tag beta'>BETA</span>Remove a group from the project.\n\nPermissions:\n\nRequires the permission `workzone:members:write` on the top most work zone of the project.\n",
        "tags": [
          "Members"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/groupRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The group was successfully removed from the project"
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "integer",
                      "enum": [
                        403
                      ]
                    },
                    "type": {
                      "type": "string",
                      "enum": [
                        "Cannot remove group(s). Need to have \"manage_user\" permission on the project"
                      ]
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport GROUPUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/members/groups/$GROUPUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ngroupUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/members/groups/%s\"\n    % (host, accountUUID, projectUUID, groupUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst groupUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/members/groups/${groupUUID}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/workzones/{workzoneRef}/members/users/{userRef}": {
      "delete": {
        "summary": "Remove user from work zone",
        "operationId": "removeUserFromWorkzone",
        "description": "<span class='tag beta'>BETA</span>Remove a user from a work zone and all child work zones.\n\nIf the work zone is not the project's root work zone, and the user to remove is also a contributor on a parent\nwork zone, the user must be removed from the parents for which he is a contributor.\nIf this is the case, and the query parameter 'allowRemoveOnParents' is not specified or set to false, a bad request\nerror will be returned (code 400).\n\n**Requires** the permission `workzone:members:write` on the work zone\nas well as any parent work zone to which the user is a contributor if the parameter 'allowRemoveOnParents' is true.\n\n**Note** can be invoked on self. Any user can remove himself from a work zone.\n",
        "tags": [
          "Workzone"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/workzoneRef"
          },
          {
            "$ref": "#/components/parameters/userRef"
          },
          {
            "$ref": "#/components/parameters/allowRemoveOnParents"
          }
        ],
        "responses": {
          "204": {
            "description": "The user was successfully removed from the work zone"
          },
          "400": {
            "description": "The user is a contributor of a parent work zone and the parameter 'allowRemoveOnParents' is not set to 'true'",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorBadRequest"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `invalid-input` if the user is a contributor of a parent work zone\nand the parameter 'allowRemoveOnParents' is not set to 'true'\n"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "invalid-input": {
                    "value": {
                      "status": 400,
                      "title": "Bad Request",
                      "detail": "Invalid parameter allowRemoveOnParents: The user is contributor on a parent work zone and parameter 'allowRemoveOnParents' is false",
                      "errorCode": "invalid-input"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Forbidden",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "$ref": "#/components/schemas/ErrorForbidden"
                    },
                    {
                      "type": "object",
                      "properties": {
                        "errorCode": {
                          "type": "string",
                          "description": "* `remove-contributor-from-work-zone-forbidden`\n"
                        }
                      }
                    }
                  ]
                },
                "examples": {
                  "remove-contributor-from-work-zone-forbidden": {
                    "value": {
                      "status": 403,
                      "title": "Forbidden",
                      "detail": "You do not have the permission to remove contributor from work zone. It requires to be targeting self, or to be Project Owner, or to have permission \"manage_users\"",
                      "errorCode": "remove-contributor-from-work-zone-forbidden"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport WORKZONEID=...\nexport USERID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/workzones/$WORKZONEID/members/users/$USERID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nworkzoneId = \"...\"\nuserId = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/workzones/%s/members/users/%s\"\n    % (host, accountUUID, projectUUID, workzoneId, userId),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst workzoneId = \"...\";\nconst userId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/workzones/${workzoneId}/members/users/${userId}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/files": {
      "get": {
        "summary": "Get files",
        "operationId": "getFiles",
        "description": "<span class='tag beta'>BETA</span>get all files in project.\n\nThis endpoint accepts a \"category\" parameter to restrain the categories of the files that will be listed.\n\nPermissions:\n- the user must have permission `workzone:workzones:read` in work zones in which you can list files.\n",
        "tags": [
          "File"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/categoryFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "List of files for this project",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/File"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/files\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/files\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/files`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/files/{fileRef}": {
      "patch": {
        "summary": "Update a file name",
        "operationId": "updateFileName",
        "description": "Update the name of a file.\n\nRequires write permission on the file workzone:\n  * `workzone:reality-data:write` for scans/geo-images/site maps\n  * `workzone:cad-model:write` for models\n  * `workzone:model-reports:write` for model reports\n  * `workzone:documents:write` for documents/media/misc/archive\n  * `workzone:video3d:write` for video 360\n  * `workzone:workzones:write` for other file types\n",
        "tags": [
          "File"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/fileRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/fileUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated file",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/File"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport FILEUUID=...\n\ncurl --request PATCH --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/files/$FILEUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"filename\": \"updated-name.jpg\"\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nfileUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.patch(\n  \"https://%s/api/2/accounts/%s/projects/%s/files/%s\"\n    % (host, accountUUID, projectUUID, fileUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"filename\": \"updated-name.jpg\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst fileUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/files/${fileUUID}`;\nconst res = await fetch(url, {\n  method: \"PATCH\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    filename: \"updated-name.jpg\",\n  }),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/files/bulk-transformation": {
      "post": {
        "summary": "Update the position and/or rotation of a scan, model, geoImage or video3d",
        "operationId": "UpdateBulkFilesTransformation",
        "description": "<span class='tag beta'>BETA</span>Update the position, rotation and scale for a list of files, with the following restrictions:\n- the scan, model and geoImage files accept update of only the position and rotation.\n- the video3d files accept update of all three fields.\n\nRequired permissions depend on the type of the files being transformed:\n- scan files: `workzone:reality-data:transform`\n- model files: `workzone:cad-model:transform`\n- geoImage files: `workzone:geoimages:transform`\n- video3d files: `workzone:video3d:transform`\n",
        "tags": [
          "File"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/filesTransformationUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The files are successfully updated.\n\nThe response returns the updated files information.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/File"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/files/bulk-transformation\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '[\n    {\n      \"id\": \"...\",\n      \"position\": {\"x\": 1., \"y\": 2., \"z\": 3.},\n      \"rotation\": {\"x\": 4., \"y\": 5., \"z\": 6., \"w\": 7.}\n    }\n  ]'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/files/bulk-transformation\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token},\n  json = [\n    {\n      \"id\": \"...\",\n      \"position\": {\"x\": 1., \"y\": 2., \"z\": 3.},\n      \"rotation\": {\"x\": 4., \"y\": 5., \"z\": 6., \"w\": 7.}\n    }\n  ]\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\nconst payload = [\n  {\n    id: \"...\",\n    position: { x: 1, y: 2, z: 3 },\n    rotation: { x: 4, y: 5, z: 6, w: 7 },\n  },\n];\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/files/bulk-transformation`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(payload),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/share-links": {
      "get": {
        "summary": "List share links",
        "operationId": "getShareLinks",
        "description": "<span class='tag beta'>BETA</span>List share links.\n\nPermissions:\nA link will only be listed if the user needs has either:\n- the `workzone:share-links:read` permission\n- the `workzone:own-share-links:read` permission if he is the creator of the link\n\nProject owner automatically gets the `workzone:share-links:read` permission on all the project's work zones.\nRoles with the \"Share\" permission grants the `workzone:own-share-links:read` permission.\n",
        "tags": [
          "Share Link"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List of the project's share links",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ShareLink"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/share-links\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/share-links\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/share-links`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Create a share link",
        "operationId": "createShareLink",
        "description": "<span class='tag beta'>BETA</span>Create a share link.\n\n<span class='block' style='background-color: PapayaWhip;'><span class='icon' style='color: red; font-size:20px;'>&#9888;</span> A share link with no password will be freely usable by anyone with its id</span>\n\nPermissions:\n- the user need to have the `workzone:share-links:write` or `workzone:own-share-links:write` permission\n\nProject owner automatically gets the `workzone:share-links:write` permission on all the project's work zones.\nRoles with the \"Share\" permission grants the `workzone:own-share-links:write` permission.\n",
        "tags": [
          "Share Link"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/shareLinkCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The share link was created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareLink"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/share-links\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"name\": \"my new link\",\n    \"workzoneId\": \"urn:cintoo:workzone:...\",\n    \"membershipRequired\": false,\n    \"password\": \"this is my very long passphrase\",\n    \"expiresAt\": \"2027-02-24T12:24:42Z\",\n    \"shareOptions\": {\n      \"workzones\": true,\n      \"notes\": true,\n      \"issues\": true,\n      \"measurements\": true,\n      \"crops\": false,\n      \"tags\": false\n    },\n    \"logoBlob\": \"dXJuOmNpbnRvbzpmaWxlOjg3NmE3MGJhLTNjNjItNGRkMS05YjUyLTc5YzdmOTJlMDVmYw\\/967dfd9cba4f5b8d9d029e6dc2243a9e.png\",\n    \"savedView\": {}\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nworkzoneUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/share-links\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"name\": \"my new link\",\n    \"workzoneId\": workzoneUUID,\n    \"membershipRequired\": false,\n    \"password\": \"this is my very long passphrase\",\n    \"expiresAt\": \"2027-02-24T12:24:42Z\",\n    \"shareOptions\": {\n      \"workzones\": true,\n      \"notes\": true,\n      \"issues\": true,\n      \"measurements\": true,\n      \"crops\": false,\n      \"tags\": false\n    },\n    \"logoBlob\": \"dXJuOmNpbnRvbzpmaWxlOjg3NmE3MGJhLTNjNjItNGRkMS05YjUyLTc5YzdmOTJlMDVmYw\\/967dfd9cba4f5b8d9d029e6dc2243a9e.png\",\n    \"savedView\": {}\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/share-links`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"name\": \"my new link\",\n        \"workzoneId\": \"urn:cintoo:workzone:...\",\n        \"membershipRequired\": false,\n        \"password\": \"this is my very long passphrase\",\n        \"expiresAt\": \"2027-02-24T12:24:42Z\",\n        \"shareOptions\": {\n          \"workzones\": true,\n          \"notes\": true,\n          \"issues\": true,\n          \"measurements\": true,\n          \"crops\": false,\n          \"tags\": false\n        },\n        \"logoBlob\": \"dXJuOmNpbnRvbzpmaWxlOjg3NmE3MGJhLTNjNjItNGRkMS05YjUyLTc5YzdmOTJlMDVmYw\\/967dfd9cba4f5b8d9d029e6dc2243a9e.png\",\n        \"savedView\": {}\n      }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/share-links/{shareLinkRef}": {
      "get": {
        "summary": "Get a share link",
        "operationId": "getShareLink",
        "description": "<span class='tag beta'>BETA</span>Get details on a share link.\n\nPermissions:\nThe user need to either:\n- have the `workzone:share-links:read` permission\n- have the `workzone:own-share-links:read` permission and be the creator of the link\n\nProject owner automatically gets the `workzone:share-links:read` permission on all the project's work zones.\nRoles with the \"Share\" permission grants the `workzone:own-share-links:read` permission.\n",
        "tags": [
          "Share Link"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/shareLinkRef"
          }
        ],
        "responses": {
          "200": {
            "description": "Get a share link",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareLink"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport SHARELINKID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/share-links/$SHARELINKID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nshareLinkID= \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/share-links/%s\"\n    % (host, accountUUID, projectUUID, shareLinkID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst shareLinkId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/share-links/${shareLinkId}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete a share link",
        "operationId": "deleteShareLink",
        "description": "<span class='tag beta'>BETA</span>Delete a share link.\n\nPermissions:\nThe user need to either:\n- have the `workzone:share-links:write` permission\n- have the `workzone:own-share-links:write` permission and be the creator of the link\n\nProject owner automatically gets the `workzone:share-links:write` permission on all the project's work zones.\nRoles with the \"Share\" permission grants the `workzone:own-share-links:write` permission.\n",
        "tags": [
          "Share Link"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/shareLinkRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The share link was deleted successfully"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport SHARELINKID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/share-links/$SHARELINKID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nshareLinkID= \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/share-links/%s\"\n    % (host, accountUUID, projectUUID, shareLinkID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst shareLinkId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/share-links/${shareLinkId}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      },
      "put": {
        "summary": "Update a share link",
        "operationId": "updateShareLink",
        "description": "<span class='tag beta'>BETA</span>Update a share link.\n\n<span class='block' style='background-color: PapayaWhip;'><span class='icon' style='color: red; font-size:20px;'>&#9888;</span> Overwrites all fields. Missing fields will be considered as null and current values will be erased</span>\n\nNote: the `password` field has a special semantic here, to allow updating a share link without supplying the password every time.\nIt can be either:\n- null or absent field: the password will remain the same.\n- \"\" (an empty string): the password will be removed.\n- \"...\" (a non-empty string): the password will be replaced.\n\n<span class='block' style='background-color: PapayaWhip;'><span class='icon' style='color: red; font-size:20px;'>&#9888;</span> A share link with no password will be freely usable by anyone with its id</span>\n\nPermissions:\n\nThe user need to either:\n- have the `workzone:share-links:write` permission\n- have the `workzone:own-share-links:write` permission and be the creator of the link\n\nProject owner automatically gets the `workzone:share-links:write` permission on all the project's workzones.\nRoles with the \"Share\" permission grants the `workzone:own-share-links:write` permission.\n",
        "tags": [
          "Share Link"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/shareLinkRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/shareLinkUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The share link was updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ShareLink"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport SHARELINKID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/share-links/$SHARELINKID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"name\": \"my new link\",\n    \"membershipRequired\": false,\n    \"password\": \"this is my new very long passphrase\",\n    \"expiresAt\": \"2027-02-24T12:24:42Z\",\n    \"shareOptions\": {\n      \"workzones\": true,\n      \"notes\": true,\n      \"issues\": true,\n      \"measurements\": true,\n      \"crops\": false,\n      \"tags\": false\n    },\n    \"logoBlob\": \"dXJuOmNpbnRvbzpmaWxlOjg3NmE3MGJhLTNjNjItNGRkMS05YjUyLTc5YzdmOTJlMDVmYw\\/967dfd9cba4f5b8d9d029e6dc2243a9e.png\",\n    \"savedView\": {}\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nworkzoneUUID = \"...\"\nshareLinkID= \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/share-links/%s\"\n    % (host, accountUUID, projectUUID, shareLinkID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"name\": \"my new link\",\n    \"membershipRequired\": false,\n    \"password\": \"this is my new very long passphrase\",\n    \"expiresAt\": \"2027-02-24T12:24:42Z\",\n    \"shareOptions\": {\n      \"workzones\": true,\n      \"notes\": true,\n      \"issues\": true,\n      \"measurements\": true,\n      \"crops\": false,\n      \"tags\": false\n    },\n    \"logoBlob\": \"dXJuOmNpbnRvbzpmaWxlOjg3NmE3MGJhLTNjNjItNGRkMS05YjUyLTc5YzdmOTJlMDVmYw\\/967dfd9cba4f5b8d9d029e6dc2243a9e.png\",\n    \"savedView\": {}\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst shareLinkId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/share-links/${shareLinkId}`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"name\": \"my new link\",\n        \"membershipRequired\": false,\n        \"password\": \"this is my new very long passphrase\",\n        \"expiresAt\": \"2027-02-24T12:24:42Z\",\n        \"shareOptions\": {\n          \"workzones\": true,\n          \"notes\": true,\n          \"issues\": true,\n          \"measurements\": true,\n          \"crops\": false,\n          \"tags\": false\n        },\n        \"logoBlob\": \"dXJuOmNpbnRvbzpmaWxlOjg3NmE3MGJhLTNjNjItNGRkMS05YjUyLTc5YzdmOTJlMDVmYw\\/967dfd9cba4f5b8d9d029e6dc2243a9e.png\",\n        \"savedView\": {}\n      }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/blobs/{blobRef}": {
      "get": {
        "summary": "Download a blob",
        "operationId": "getBlob",
        "description": "Download a blob, via a redirection to pre-signed URL",
        "tags": [
          "File"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "name": "blobRef",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "a blob ref -> `blob` attribute in File schema",
              "example": "1f74af182236bd4e5df2c3f18f3d94fe.png"
            }
          }
        ],
        "responses": {
          "302": {
            "description": "Redirection to a pre-signed download link, in the Location header"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport BLOBID=...\n\ncurl --location \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/blobs/$BLOBID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nblobId = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/blobs/%s\"\n    % (host, accountUUID, projectUUID, blobId),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nwith open(blobId, mode='wb') as localfile:\n  localfile.write(response.content)\n"
          },
          {
            "lang": "TypeScript",
            "source": "import { writeFile } from \"node:fs/promises\";\n\n\n  const host = \"aec.cintoo.com\";\n  const accountUUID = \"...\";\n  const projectUUID = \"...\";\n  const blobId = \"...\";\n  const token = \"...\";\n\n  const url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/blobs/${blobId}`;\n  const res = await fetch(url, {\n    redirect: \"follow\",\n    headers: {\n      \"Authorization\": `Bearer ${token}`,\n    },\n  });\n\n  console.log(res.status);\n  const fileBuffer = Buffer.from(await res.arrayBuffer());\n  await writeFile(blobId, fileBuffer);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/blobs": {
      "post": {
        "summary": "Get pre-signed urls for multiple blobs",
        "operationId": "getBlobs",
        "description": "Get pre-signed urls for multiple blobs.",
        "tags": [
          "File"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "string",
                  "description": "list of blob refs -> `blob` attribute in File schema",
                  "example": "1f74af182236bd4e5df2c3f18f3d94fe.png"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Pre-signed urls to the requested blobs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "expiresIn",
                    "urls"
                  ],
                  "properties": {
                    "expiresIn": {
                      "description": "validity duration of urls, in seconds",
                      "type": "integer"
                    },
                    "urls": {
                      "description": "map associating each blob ref to its pre-signed download link",
                      "type": "object"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport BLOBID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/blobs\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"[ \\\"$BLOBID\\\" ]\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nblobId = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/blobs\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [ blobId ]\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\nconst blobId = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/blobs`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [ blobId ]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/workzones/{workzoneRef}/bulk-files": {
      "post": {
        "summary": "Get a signed URL for cloud file upload",
        "operationId": "signUploadURL",
        "description": "<span class='tag beta'>BETA</span>Get a signed URL for cloud file upload\n\nRequires the permission `workzone:documents:write` and/or `workzone:reality-data:write` on the workzone, depending on the file types\n\nAfter this call, use the `url`s from the response to upload the files.\nNote that there are examples on how to upload the data after calling the endpoints in the example section.\n\nRequired headers to push the files\n* `Content-MD5: xxx` with `xxx` being a base 64 encode of the md5sum in binary format.\\\n  Example: `MD5SUM=\"$(openssl md5 -binary < \"$FILENAME\" | base64)\"`\n* `Cache-Control: max-age=2592000`\n* `x-ms-blob-type: BlockBlob` mandatory if the storage type is Azure. \\\n  Note: always adding the `x-ms-blob-type` could be a good idea as Aws ignores it anyway.\n",
        "tags": [
          "File"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/workzoneRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/bulk-files"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The signing process succeeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "provider": {
                      "type": "string"
                    },
                    "expiresIn": {
                      "type": "integer"
                    },
                    "files": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "extension": {
                            "type": "string"
                          },
                          "size": {
                            "type": "integer"
                          },
                          "md5": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          },
                          "blobName": {
                            "$ref": "#/components/schemas/BlobName"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTID=...\nexport PROJECTID=...\nexport WORKZONEID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTID/projects/$PROJECTID/workzones/$WORKZONEID/bulk-files\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '[\n    {\n      \"name\":\"tumbleweed.gif\",\n      \"extension\":\"gif\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\",\n      \"isAttachment\": false\n    }\n  ]'\n\n# -- UPLOAD OF THE FILE --\n\n# the url received in the body of the response\nexport URL=...\nexport FILENAME=...\n\nMD5SUM=\"$(openssl md5 -binary < \"$FILENAME\" | base64)\"\ncurl --request PUT --url \"$URL\" --header \"Content-Type: application/json\" -T \"$FILENAME\" -H \"Content-MD5: ${MD5SUM}\" -H \"Cache-Control: max-age=2592000\" -H \"x-ms-blob-type: BlockBlob\" -i\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountID = \"...\"\nprojectID = \"...\"\nworkzoneID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/workzones/%s/bulk-files\"\n    % (host, accountID, projectID, workzoneID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [\n    {\n      \"name\":\"tumbleweed.gif\",\n      \"extension\":\"gif\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\",\n      \"isAttachment\": false\n    }\n  ]\n)\nprint(response.status_code)\nprint(response.json())\n\nimport base64\nimport hashlib\n\n# the url received in the body of the response\nexport url=...\nexport filename=...\n\nhash_md5 = hashlib.md5()\nwith open(filename, \"rb\") as fin:\n    for chunk in iter(lambda: fin.read(4096), b\"\"):\n        hash_md5.update(chunk)\ndigest = hash_md5.digest()\nmd5 = base64.b64encode(digest).decode(\"utf-8\")\n\nheaders = {\n  \"Content-MD5\": md5,\n  \"Cache-Control\": \"max-age=2592000\",\n  \"x-ms-blob-type\": \"BlockBlob\", # mandatory if storage type is azure\n}\ndata = open(filename, \"rb\")\nr = requests.put(url, data=data, headers=headers)\nprint(r.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountId = \"...\";\nconst projectId = \"...\";\nconst workzoneId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountId}/projects/${projectId}/workzones/${workzoneId}/bulk-files`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [\n        {\n          \"name\":\"tumbleweed.gif\",\n          \"extension\":\"gif\",\n          \"size\":448459,\n          \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\",\n          \"isAttachment\": false\n        }\n      ]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "put": {
        "summary": "Register cloud files on a workzone",
        "operationId": "registerFiles",
        "description": "<span class='tag beta'>BETA</span>Register cloud files on a workzone\n\nRequires the permission `workzone:documents:write` and/or `workzone:reality-data:write` in the work zone, depending on the file types\n\nThis actually adds an already uploaded file in a work zone, so that it appears in the file browser\n",
        "tags": [
          "File"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/workzoneRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/bulk-files"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "the files have been correctly registered",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string"
                      },
                      "extension": {
                        "type": "string"
                      },
                      "size": {
                        "type": "integer"
                      },
                      "md5": {
                        "type": "string"
                      },
                      "id": {
                        "$ref": "#/components/schemas/FileUrn"
                      },
                      "blobName": {
                        "$ref": "#/components/schemas/BlobName"
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTID=...\nexport PROJECTID=...\nexport WORKZONEID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTID/projects/$PROJECTID/workzones/$WORKZONEID/bulk-files\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '[\n    {\n      \"name\":\"tumbleweed.gif\",\n      \"extension\":\"gif\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\",\n      \"isAttachment\": false\n    }\n  ]'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountID = \"...\"\nprojectID = \"...\"\nworkzoneID = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/workzones/%s/bulk-files\"\n    % (host, accountID, projectID, workzoneID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [\n    {\n      \"name\":\"tumbleweed.gif\",\n      \"extension\":\"gif\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\",\n      \"isAttachment\": false\n    }\n  ]\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountId = \"...\";\nconst projectId = \"...\";\nconst workzoneId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountId}/projects/${projectId}/workzones/${workzoneId}/bulk-files`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [\n        {\n          \"name\":\"tumbleweed.gif\",\n          \"extension\":\"gif\",\n          \"size\":448459,\n          \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\",\n          \"isAttachment\": false\n        }\n      ]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/workzones/{workzoneRef}/copy": {
      "post": {
        "summary": "Copy a work zone",
        "operationId": "copyWorkzone",
        "description": "<span class='tag beta'>BETA</span>Copy a work zone, its sub-work zones, and the files on these work zones.\n\nThe destination of the copy is provided by:\n- `destinationProject`: if not provided or null, a new project is created, and the copied work zone will\n  be the root work zone of the new project.\n- `destinationWorkzone`: if provided and not null, specify the work zone inside the destination project in which\n  the copied work zone will be. Default is the root work zone of the destination project.\n  Cannot be provided if `destinationProject` is not provided.\n- Only in case a new project is created (`destinationProject` not provided), the `destinationSubscription`\n  can be provided to assign the new project to this subscription. Default is to use the same subscription as\n  the source project.\n\nNotes:\n- the resources like tags, annotations, crops, etc... are not copied. Only the structure and the files\n  are copied.\n- if the request is accepted, the server responds immediately with a 202 status code, but at this moment\n  the copy is not yet processed. It will be processed asynchronously, and the user will receive a\n  notification by email once the process is finished (either successfully or with an error).\n- if a copy is already in progress on the source or destination project, it will fail\n\nPermissions:\n- On the source work zone, the user must be contributor and have the permissions `workzone:workzones:read`,\n  `workzone:reality-data:read` and `workzone:cad-model:read`\n  (\"View Reality Data\" and \"Upload and download documents\"),\n   which are automatically included for the project owner.\n- If the destination is a new project, the user must be a project manager.\n- If the destination is an existing project, the user must be a contributor of the destination work zone\n  with permissions `workzone:workzones:write`, `workzone:reality-data:write` and `workzone:cad-model:write`\n  (\"Work Zones\", \"Upload or Delete Reality Data\", \"Upload and download documents\"),\n   which are automatically included for the project owner.\n\n<span class='block' style='background-color: PapayaWhip;'><span class='icon' style='color: red; font-size:20px;'>&#9888;</span> We strongly recommend not to make any modification in the source work zone (and its sub-work zones) while the copy is in progress. If any changes are done in the source, they may not be taken into account and it might compromise the result. Both source and destination projects may be temporarily not accessible during the copy.</span>\n",
        "tags": [
          "Workzone"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/workzoneRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "destinationName"
                ],
                "properties": {
                  "destinationName": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255
                  },
                  "destinationProject": {
                    "description": "The project to copy into. If not provided, a new project is created.",
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/ProjectRef"
                      }
                    ],
                    "type": "string",
                    "nullable": true
                  },
                  "destinationWorkzone": {
                    "description": "The work zone to copy into. Only valid if a destination project is specified.",
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/WorkzoneRef"
                      }
                    ],
                    "type": "string",
                    "nullable": true
                  },
                  "destinationSubscription": {
                    "description": "The subscription to use for the new project. Only valid if a destination project is not specified.",
                    "allOf": [
                      {
                        "$ref": "#/components/schemas/SubscriptionRef"
                      }
                    ],
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "The copy has been accepted and will be processed in a short time"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTID=...\nexport PROJECTID=...\nexport WORKZONEID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTID/projects/$PROJECTID/workzones/$WORKZONEID/copy\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{ \"destinationName\": \"My copy\" }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountID = \"...\"\nprojectID = \"...\"\nworkzoneID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/workzones/%s/copy\"\n    % (host, accountID, projectID, workzoneID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = { \"destinationName\": \"My copy\" }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountId = \"...\";\nconst projectId = \"...\";\nconst workzoneId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountId}/projects/${projectId}/workzones/${workzoneId}/copy`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    { \"destinationName\": \"My copy\" }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/annotations": {
      "get": {
        "summary": "List annotations in a project",
        "operationId": "getAnnotationsFromProject",
        "description": "<span class='tag beta'>BETA</span>List all annotations in a project\n\nOnly annotations on work zones where the user has the permission `workzone:annotations:read` are returned.\n",
        "tags": [
          "Annotation"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/includeComments"
          },
          {
            "$ref": "#/components/parameters/includeAttachments"
          }
        ],
        "responses": {
          "200": {
            "description": "List of annotations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Annotation"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/annotations\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/annotations\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/annotations`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Create an annotation",
        "operationId": "createAnnotation",
        "description": "<span class='tag beta'>BETA</span>Create an annotation\n\nRequires the permission `workzone:annotations:write` on the work zone.\n\nA maximum of 3000 annotations are allowed on the same project. If this limit is reached, an error 400 with\nerror code `project-max-annotations` is returned.\n",
        "tags": [
          "Annotation"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/annotationCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The annotation was created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Annotation"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport WORKZONEID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/annotations\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"workzoneId\\\":\\\"$WORKZONEID\\\",\\\"type\\\":\\\"Note\\\",\\\"title\\\":\\\"test\\\",\\\"description\\\":\\\"test\\\",\\\"position\\\":\\\"1,2,3\\\"}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nworkzoneId = \"\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/annotations\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"workzoneId\": workzoneId,\n    \"type\": \"Note\",\n    \"title\": \"test\",\n    \"description\": \"test\",\n    \"position\": \"1,2,3\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\nconst workzoneId = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/annotations`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"workzoneId\":workzoneId,\"type\":\"Note\",\"title\":\"test\",\"description\":\"test\",\"position\":\"1,2,3\"}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/annotations/{annotationRef}": {
      "get": {
        "summary": "Get annotation",
        "operationId": "getAnnotationById",
        "description": "<span class='tag beta'>BETA</span>Retrieve an annotation, optionally with comments and attachments\n\nRequires the permission `workzone:annotations:read` on the work zone where the annotation is.\n",
        "tags": [
          "Annotation"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/annotationRef"
          },
          {
            "$ref": "#/components/parameters/includeComments"
          },
          {
            "$ref": "#/components/parameters/includeAttachments"
          }
        ],
        "responses": {
          "200": {
            "description": "The content of the annotation",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Annotation"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport ANNOTATIONID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/annotations/$ANNOTATIONID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nannotationId = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/annotations/%s\"\n    % (host, accountUUID, projectUUID, annotationId),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst annotationId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/annotations/${annotationId}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "put": {
        "summary": "Update an annotation",
        "operationId": "updateAnnotation",
        "description": "<span class='tag beta'>BETA</span>Update an annotation\n\n<span class='block' style='background-color: PapayaWhip;'><span class='icon' style='color: red; font-size:20px;'>&#9888;</span> Overwrites all fields. Missing fields will be considered as null and current values will be erased</span>\n\nRequires the permission `workzone:annotations:write` on the work zone.\n",
        "tags": [
          "Annotation"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/annotationRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/annotationUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The annotation was updated successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Annotation"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport ANNOTATIONUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/annotations/$ANNOTATIONUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"type\\\":\\\"Note\\\",\\\"title\\\":\\\"test\\\",\\\"description\\\":\\\"test\\\",\\\"position\\\":\\\"1,2,3\\\"}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nannotationUUID = \"\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/annotations/%s\"\n    % (host, accountUUID, projectUUID, annotationUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"type\": \"Note\",\n    \"title\": \"test\",\n    \"description\": \"test\",\n    \"position\": \"1,2,3\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst annotationUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/annotations/${annotationUUID}`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"type\":\"Note\",\"title\":\"test\",\"description\":\"test\",\"position\":\"1,2,3\"}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete an annotation",
        "operationId": "deleteAnnotation",
        "description": "<span class='tag beta'>BETA</span>Delete an annotation\n\nRequires the permission `workzone:annotations:write` on the work zone.\n",
        "tags": [
          "Annotation"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/annotationRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The annotation was deleted successfully"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport ANNOTATIONUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/annotations/$ANNOTATIONUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nannotationUUID = \"\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/annotations/%s\"\n    % (host, accountUUID, projectUUID, annotationUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst annotationUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/annotations/${annotationUUID}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/annotations/{annotationRef}/comments": {
      "post": {
        "summary": "Create a comment on an annotation",
        "operationId": "createAnnotationComment",
        "description": "<span class='tag beta'>BETA</span>Create a comment on an annotation\n\nRequires the permission `workzone:annotations:write` on the work zone.\n",
        "tags": [
          "Annotation"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/annotationRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/annotationCommentCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The comment was created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnnotationComment"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport ANNOTATIONUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/annotations/$ANNOTATIONUUID/comments\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"description\\\":\\\"my comment\\\"}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nannotationUUID = \"\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/annotations/%s/comments\"\n    % (host, accountUUID, projectUUID, annotationUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"description\": \"my comment\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst annotationUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/annotations/${annotationUUID}/comments`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"description\":\"my comment\"}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/annotations/bulk-create-integration": {
      "post": {
        "summary": "Create integration links on annotations",
        "operationId": "createAnnotationIntegrationLinks",
        "description": "<span class='tag beta'>BETA</span>Create integration links on annotations\n\nRequires the permission `project:annotations:create-integration-link` on the project, which is automatically\ngranted for users having the permission `workzone:annotations:write` on the root work zone.\n\nPre-requisites: to be created, an integration link needs the project to have a valid configuration:\n* An active subscription with BCM enabled\n* For Autodesk:\n  * the project must be configured and linked to an Autodesk hub and project\n  * a valid Autodesk token must exist for the user who created the annotation (logged in)\n* For Procore:\n  * the project must be configured and linked to a Procore company and project\n  * a valid Procore token must exist for the user who created the annotation (logged in)\n* For Newforma Konekt:\n  * A valid Newforma Konekt token must exist on the account\n  * The project must be configured and linked to a Konekt hub and project\n",
        "tags": [
          "Integrations"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/annotationCreateIntegrationLinks"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Returns the list of annotations' URN for which links have been initialized, and for each annotation the types of\nintegration that have been initialized.\n\nIf an annotation is not returned, or a requested integration type is not returned for an annotation,\nit means one of those situations:\n * the link already exist\n * the link cannot be created because the configuration is incorrect or missing\n\nAfter this call, the links are initialized but the creation will be processed by an asynchronous batch.\nTo check the status, you can get the annotations, and check the `integrations` field. In this field,\nan integration with inner field `url` set to `null` means it is still pending.\nOnce the `url` field is not null, it means the link has been successfully created.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AnnotationBulkCreateIntegrationLinksResponse"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport ANNOTATIONUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/annotations/bulk-create-integration\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"annotations\\\":[\\\"$ANNOTATIONUUID\\\"], \\\"integrationTypes\\\":[\\\"AUTODESK\\\",\\\"PROCORE\\\"]}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nannotationUUID = \"\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/annotations/bulk-create-integration\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"annotations\": [annotationUUID],\n    \"integrationTypes\": [\"AUTODESK\",\"PROCORE\"]\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\nconst annotationUUID = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/annotations/bulk-create-integration`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"annotations\":[annotationUUID], \"integrationTypes\":[\"AUTODESK\",\"PROCORE\"]}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/integrations": {
      "get": {
        "summary": "List integrations on the project",
        "operationId": "getProjectIntegrations",
        "description": "<span class='tag beta'>BETA</span>List all integrations on the project\n\nRequires the permission `project:integrations:read` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Integrations"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List of integrations",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectIntegrations"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/integrations/konekt": {
      "get": {
        "summary": "Get configuration of integration with Konekt on a Project",
        "operationId": "getKonektProjectIntegration",
        "description": "<span class='tag beta'>BETA</span>Get the integration with Newforma Konekt configured on the project\n\nRequires the permission `project:integrations:read` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "200": {
            "description": "The configuration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectIntegrationKonekt"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations/konekt\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations/konekt\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations/konekt`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Create configuration of integration with Konekt on Project",
        "operationId": "createKonektProjectIntegration",
        "description": "<span class='tag beta'>BETA</span>Create the configuration for the integration with Newforma Konekt.\n\nRequires the permission `project:integrations:write` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/projectIntegrationKonektCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The integration was successfully created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectIntegrationKonekt"
                }
              }
            }
          },
          "409": {
            "description": "A configuration already exists on this project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorConflict"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations/konekt\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"hubId\\\":\\\"...\\\",\\\"konektProjectId\\\":1,\\\"options\\\":{\\\"allowInviteUsers\\\":false,\\\"syncStrategy\\\":\\\"BOTH_WAY\\\"}}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations/konekt\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"hubId\": \"...\",\n    \"konektProjectId\": 1,\n    \"options\": {\"allowInviteUsers\": False, \"syncStrategy\": \"BOTH_WAY\"}\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations/konekt`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"hubId\":\"...\",\"konektProjectId\":1,\"options\":{\"allowInviteUsers\":false,\"syncStrategy\":\"BOTH_WAY\"}}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "put": {
        "summary": "Update configuration of the integration with Konekt on Project",
        "operationId": "updateKonektProjectIntegration",
        "description": "<span class='tag beta'>BETA</span>Update the configuration for the integration with Newforma Konekt.\n\nRequires the permission `project:integrations:write` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/projectIntegrationKonektUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The integration was successfully updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectIntegrationKonekt"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations/konekt\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"hubId\\\":\\\"...\\\",\\\"konektProjectId\\\":1,\\\"options\\\":{\\\"allowInviteUsers\\\":false,\\\"syncStrategy\\\":\\\"BOTH_WAY\\\"}}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations/konekt\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"hubId\": \"...\",\n    \"konektProjectId\": 1,\n    \"options\": {\"allowInviteUsers\": False, \"syncStrategy\": \"BOTH_WAY\"}\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations/konekt`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"hubId\":\"...\",\"konektProjectId\":1,\"options\":{\"allowInviteUsers\":false,\"syncStrategy\":\"BOTH_WAY\"}}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete the integration with Konekt on Project",
        "operationId": "deleteKonektProjectIntegration",
        "description": "<span class='tag beta'>BETA</span>Delete the integration with Newforma Konekt on the project.\n\nRequires the permission `project:integrations:write` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Konekt"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The integration was successfully deleted"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations/konekt\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations/konekt\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token }\n)\nprint(response.status_code)\nif response.status_code != 204:\n  print(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations/konekt`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/integrations/autodesk": {
      "get": {
        "summary": "Get configuration of integration with Autodesk on a Project",
        "operationId": "getAutodeskProjectIntegration",
        "description": "<span class='tag beta'>BETA</span>Get the integration with Autodesk configured on the project\n\nRequires the permission `project:integrations:read` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Autodesk"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "200": {
            "description": "The configuration",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectIntegrationAutodesk"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations/autodesk\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations/autodesk\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations/autodesk`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Create configuration of integration with Autodesk on Project",
        "operationId": "createAutodeskProjectIntegration",
        "description": "<span class='tag beta'>BETA</span>Create the configuration for the integration with Autodesk.\n\nRequires the permission `project:integrations:write` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Autodesk"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/projectIntegrationAutodeskCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The integration was successfully created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectIntegrationAutodesk"
                }
              }
            }
          },
          "409": {
            "description": "A configuration already exists on this project",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorConflict"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations/autodesk\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"autodeskHubId\\\":\\\"...\\\",\\\"autodeskProjectId\\\":\\\"...\\\"}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations/autodesk\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"autodeskHubId\": \"...\",\n    \"autodeskProjectId\": \"...\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations/autodesk`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"autodeskHubId\":\"...\",\"autodeskProjectId\":\"...\"}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "put": {
        "summary": "Update configuration of the integration with Autodesk on Project",
        "operationId": "updateAutodeskProjectIntegration",
        "description": "<span class='tag beta'>BETA</span>Update the configuration for the integration with Autodesk.\n\nRequires the permission `project:integrations:write` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Autodesk"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/projectIntegrationAutodeskUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The integration was successfully updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ProjectIntegrationAutodesk"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations/autodesk\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\\\"autodeskHubId\\\":\\\"...\\\",\\\"autodeskProjectId\\\":\\\"...\\\"}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations/autodesk\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"autodeskHubId\": \"...\",\n    \"autodeskProjectId\": \"...\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations/autodesk`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"autodeskHubId\":\"...\",\"autodeskProjectId\":\"...\"}\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete the integration with Autodesk on Project",
        "operationId": "deleteAutodeskProjectIntegration",
        "description": "<span class='tag beta'>BETA</span>Delete the integration with Autodesk on the project.\n\nRequires the permission `project:integrations:write` automatically granted for users having\n`workzone:annotations:write` on the root work zone of the project.\n",
        "tags": [
          "Autodesk"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The integration was successfully deleted"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/integrations/autodesk\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/integrations/autodesk\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token }\n)\nprint(response.status_code)\nif response.status_code != 204:\n  print(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/integrations/autodesk`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/crops": {
      "get": {
        "summary": "Get Crops",
        "operationId": "getCrops",
        "description": "<span class='tag beta'>BETA</span>Get all crops related to a project.\n\nRequires the permission `workzone:crops:read` on at least one work zone of the project.\nThe crop returned are all crops on work zones the user has this permission.\n",
        "tags": [
          "Crop"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/workzonesFilter"
          }
        ],
        "responses": {
          "200": {
            "description": "Content of each Crop inside the project you have access to",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Crop"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/crops\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/crops\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/crops`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Create a crop",
        "operationId": "createCrop",
        "description": "<span class='tag beta'>BETA</span>Create a crop\n\nRequires the permission `workzone:crops:write` on the work zone.\n",
        "tags": [
          "Crop"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/cropCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The crop was created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Crop"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport WORKZONEUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/crops\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\n    \\\"workzoneId\\\":\\\"$WORKZONEUUID\\\",\n    \\\"crop\\\":\\\"CropContent\\\",\n    \\\"actualCrop\\\":\\\"actualCropContent\\\",\n    \\\"rotation\\\":\\\"rotationContent\\\",\n    \\\"cameraType\\\":\\\"scan\\\",\n    \\\"cameraState\\\":\\\"cameraStateContent\\\",\n    \\\"scan\\\":\\\"scanContent\\\",\n    \\\"name\\\":\\\"cropName\\\"\n  }\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nworkzoneUUID = \"\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/crops\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"workzoneId\": workzoneUUID,\n    \"crop\": \"CropContent\",\n    \"actualCrop\": \"actualCropContent\",\n    \"rotation\": \"rotationContent\",\n    \"cameraType\": \"scan\",\n    \"cameraState\": \"cameraStateContent\",\n    \"scan\": \"scanContent\",\n    \"name\": \"cropName\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst workzoneId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/crops`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    workzoneId,\n    crop: \"CropContent\",\n    actualCrop: \"actualCropContent\",\n    rotation: \"rotationContent\",\n    cameraType: \"scan\",\n    cameraState: \"cameraStateContent\",\n    scan: \"scanContent\",\n    name: \"cropName\",\n  }),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/crops/{cropRef}": {
      "get": {
        "summary": "Get Crop",
        "operationId": "getCrop",
        "description": "<span class='tag beta'>BETA</span>Get details about a specific crop, related to a project.\n\nRequires the permission `workzone:crops:read` on the work zone in which the crop has been created.\n",
        "tags": [
          "Crop"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/cropRef"
          }
        ],
        "responses": {
          "200": {
            "description": "Content of Crop",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Crop"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport CROPUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/crops/$CROPUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ncropUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/crops/%s\"\n    % (host, accountUUID, projectUUID, cropUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst cropUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/crops/${cropUUID}`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "put": {
        "summary": "Update Crop",
        "operationId": "putCrop",
        "description": "<span class='tag beta'>BETA</span>Update a Crop. This can also be a work zone move by providing new workzoneId in which you have required permission.\nNote that missing fields, even optionals, are considered as null (useful for removing fields).\n\nRequires the permission `workzone:crops:write` in the work zone in which the crop belong to, and in case of crop move, also in the target work zone.\n",
        "tags": [
          "Crop"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/cropRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/cropUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Details of updated crop",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Crop"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport CROPUUID=...\nexport WORKZONEUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/crops/$CROPUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"{\n    \\\"workzoneId\\\":\\\"$WORKZONEUUID\\\",\n    \\\"crop\\\":\\\"CropContent\\\",\n    \\\"actualCrop\\\":\\\"actualCropContent\\\",\n    \\\"rotation\\\":\\\"rotationContent\\\",\n    \\\"cameraType\\\":\\\"scan\\\",\n    \\\"cameraState\\\":\\\"cameraStateContent\\\",\n    \\\"scan\\\":\\\"scanContent\\\",\n    \\\"name\\\":\\\"cropName\\\"\n  }\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ncropUUID = \"...\"\nworkzoneUUID = \"\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/crops/%s\"\n    % (host, accountUUID, projectUUID, cropUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"workzoneId\": workzoneUUID,\n    \"crop\": \"CropContent\",\n    \"actualCrop\": \"actualCropContent\",\n    \"rotation\": \"rotationContent\",\n    \"cameraType\": \"scan\",\n    \"cameraState\": \"cameraStateContent\",\n    \"scan\": \"scanContent\",\n    \"name\": \"cropName\"\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst cropUUID = \"...\";\nconst workzoneUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/crops/${cropUUID}`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify({\n    workzoneId: workzoneUUID,\n    crop: \"CropContent\",\n    actualCrop: \"actualCropContent\",\n    rotation: \"rotationContent\",\n    cameraType: \"scan\",\n    cameraState: \"cameraStateContent\",\n    scan: \"scanContent\",\n    name: \"cropName\",\n  }),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete Crop",
        "operationId": "deleteCrop",
        "description": "<span class='tag beta'>BETA</span>Delete a given Crop.\n\nRequires the permission `workzone:crops:write` in the work zone in which the crop belongs to.\n",
        "tags": [
          "Crop"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/cropRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The Crop has been successfully deleted"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport CROPUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/crops/$CROPUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ncropUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/crops/%s\"\n    % (host, accountUUID, projectUUID, cropUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst cropUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/crops/${cropUUID}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/crops/{cropRef}/cover": {
      "post": {
        "summary": "Get a signed URL for crop cover file upload",
        "operationId": "signCropCoverURL",
        "description": "<span class='tag beta'>BETA</span>- Get a signed URL for crop cover file upload\n\nRequires the permission `workzone:crops:write`.\n\nAfter this call, use the `url`s from the response to upload the crop cover file.\n\nRequired headers to push the files\n* `Content-MD5: xxx` with `xxx` being a base 64 encode of the md5sum in binary format.\\\n  Example: `MD5SUM=\"$(openssl md5 -binary < \"$FILENAME\" | base64)\"`\n* `Cache-Control: max-age=2592000`\n* `x-ms-blob-type: BlockBlob` mandatory if the storage type is Azure. \\\n  Note: always adding the `x-ms-blob-type` could be a good idea as Aws ignores it anyway.\n",
        "tags": [
          "Crop"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/cropRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "extension",
                  "size",
                  "md5"
                ],
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "extension": {
                    "type": "string",
                    "enum": [
                      "png",
                      "jpg",
                      "jpeg"
                    ]
                  },
                  "size": {
                    "type": "integer",
                    "description": "Size of the file (bytes)",
                    "minimum": 1,
                    "maximum": 10485760
                  },
                  "md5": {
                    "type": "string",
                    "description": "The md5 sum-check of the file"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The signing process succeeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "provider",
                    "expiresIn",
                    "file"
                  ],
                  "properties": {
                    "provider": {
                      "type": "string"
                    },
                    "expiresIn": {
                      "type": "integer",
                      "description": "After this amount of seconds, the upload link won't be available anymore"
                    },
                    "file": {
                      "type": "object",
                      "required": [
                        "name",
                        "extension",
                        "size",
                        "md5",
                        "url"
                      ],
                      "properties": {
                        "name": {
                          "type": "string"
                        },
                        "extension": {
                          "type": "string"
                        },
                        "size": {
                          "type": "integer",
                          "description": "Size of the file (bytes)"
                        },
                        "md5": {
                          "type": "string",
                          "description": "The md5 sum-check of the file"
                        },
                        "url": {
                          "type": "string",
                          "description": "the url to which upload the file"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTID=...\nexport PROJECTID=...\nexport CROPID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTID/projects/$PROJECTID/crops/$CROPID/cover\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n      \"name\":\"cover.png\",\n      \"extension\":\"png\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\"\n    }'\n\n# -- UPLOAD OF THE FILE --\n\n# the url received in the body of the response\nexport URL=...\nexport FILENAME=...\n\nMD5SUM=\"$(openssl md5 -binary < \"$FILENAME\" | base64)\"\ncurl --request PUT --url \"$URL\" --header \"Content-Type: application/json\" -T \"$FILENAME\" -H \"Content-MD5: ${MD5SUM}\" -H \"Cache-Control: max-age=2592000\" -H \"x-ms-blob-type: BlockBlob\" -i\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountID = \"...\"\nprojectID = \"...\"\ncropID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/crops/%s/cover\"\n    % (host, accountID, projectID, cropID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n      \"name\":\"tumbleweed.png\",\n      \"extension\":\"png\",\n      \"size\":448459,\n      \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\"\n    }\n)\nprint(response.status_code)\nprint(response.json())\n\nimport base64\nimport hashlib\n\n# the url received in the body of the response\nexport url=...\nexport filename=...\n\nhash_md5 = hashlib.md5()\nwith open(filename, \"rb\") as fin:\n    for chunk in iter(lambda: fin.read(4096), b\"\"):\n        hash_md5.update(chunk)\ndigest = hash_md5.digest()\nmd5 = base64.b64encode(digest).decode(\"utf-8\")\n\nheaders = {\n  \"Content-MD5\": md5,\n  \"Cache-Control\": \"max-age=2592000\",\n  \"x-ms-blob-type\": \"BlockBlob\", # mandatory if storage type is azure\n}\ndata = open(filename, \"rb\")\nr = requests.put(url, data=data, headers=headers)\nprint(r.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountId = \"...\";\nconst projectId = \"...\";\nconst cropId = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountId}/projects/${projectId}/crops/${cropId}/cover`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n          \"name\":\"cover.png\",\n          \"extension\":\"png\",\n          \"size\":448459,\n          \"md5\":\"da04845eaedb7db7f5b6f32c4076821f\",\n        }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/measurements": {
      "get": {
        "summary": "Get Measurements",
        "operationId": "getMeasurements",
        "description": "<span class='tag beta'>BETA</span>Get all Measurements related to a project.\n\nRequires the permission `workzone:measurements:read` on at least one work zone of the project.\nThe measurements returned are all measurements on work zones the user has this permission.\n",
        "tags": [
          "Measurement"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "200": {
            "description": "Content of each Measurement inside the project you have access to",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Measurement"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/measurements\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/measurements\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/measurements`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/tag-lists": {
      "get": {
        "summary": "Get tag lists",
        "operationId": "getTagsOnProject",
        "description": "<span class='tag beta'>BETA</span>Get all tag lists in a project.\n\nRequires the permission `workzone:tags:read` on at least one work zone of the project.\nThe tag lists returned are all tag lists on work zones the user has this permission.\n\nThe project must have an active subscription.\n",
        "tags": [
          "Tag List"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "responses": {
          "200": {
            "description": "List of tag lists",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagList"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "post": {
        "summary": "Create a tag list",
        "operationId": "createTagList",
        "description": "<span class='tag beta'>BETA</span>Create a tag list.\n\nRequires the permission `workzone:tags:write` on the work zone.\n\nThe project must have an active subscription.\n",
        "tags": [
          "Tag List"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/tagListCreate"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The tag list was successfully created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagList"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"workzoneId\": \"...\",\n    \"tagListType\": \"3d\",\n    \"name\": \"Test\",\n    \"description\": \"This is a test\",\n    \"color\": \"#123456\",\n    \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n}'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"workzoneId\": \"...\",\n    \"tagListType\": \"3d\",\n    \"name\": \"Test\",\n    \"description\": \"This is a test\",\n    \"color\": \"#123456\",\n    \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"workzoneId\": \"...\",\n        \"tagListType\": \"3d\",\n        \"name\": \"Test\",\n        \"description\": \"This is a test\",\n        \"color\": \"#123456\",\n        \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n    }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/tag-lists/bulk-update": {
      "post": {
        "summary": "Update multiple tag lists",
        "operationId": "bulkUpdateTagLists",
        "description": "<span class='tag beta'>BETA</span>Update tag lists.\n\nRequires the permission `workzone:tags:write` on the work zones of the tag lists.\n\nThe project must have an active subscription.\nThe tag lists must not be pending.\n\nNote that the workzoneId may be updated to perform a move to another work zone. In this case the permission\n`workzone:tags:write` is also required on the target work zone.\n",
        "tags": [
          "Tag List"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "allOf": [
                    {
                      "type": "object",
                      "required": [
                        "id"
                      ],
                      "properties": {
                        "id": {
                          "$ref": "#/components/schemas/TagListRef"
                        }
                      }
                    },
                    {
                      "$ref": "#/components/schemas/tagListUpdate"
                    }
                  ]
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tag lists were successfully updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TagList"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists/bulk-update\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '[{\n    \"id\": \"...\",\n    \"workzoneId\": \"...\",\n    \"tagListType\": \"3d\",\n    \"name\": \"Test\",\n    \"description\": \"This is a test\",\n    \"color\": \"#123456\",\n    \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n}]'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists/bulk-update\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"id\": \"...\",\n    \"workzoneId\": \"...\",\n    \"tagListType\": \"3d\",\n    \"name\": \"Test\",\n    \"description\": \"This is a test\",\n    \"color\": \"#123456\",\n    \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists/bulk-update`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [{\n        \"id\": \"...\",\n        \"workzoneId\": \"...\",\n        \"tagListType\": \"3d\",\n        \"name\": \"Test\",\n        \"description\": \"This is a test\",\n        \"color\": \"#123456\",\n        \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n    }]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/tag-lists/bulk-delete": {
      "post": {
        "summary": "Delete multiple tag lists",
        "operationId": "bulkDeleteTagLists",
        "description": "<span class='tag beta'>BETA</span>Delete tag lists.\n\nThe project must have an active subscription.\nThe tag lists must not be pending.\n\nRequires the permission `workzone:tags:write` on the work zones of the tag lists.\n",
        "tags": [
          "Tag List"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "ids"
                ],
                "properties": {
                  "ids": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/TagListRef"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "204": {
            "description": "The tag lists were successfully deleted"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists/bulk-delete\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\"ids\": [\"...\", \"...\"]}'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists/bulk-delete\"\n    % (host, accountUUID, projectUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"ids\": [\"...\", \"...\"]\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists/bulk-delete`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\"ids\": [\"...\", \"...\"]}\n  ),\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/tag-lists/{tagListRef}": {
      "put": {
        "summary": "Update a tag list",
        "operationId": "updateTagList",
        "description": "<span class='tag beta'>BETA</span>Update a tag list.\n\n<span class='block' style='background-color: PapayaWhip;'><span class='icon' style='color: red; font-size:20px;'>&#9888;</span> Overwrites all fields. Missing fields will be considered as null and current values will be erased</span>\n\nRequires the permission `workzone:tags:write` on the work zone of the tag list.\n\nThe project must have an active subscription.\nThe tag list must not be pending.\n\nNote that the workzoneId may be updated to perform a move to another work zone. In this case the permission\n`workzone:tags:write` is also required on the target work zone.\n",
        "tags": [
          "Tag List"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/tagListRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/tagListUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tag list was successfully updated",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagList"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport LISTUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists/$LISTUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"workzoneId\": \"...\",\n    \"tagListType\": \"3d\",\n    \"name\": \"Test\",\n    \"description\": \"This is a test\",\n    \"color\": \"#123456\",\n    \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n}'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nlistUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.put(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists/%s\"\n    % (host, accountUUID, projectUUID, listUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"workzoneId\": \"...\",\n    \"tagListType\": \"3d\",\n    \"name\": \"Test\",\n    \"description\": \"This is a test\",\n    \"color\": \"#123456\",\n    \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst listUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists/${listUUID}`;\nconst res = await fetch(url, {\n  method: \"PUT\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"workzoneId\": \"...\",\n        \"tagListType\": \"3d\",\n        \"name\": \"Test\",\n        \"description\": \"This is a test\",\n        \"color\": \"#123456\",\n        \"metadataDefinition\": [{\"id\": \"test\", \"name\": \"label for test\"}]\n    }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Delete a tag list",
        "operationId": "deleteTagList",
        "description": "<span class='tag beta'>BETA</span>Delete a tag list.\n\nThe project must have an active subscription.\nThe tag list must not be pending.\n\nRequires the permission `workzone:tags:write` on the work zone of the tag list.\n",
        "tags": [
          "Tag List"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/tagListRef"
          }
        ],
        "responses": {
          "204": {
            "description": "The tag list was successfully deleted"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport LISTUUID=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists/$LISTUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nlistUUID = \"\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists/%s\"\n    % (host, accountUUID, projectUUID, listUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst listUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists/${listUUID}`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/tag-lists/{tagListRef}/ai-detection": {
      "post": {
        "summary": "Object Detection on a tag list",
        "operationId": "tagListAiDetection",
        "description": "<span class='tag beta'>BETA</span>Launch AI Detection on a tag list.\n\nRequired:\n- the permission `workzone:tags:write` on the work zone of the tag list\n- the permissions `workzone:reality-data:read` and `workzone:export-jobs-reality-data:write`\n  on the work zones of the scans\n\nThe project must have an active subscription.\nThe tag list must not be pending.\n\nAfter this call, the tag list will become *pending* until the AI detection is done, meaning no more\noperation can be performed on this tag list until the end of the detection.\n",
        "tags": [
          "Tag List"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/tagListRef"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "classes",
                  "filesIds"
                ],
                "properties": {
                  "classes": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minLength": 1,
                    "description": "The list of possible classes can be obtained using the [List AI detection classes](#tag/Tag-List/operation/listAIDetectionClasses) endpoint"
                  },
                  "filesIds": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/FileRef"
                    },
                    "minLength": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The AI detection has been successfully launched on the tag list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TagList"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport LISTUUID=...\n\ncurl --request POST --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists/$LISTUUID/ai-detection\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data '{\n    \"classes\": [\"control_box\"],\n    \"filesIds\": [\"...\"]\n  }'\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nlistUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists/%s/ai-detection\"\n    % (host, accountUUID, projectUUID, listUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = {\n    \"classes\": [\"control_box\"],\n    \"filesIds\": [\"...\"]\n  }\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst listUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists/${listUUID}/ai-detection`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    {\n        \"classes\": [\"control_box\"],\n        \"filesIds\": [\"...\"]\n      }\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/tag-lists/{tagListRef}/tags": {
      "get": {
        "summary": "Get tags",
        "operationId": "getTagsOnList",
        "description": "<span class='tag beta'>BETA</span>Get tags from a tag list.\n\nRequires the permission `workzone:tags:read` on the work zone of the tag list.\n\nThe project must have an active subscription.\n\nIf the parameter `afterVersion` is not specified (or 0 or negative value), all tags of the tag list are returned.\nIf it is specified, it will return all changes after the given version, including new tags, updated tags,\nbut also deleted tags (with `isDeleted` set to true in the response).\n",
        "tags": [
          "Tag"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/tagListRef"
          },
          {
            "$ref": "#/components/parameters/afterVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "List of tags",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Tag"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport LISTUUID=...\n\ncurl --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists/$LISTUUID?afterVersion=0\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\nlistUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists/%s?afterVersion=0\"\n    % (host, accountUUID, projectUUID, listUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst listUUID = \"...\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists/${listUUID}?afterVersion=0`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/tag-lists/{tagListRef}/tags/bulk": {
      "post": {
        "summary": "Bulk operation on tags",
        "operationId": "bulkTags",
        "description": "<span class='tag beta'>BETA</span>Bulk operation on tags inside a tag list.\n\nRequires the permission `workzone:tags:write` on the work zone of the tag list.\nThe tag list must not be pending, and must not exceed the maximum number of tags for a tag list (50000).\n\nThe bulk operation perform all requests together, if any fails nothing is done (no partial execution).\n",
        "tags": [
          "Tag"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/tagListRef"
          }
        ],
        "requestBody": {
          "description": "Operations to perform: tags to create, tags to update, and tags to delete.\n",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/tagsBulkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "All the operations are successful.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/tagsBulkResponse"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport TARGETTAGLISTUUID=...\nexport SOURCETAGLISTUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists/$TARGETTAGLISTUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"[{\\\"sourceTagListId\\\":\\\"$SOURCETAGLISTUUID\\\",\\\"tagsIds\\\":[...]}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntargetListUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists/%s\"\n    % (host, accountUUID, projectUUID, targetListUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [{\n    \"sourceTagListId\": \"...\",\n    \"tagsIds\": [...]\n  }]\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst targetTagListUUID = \"...\";\nconst token = \"...\";\nconst sourceTagListUUID = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists/${targetTagListUUID}`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [{\"sourceTagListId\":sourceTagListUUID,\"tagsIds\":[...]}]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/accounts/{accountRef}/projects/{projectRef}/tag-lists/{tagListRef}/tags/bulk-move": {
      "post": {
        "summary": "Move tags between tag lists",
        "operationId": "bulkMoveTags",
        "description": "<span class='tag beta'>BETA</span>Move tags from different tag lists to a common target tag list.\n\n- Requires the permission `workzone:tags:write` on the work zones of all tag lists\n- The project must have a valid subscription\n- All tag lists must not be pending\n- The target tag list must not exceed the maximum number of tags for a tag list (50000)\n",
        "tags": [
          "Tag"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/accountRef"
          },
          {
            "$ref": "#/components/parameters/projectRef"
          },
          {
            "$ref": "#/components/parameters/tagListRef"
          }
        ],
        "requestBody": {
          "description": "For each source tag list, the tags to move.\n\nAn optional metadata id mapping can be specified for each list, to update the metadata ids inside the tags to move.\n",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/tagsMoveBulkRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tags are successfully moved.\n\nThe response returns for each tag list (including all source lists and the target list),\nthe new state of the tag list together with the state of the updated tags.\n\nThe target tag list contains all moved tags as new tags, while each source tag list contains the tags moved\nfrom it as deleted in the list.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/tagsMoveBulkResponse"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\nexport ACCOUNTUUID=...\nexport PROJECTUUID=...\nexport TARGETTAGLISTUUID=...\nexport SOURCETAGLISTUUID=...\n\ncurl --request PUT --url \"https://aec.cintoo.com/api/2/accounts/$ACCOUNTUUID/projects/$PROJECTUUID/tag-lists/$TARGETTAGLISTUUID\" \\\n  --header \"Authorization: Bearer $TOKEN\" \\\n  --header \"Content-Type: application/json\" \\\n  --data \"[{\\\"sourceTagListId\\\":\\\"$SOURCETAGLISTUUID\\\",\\\"tagsIds\\\":[...]}\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\naccountUUID = \"...\"\nprojectUUID = \"...\"\ntargetListUUID = \"...\"\ntoken = \"...\"\n\nresponse = requests.post(\n  \"https://%s/api/2/accounts/%s/projects/%s/tag-lists/%s\"\n    % (host, accountUUID, projectUUID, targetListUUID),\n  headers = { \"Authorization\": \"Bearer %s\" % token },\n  json = [{\n    \"sourceTagListId\": \"...\",\n    \"tagsIds\": [...]\n  }]\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst accountUUID = \"...\";\nconst projectUUID = \"...\";\nconst targetTagListUUID = \"...\";\nconst token = \"...\";\nconst sourceTagListUUID = \"...\";\n\nconst url = `https://${host}/api/2/accounts/${accountUUID}/projects/${projectUUID}/tag-lists/${targetTagListUUID}`;\nconst res = await fetch(url, {\n  method: \"POST\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n    \"Content-Type\": \"application/json\",\n  },\n  body: JSON.stringify(\n    [{\"sourceTagListId\":sourceTagListUUID,\"tagsIds\":[...]}]\n  ),\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/values/permissions": {
      "get": {
        "summary": "List permissions",
        "operationId": "listPermissions",
        "description": "<span class='tag beta'>BETA</span>List available permissions",
        "tags": [
          "Permissions"
        ],
        "responses": {
          "200": {
            "description": "List of permissions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Permission"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\n\ncurl --url \"https://aec.cintoo.com/api/2/values/permissions\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/values/permissions\" % host,\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/values/permissions`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/values/formats": {
      "get": {
        "summary": "List file formats",
        "operationId": "listFormats",
        "description": "<span class='tag beta'>BETA</span>List supported file formats",
        "tags": [
          "File"
        ],
        "responses": {
          "200": {
            "description": "List of file formats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/FileFormat"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        }
      }
    },
    "/api/2/values/spatial-references": {
      "get": {
        "summary": "List Spatial References",
        "operationId": "listSpatialReferences",
        "description": "<span class='tag beta'>BETA</span>List official Spatial References from https://spatialreference.org/",
        "tags": [
          "Project"
        ],
        "responses": {
          "200": {
            "description": "List of Spatial References",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/SpatialReferenceValue"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\n\ncurl --url \"https://aec.cintoo.com/api/2/values/spatial-references\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/values/spatial-references\" % host,\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/values/spatial-references`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/values/ai-detection-classes": {
      "get": {
        "summary": "List AI detection classes",
        "operationId": "listAIDetectionClasses",
        "description": "<span class='tag beta'>BETA</span>List possible classes for AI detection",
        "tags": [
          "Tag List"
        ],
        "responses": {
          "200": {
            "description": "List of classes",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AIDetectionClass"
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\n\ncurl --url \"https://aec.cintoo.com/api/2/values/ai-detection-classes\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/values/ai-detection-classes\" % host,\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "\nconst host = \"aec.cintoo.com\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/values/ai-detection-classes`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      }
    },
    "/api/2/integrations/autodesk/connection": {
      "get": {
        "summary": "Get my connection to Autodesk",
        "operationId": "getAutodeskConnection",
        "description": "<span class='tag beta'>BETA</span>Get the Autodesk user connected for the current user\n\nRequires no permission, but must be logged in as a user.\n\nIf no connection exists, an error 404 is returned. To create a connection, the user needs to follow the\nOAuth flow on Autodesk, using the [/integrations/autodesk/connection/url](#tag/AutodeskConnection/operation/getAutodeskConnectionUrl) endpoint.\n",
        "tags": [
          "Autodesk"
        ],
        "responses": {
          "200": {
            "description": "Connection to Autodesk",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AutodeskConnection"
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\n\ncurl --url \"https://aec.cintoo.com/api/2/integrations/autodesk/connection\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\ntoken = \"...\"\n\nresponse = requests.get(\n  \"https://%s/api/2/integrations/autodesk/connection\"\n    % (host),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\nprint(response.json())\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/integrations/autodesk/connection`;\nconst res = await fetch(url, {\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nconst data = await res.json();\nconsole.log(data);\n"
          }
        ]
      },
      "delete": {
        "summary": "Disconnect me from Autodesk",
        "operationId": "deleteAutodeskConnection",
        "description": "<span class='tag beta'>BETA</span>Delete connection on Autodesk for the current user\n\nRequires no permission, but must be logged in as a user.\n\nRemoving the connection to Autodesk implies that annotations created by the user won't be synchronized on\nAutodesk for all accounts and all projects.\n",
        "tags": [
          "Autodesk"
        ],
        "responses": {
          "204": {
            "description": "Connection successfully deleted"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        },
        "x-codeSamples": [
          {
            "lang": "cURL",
            "source": "export TOKEN=...\n\ncurl --request DELETE --url \"https://aec.cintoo.com/api/2/integrations/autodesk/connection\" \\\n  --header \"Authorization: Bearer $TOKEN\"\n"
          },
          {
            "lang": "Python",
            "source": "import requests\n\nhost = \"aec.cintoo.com\"\ntoken = \"...\"\n\nresponse = requests.delete(\n  \"https://%s/api/2/integrations/autodesk/connection\"\n    % (host),\n  headers = { \"Authorization\": \"Bearer %s\" % token}\n)\nprint(response.status_code)\n"
          },
          {
            "lang": "TypeScript",
            "source": "const host = \"aec.cintoo.com\";\nconst token = \"...\";\n\nconst url = `https://${host}/api/2/integrations/autodesk/connection`;\nconst res = await fetch(url, {\n  method: \"DELETE\",\n  headers: {\n    \"Authorization\": `Bearer ${token}`,\n  },\n});\n\nconsole.log(res.status);\nif (res.status !== 204) {\n  const data = await res.json();\n  console.log(data);\n}\n"
          }
        ]
      }
    },
    "/api/2/integrations/autodesk/connection/url": {
      "get": {
        "summary": "Create or update Autodesk connection",
        "operationId": "getAutodeskConnectionUrl",
        "description": "<span class='tag beta'>BETA</span>Forward to the OAuth flow on Autodesk. If the user successfully signed in Autodesk and allows Cintoo to\naccess his account, his Autodesk connection is created or updated.\n\nThis endpoint needs to be called using a browser to allow the user to sign in on Autodesk.\n\nOn success, the user is finally redirected to the given query parameter `redirectUri`, allowing your application\nto be notified.\n\nRequires no permission, but must be logged in as a user.\n",
        "tags": [
          "Autodesk"
        ],
        "parameters": [
          {
            "$ref": "#/components/parameters/redirectUri"
          }
        ],
        "responses": {
          "302": {
            "description": "Forward to the OAuth flow on Autodesk"
          },
          "4XX": {
            "$ref": "#/components/responses/UnexpectedError"
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "accountRef": {
        "name": "accountRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the account",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/AccountUrn"
            },
            {
              "$ref": "#/components/schemas/AccountId"
            }
          ]
        }
      },
      "subscriptionRef": {
        "name": "subscriptionRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the subscription",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/SubscriptionUrn"
            },
            {
              "$ref": "#/components/schemas/SubscriptionId"
            }
          ]
        }
      },
      "userRef": {
        "name": "userRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the user",
        "schema": {
          "$ref": "#/components/schemas/UserRef"
        }
      },
      "groupRef": {
        "name": "groupRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the group",
        "schema": {
          "$ref": "#/components/schemas/GroupRef"
        }
      },
      "roleRef": {
        "name": "roleRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the role",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/RoleUrn"
            },
            {
              "$ref": "#/components/schemas/RoleId"
            }
          ]
        }
      },
      "accountIntegrationKonektRef": {
        "name": "integrationRef",
        "in": "path",
        "required": true,
        "description": "The Urn of the integration",
        "schema": {
          "$ref": "#/components/schemas/AccountIntegrationKonektUrn"
        }
      },
      "countScans": {
        "name": "countScans",
        "in": "query",
        "required": false,
        "description": "If true, includes `scanCount` and `scanSize` in the `statsInfo` field of the response.\nIf false, these fields will not be included in `statsInfo`.\n\n**Upcoming change:** The default value will change from `true` to `false` in a future release.\nClients that rely on `scanCount` or `scanSize` should start passing `countScans=true` explicitly.\n",
        "schema": {
          "type": "boolean",
          "default": true
        }
      },
      "countTags": {
        "name": "countTags",
        "in": "query",
        "required": false,
        "description": "If true, includes `tagCount` in the `statsInfo` field of the response.\nIf false, this field will not be included in `statsInfo`.\n\n**Upcoming change:** The default value will change from `true` to `false` in a future release.\nClients that rely on `tagCount` should start passing `countTags=true` explicitly.\n",
        "schema": {
          "type": "boolean",
          "default": true
        }
      },
      "countWorkzones": {
        "name": "countWorkzones",
        "in": "query",
        "required": false,
        "description": "If true, includes `workzoneCount` in the `statsInfo` field of the response.\nIf false, this field will not be included in `statsInfo`.\n\n**Upcoming change:** The default value will change from `true` to `false` in a future release.\nClients that rely on `workzoneCount` should start passing `countWorkzones=true` explicitly.\n",
        "schema": {
          "type": "boolean",
          "default": true
        }
      },
      "projectRef": {
        "name": "projectRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the project",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/ProjectUrn"
            },
            {
              "$ref": "#/components/schemas/ProjectId"
            }
          ]
        }
      },
      "permanentProjectDelete": {
        "name": "permanent",
        "in": "query",
        "required": false,
        "description": "Delete Permanently a project",
        "schema": {
          "type": "boolean"
        }
      },
      "workzoneRef": {
        "name": "workzoneRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the work zone",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/WorkzoneUrn"
            },
            {
              "$ref": "#/components/schemas/WorkzoneId"
            }
          ]
        }
      },
      "allowRemoveOnParents": {
        "name": "allowRemoveOnParents",
        "in": "query",
        "required": false,
        "description": "If true the operation is allowed to remove from a parent.\n\nIf false and the operation needs to remove from a parent, a bad request error will be returned.\n",
        "schema": {
          "type": "boolean",
          "default": false
        }
      },
      "categoryFilter": {
        "name": "category",
        "in": "query",
        "required": false,
        "description": "Comma-separated list of case-sensitive categories of the files we want to list.\n\nProviding at least 1 invalid category will return a 400 Bad Request error.\nProviding empty parameter will return empty files list.\nIf not provided, all files are returned.\n\nThe category of an existing file can be found in its \"type\" field.\n",
        "schema": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "document",
              "model",
              "scan",
              "media",
              "miscfile",
              "archive",
              "geoImage",
              "sitemap",
              "modelReport"
            ]
          }
        },
        "examples": {
          "oneId": {
            "summary": "Example of single category",
            "value": [
              "scan"
            ]
          },
          "multipleIds": {
            "summary": "Example of multiple categories",
            "value": [
              "geoImage",
              "model"
            ]
          }
        }
      },
      "fileRef": {
        "name": "fileRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the file",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/FileUrn"
            },
            {
              "$ref": "#/components/schemas/FileId"
            }
          ]
        }
      },
      "shareLinkRef": {
        "name": "shareLinkRef",
        "in": "path",
        "required": true,
        "description": "The Urn of the share link",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/ShareLinkUrn"
            }
          ]
        }
      },
      "includeComments": {
        "name": "includeComments",
        "in": "query",
        "required": false,
        "description": "If true the operation retrieves comments attached to each annotation,\nelse the comments field will not be returned.\n",
        "schema": {
          "type": "boolean",
          "default": false
        }
      },
      "includeAttachments": {
        "name": "includeAttachments",
        "in": "query",
        "required": false,
        "description": "If true the operation retrieves information about files attached to each annotation or comment,\nelse the attachments field will not be returned.\n",
        "schema": {
          "type": "boolean",
          "default": false
        }
      },
      "annotationRef": {
        "name": "annotationRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the annotation",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/AnnotationUrn"
            },
            {
              "$ref": "#/components/schemas/AnnotationId"
            }
          ]
        }
      },
      "workzonesFilter": {
        "name": "workzones",
        "in": "query",
        "required": false,
        "description": "Comma-separated list of work zone references.\n\nProviding at least 1 invalid (bad format, not exist, unreachable) work zone will return a 400 Bad Request error.\nProviding empty parameter will return empty crops list.\n",
        "schema": {
          "type": "array",
          "items": {
            "$ref": "#/components/schemas/WorkzoneRef"
          }
        },
        "examples": {
          "oneId": {
            "summary": "Example of single work zone",
            "value": [
              "9260cd6f-a27b-456f-a5e3-b9c9fd4689f9"
            ]
          },
          "multipleIds": {
            "summary": "Example of multiple work zones",
            "value": [
              "9260cd6f-a27b-456f-a5e3-b9c9fd4689f9",
              "urn:cintoo:workzone:e7868b89-80a6-429d-949f-66e3834651f2"
            ]
          }
        }
      },
      "cropRef": {
        "name": "cropRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the crop",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/CropUrn"
            },
            {
              "$ref": "#/components/schemas/CropId"
            }
          ]
        }
      },
      "tagListRef": {
        "name": "tagListRef",
        "in": "path",
        "required": true,
        "description": "The Id or Urn of the tag list",
        "schema": {
          "oneOf": [
            {
              "$ref": "#/components/schemas/TagListUrn"
            },
            {
              "$ref": "#/components/schemas/TagListId"
            }
          ]
        }
      },
      "afterVersion": {
        "name": "afterVersion",
        "in": "query",
        "required": false,
        "description": "If specified, return changes after the given version. A negative value or 0 is ignored.\n",
        "schema": {
          "type": "integer",
          "default": 0
        }
      },
      "redirectUri": {
        "name": "redirectUri",
        "in": "query",
        "required": true,
        "description": "The URL to redirect the user once the OAuth flow is successful.\n",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "AccountUrn": {
        "type": "string",
        "description": "\"urn:cintoo:account:\" followed by an UUIDv4\n"
      },
      "DateTime": {
        "type": "string",
        "format": "date-time",
        "description": "The date-time notation as defined by RFC 3339, section 5.6 (ex: 2017-08-18T12:41:31Z)",
        "example": "2017-08-18T12:41:31Z"
      },
      "UserUrn": {
        "type": "string",
        "description": "\"urn:cintoo:user:\" followed by an UUIDv4\n"
      },
      "AccountPermissions": {
        "type": "object",
        "required": [
          "isOwner",
          "isAdmin",
          "isManager",
          "isProjectLister"
        ],
        "properties": {
          "isOwner": {
            "type": "boolean"
          },
          "isAdmin": {
            "type": "boolean"
          },
          "isManager": {
            "type": "boolean"
          },
          "isProjectLister": {
            "type": "boolean"
          }
        }
      },
      "SubscriptionUrn": {
        "type": "string",
        "description": "\"urn:cintoo:subscription:\" followed by an UUIDv4\n"
      },
      "Subscription": {
        "type": "object",
        "required": [
          "id",
          "type",
          "accountId",
          "isVa",
          "isActive",
          "isTrial",
          "geoImageCapacity",
          "tagCapacity",
          "scanCapacity"
        ],
        "x-tags": [
          "Subscription"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/SubscriptionUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "subscription"
            ]
          },
          "accountId": {
            "$ref": "#/components/schemas/AccountUrn"
          },
          "isVa": {
            "type": "boolean"
          },
          "isActive": {
            "type": "boolean"
          },
          "isTrial": {
            "type": "boolean",
            "description": "Indicates whether this subscription is a trial (Free Plan).\n"
          },
          "name": {
            "type": "string",
            "example": "My Subscription"
          },
          "start": {
            "$ref": "#/components/schemas/DateTime"
          },
          "end": {
            "$ref": "#/components/schemas/DateTime",
            "description": "Subscription end date. This property is only included when the requester has the `account:subscriptions:read-sensitive-infos` permission (account owner or administrator).\n"
          },
          "tagCapacity": {
            "type": "integer",
            "example": 50
          },
          "geoImageCapacity": {
            "type": "integer",
            "example": 50
          },
          "scanCapacity": {
            "type": "integer",
            "example": 500
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "inviteAccountOwnerInNewProjects": {
            "type": "boolean",
            "description": "When true, the account owner is automatically invited to every new project in the subscription. This property is only included in responses when the requester is the account owner.\n"
          }
        }
      },
      "Region": {
        "type": "object",
        "required": [
          "id",
          "description",
          "provider",
          "hasCdn",
          "selected",
          "default"
        ],
        "x-tags": [
          "Region"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "provider": {
            "description": "The storage used in this region",
            "type": "string",
            "enum": [
              "azure",
              "s3",
              "minio"
            ]
          },
          "cloudProvider": {
            "description": "The Cloud Platform managing this region",
            "type": "string",
            "enum": [
              "azure",
              "s3",
              "gcp",
              "minio"
            ]
          },
          "region": {
            "description": "A unique region identifier used by the Cloud Platform",
            "type": "string"
          },
          "countryCode": {
            "description": "The country in which the region is physically located",
            "type": "string"
          },
          "hasCdn": {
            "description": "true if a CDN system is enabled with this region",
            "type": "boolean"
          },
          "selected": {
            "description": "true if the region is available for this account",
            "type": "boolean"
          },
          "default": {
            "description": "true if this region is the default one for this account",
            "type": "boolean"
          }
        }
      },
      "Account": {
        "type": "object",
        "required": [
          "id",
          "type",
          "name",
          "createdAt",
          "updatedAt",
          "ownerId",
          "permissions",
          "subscriptions",
          "regions"
        ],
        "x-tags": [
          "Account"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/AccountUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "account"
            ]
          },
          "name": {
            "type": "string",
            "example": "My Account"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "ownerId": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "permissions": {
            "$ref": "#/components/schemas/AccountPermissions"
          },
          "subscriptions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Subscription"
            }
          },
          "regions": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Region"
            }
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "status",
          "title"
        ],
        "properties": {
          "status": {
            "type": "integer",
            "format": "int32"
          },
          "title": {
            "type": "string"
          },
          "detail": {
            "type": "string",
            "description": "human readable description of the error in english"
          },
          "errorCode": {
            "type": "string",
            "description": "detailed code describing error, can be used to map to a localized message"
          },
          "errorValues": {
            "type": "object",
            "description": "values implied in the error, typically an input parameter, can be used to include in a localized message"
          }
        }
      },
      "Uuid": {
        "type": "string",
        "description": "UUIDv4",
        "format": "uuid",
        "example": "156fff1a-0ef7-4335-891a-627928a19e29"
      },
      "AccountId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "SubscriptionId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "date": {
        "type": "string",
        "format": "date",
        "description": "The date-time notation as defined by RFC 3339, section 5.6 (ex: 2017-08-18)",
        "example": "2017-07-21"
      },
      "Date": {
        "type": "string",
        "format": "date",
        "description": "The date-time notation as defined by RFC 3339, section 5.6 (ex: 2017-08-18)",
        "example": "2017-07-21"
      },
      "ProjectUrn": {
        "type": "string",
        "description": "\"urn:cintoo:project:\" followed by an UUIDv4\n"
      },
      "UsageReport": {
        "type": "object",
        "x-tags": [
          "Usage Report"
        ],
        "required": [
          "date",
          "userId",
          "firstName",
          "lastName",
          "email",
          "company",
          "projectId",
          "projectName",
          "scansUploaded",
          "scansDownloaded",
          "360ImagesUploaded",
          "cropsDownloaded",
          "unifiedMeshesCreated",
          "tagsUploaded",
          "tagsDownloaded"
        ],
        "properties": {
          "date": {
            "$ref": "#/components/schemas/Date"
          },
          "userId": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "email": {
            "type": "string"
          },
          "company": {
            "type": "string"
          },
          "projectId": {
            "$ref": "#/components/schemas/ProjectUrn"
          },
          "projectName": {
            "type": "string"
          },
          "scansUploaded": {
            "type": "integer"
          },
          "scansDownloaded": {
            "type": "integer"
          },
          "360ImagesUploaded": {
            "type": "integer"
          },
          "cropsDownloaded": {
            "type": "integer"
          },
          "unifiedMeshesCreated": {
            "type": "integer"
          },
          "tagsUploaded": {
            "type": "integer"
          },
          "tagsDownloaded": {
            "type": "integer"
          }
        }
      },
      "AccountRoles": {
        "type": "string",
        "enum": [
          "administrator",
          "projectLister",
          "projectManager"
        ]
      },
      "UserOldId": {
        "type": "string",
        "pattern": "^[-_0-9a-zA-Z]+$",
        "description": "Base64url encoding of \"user-{id}\""
      },
      "User": {
        "type": "object",
        "required": [
          "id",
          "type",
          "api1Id",
          "firstName",
          "email"
        ],
        "x-tags": [
          "User"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/UserUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "user"
            ]
          },
          "api1Id": {
            "$ref": "#/components/schemas/UserOldId"
          },
          "firstName": {
            "type": "string",
            "example": "John"
          },
          "lastName": {
            "type": "string",
            "example": "Doe"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "company": {
            "type": "string",
            "example": "Cintoo"
          },
          "title": {
            "type": "string",
            "example": "Account Manager"
          },
          "avatar": {
            "type": "string",
            "format": "uri"
          },
          "accountRoles": {
            "type": "array",
            "description": "Account-level roles assigned to this user. Visibility depends on caller's permissions:\n\nVisibility rules:\n- Field is omitted if caller has none of the role read permissions\n- Field is included with filtered roles based on caller's permissions:\n  - `account:administrators:read`: can see administrator role\n  - `account:project-managers:read`: can see projectManager role\n  - `account:project-listers:read`: can see projectLister role\n\nExamples:\n- Account Owner/Admin (has all three read permissions): sees all roles (administrator, projectManager, projectLister)\n- Project Manager (has only project-managers:read): sees only projectManager role\n- Normal user (has no read permissions): field is omitted entirely\n\nNote: The accountOwner role is never exposed in this field.\n",
            "items": {
              "$ref": "#/components/schemas/AccountRoles"
            },
            "example": [
              "administrator",
              "projectManager"
            ]
          }
        }
      },
      "UserId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "UserRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/UserUrn"
          },
          {
            "$ref": "#/components/schemas/UserId"
          }
        ]
      },
      "GroupUrn": {
        "type": "string",
        "description": "\"urn:cintoo:group:\" followed by an UUIDv4\n"
      },
      "Color": {
        "type": "string",
        "pattern": "^#[0-9a-f]{6}$",
        "example": "#0698ec"
      },
      "Group": {
        "type": "object",
        "required": [
          "type",
          "name",
          "color",
          "createdAt",
          "createdBy",
          "updatedAt",
          "userIds",
          "accountIds"
        ],
        "x-tags": [
          "Group"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/GroupUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "group"
            ]
          },
          "name": {
            "type": "string",
            "example": "group"
          },
          "description": {
            "type": "string",
            "example": "group description"
          },
          "color": {
            "$ref": "#/components/schemas/Color"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "userIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserUrn"
            }
          },
          "accountIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountUrn"
            }
          }
        }
      },
      "GroupId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "GroupRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/GroupUrn"
          },
          {
            "$ref": "#/components/schemas/GroupId"
          }
        ]
      },
      "ErrorBadRequest": {
        "type": "object",
        "required": [
          "status",
          "title"
        ],
        "properties": {
          "status": {
            "type": "integer",
            "format": "int32",
            "enum": [
              400
            ]
          },
          "title": {
            "type": "string",
            "enum": [
              "Bad Request"
            ]
          },
          "detail": {
            "type": "string",
            "description": "human readable description of the error in english"
          }
        }
      },
      "RoleUrn": {
        "type": "string",
        "description": "\"urn:cintoo:role:\" followed by an UUIDv4\n"
      },
      "RolePermissions": {
        "type": "array",
        "description": "permissions given by the role. Please check the [permissions](#section/API-Specification/Permissions) section for the list of allowed combinations",
        "minItems": 1,
        "items": {
          "type": "string",
          "enum": [
            "project:project:delete",
            "project:project:update-details",
            "workzone:workzones:write",
            "workzone:workzones:read",
            "workzone:annotations:write",
            "workzone:annotations:read",
            "workzone:measurements:write",
            "workzone:measurements:read",
            "workzone:share-links:write",
            "workzone:share-links:read",
            "workzone:own-share-links:write",
            "workzone:own-share-links:read",
            "workzone:reality-data:read",
            "workzone:reality-data:write",
            "workzone:reality-data:transform",
            "workzone:cad-model:transform",
            "workzone:cad-model:read",
            "workzone:import-jobs-reality-data:write",
            "workzone:export-jobs-reality-data:read",
            "workzone:export-jobs-reality-data:write",
            "workzone:documents:write",
            "workzone:documents:read",
            "workzone:members:write",
            "workzone:tags:write",
            "workzone:tags:read",
            "workzone:savedviews:write",
            "workzone:savedviews:read",
            "workzone:model-reports:read",
            "workzone:model-reports:write",
            "workzone:progress-monitoring-jobs:read",
            "workzone:progress-monitoring-jobs:write",
            "workzone:own-progress-monitoring-jobs:read",
            "workzone:own-progress-monitoring-jobs:write"
          ]
        }
      },
      "Role": {
        "type": "object",
        "required": [
          "id",
          "type",
          "name",
          "createdBy",
          "createdAt",
          "updatedAt",
          "permissions",
          "accountIds"
        ],
        "x-tags": [
          "Role"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/RoleUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "role"
            ]
          },
          "name": {
            "type": "string",
            "example": "BIM / VDC Manager"
          },
          "description": {
            "type": "string",
            "example": "Can do anything except creating projects"
          },
          "color": {
            "$ref": "#/components/schemas/Color"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "permissions": {
            "$ref": "#/components/schemas/RolePermissions"
          },
          "accountIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountUrn"
            }
          }
        }
      },
      "roleCreate": {
        "type": "object",
        "required": [
          "name",
          "permissions"
        ],
        "properties": {
          "name": {
            "type": "string",
            "example": "BIM / VDC Manager"
          },
          "description": {
            "type": "string",
            "example": "Can do anything except creating projects"
          },
          "color": {
            "$ref": "#/components/schemas/Color"
          },
          "permissions": {
            "$ref": "#/components/schemas/RolePermissions"
          }
        }
      },
      "ErrorForbidden": {
        "type": "object",
        "required": [
          "status",
          "title"
        ],
        "properties": {
          "status": {
            "type": "integer",
            "format": "int32",
            "enum": [
              403
            ]
          },
          "title": {
            "type": "string",
            "enum": [
              "Forbidden"
            ]
          },
          "detail": {
            "type": "string",
            "description": "human readable description of the error in english"
          }
        }
      },
      "RoleId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "roleUpdate": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "BIM / VDC Manager"
          },
          "description": {
            "type": "string",
            "example": "Can do anything except creating projects"
          },
          "color": {
            "$ref": "#/components/schemas/Color"
          },
          "permissions": {
            "$ref": "#/components/schemas/RolePermissions"
          }
        }
      },
      "AccountIntegrationKonektUrn": {
        "type": "string",
        "description": "\"urn:cintoo:newforma-konekt-hub:\" followed by an UUIDv4\n"
      },
      "ModificationInfo": {
        "type": "object",
        "required": [
          "createdAt",
          "createdBy"
        ],
        "properties": {
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "deletedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "deletedBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "isDeleted": {
            "type": "boolean"
          }
        }
      },
      "AccountIntegrationNewformaKonektOptions": {
        "type": "object",
        "required": [
          "allowCreateNewUsersOnHub",
          "syncStrategy"
        ],
        "properties": {
          "allowCreateNewUsersOnHub": {
            "type": "boolean",
            "description": "if true it allows to create automatically new users on the Konekt Hub when synchronizing data"
          },
          "syncStrategy": {
            "type": "string",
            "enum": [
              "CONFIG_ON_PROJECT",
              "BOTH_WAY",
              "UPDATES_ONLY_FROM_KONEKT"
            ],
            "description": "CONFIG_ON_PROJECT means the option needs to be configured on each project.\n\nBOTH_WAY means an update on Cintoo triggers an update on Konekt.\n\nUPDATES_ONLY_FROM_KONEKT means an update on Cintoo does not trigger an update on Konekt.\n\nBOTH_WAY and UPDATES_ONLY_FROM_KONEKT means an update on Konekt will trigger an update on Cintoo.\n"
          }
        }
      },
      "ProjectInKonektHub": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string",
            "description": "id of the project on Konekt"
          },
          "name": {
            "type": "string",
            "description": "name of the project on Konekt"
          }
        }
      },
      "ProjectIntegrationNewformaKonektOptions": {
        "type": "object",
        "required": [
          "allowInviteUsers",
          "syncStrategy"
        ],
        "properties": {
          "allowInviteUsers": {
            "type": "boolean",
            "description": "if true it allows to invite users on the Konekt project when synchronizing data"
          },
          "syncStrategy": {
            "type": "string",
            "enum": [
              "BOTH_WAY",
              "UPDATES_ONLY_FROM_KONEKT"
            ],
            "description": "BOTH_WAY means an update on Cintoo triggers an update on Konekt.\n\nUPDATES_ONLY_FROM_KONEKT means an update on Cintoo does not trigger an update on Konekt.\n\nBOTH_WAY and UPDATES_ONLY_FROM_KONEKT means an update on Konekt will trigger an update on Cintoo.\n"
          }
        }
      },
      "AccountIntegrationNewformaKonektLinkedProject": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/ProjectUrn"
          },
          "konektId": {
            "type": "number"
          },
          "options": {
            "$ref": "#/components/schemas/ProjectIntegrationNewformaKonektOptions"
          }
        }
      },
      "AccountIntegrationKonekt": {
        "type": "object",
        "x-tags": [
          "Konekt"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/AccountIntegrationKonektUrn"
          },
          "konektId": {
            "type": "string",
            "description": "id of the hub on Konekt"
          },
          "beta": {
            "type": "boolean",
            "description": "indicates if the hub is on Konekt beta or Konekt production"
          },
          "modificationInfo": {
            "$ref": "#/components/schemas/ModificationInfo"
          },
          "link": {
            "type": "string"
          },
          "options": {
            "$ref": "#/components/schemas/AccountIntegrationNewformaKonektOptions"
          },
          "name": {
            "type": "string",
            "nullable": true,
            "description": "name of the hub on Konekt if available"
          },
          "connected": {
            "type": "boolean",
            "description": "indicates if a valid token is configured"
          },
          "konektProjects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ProjectInKonektHub"
            },
            "description": "list of projects on the Konekt Hub"
          },
          "linkedProjects": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountIntegrationNewformaKonektLinkedProject"
            },
            "description": "Cintoo projects configured with this Konekt Hub"
          }
        }
      },
      "AccountIntegrations": {
        "type": "object",
        "properties": {
          "konekt": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountIntegrationKonekt"
            }
          }
        }
      },
      "accountIntegrationKonektCreate": {
        "type": "object",
        "required": [
          "token"
        ],
        "properties": {
          "token": {
            "type": "string",
            "description": "A valid API token for Newforma Konekt"
          },
          "options": {
            "allOf": [
              {
                "$ref": "#/components/schemas/AccountIntegrationNewformaKonektOptions"
              }
            ],
            "type": "object",
            "nullable": true
          }
        }
      },
      "ErrorConflict": {
        "type": "object",
        "required": [
          "status",
          "title"
        ],
        "properties": {
          "status": {
            "type": "integer",
            "format": "int32",
            "enum": [
              409
            ]
          },
          "title": {
            "type": "string",
            "enum": [
              "Conflict"
            ]
          },
          "detail": {
            "type": "string",
            "description": "human readable description of the error in english"
          }
        }
      },
      "accountIntegrationKonektUpdate": {
        "type": "object",
        "required": [
          "options"
        ],
        "properties": {
          "options": {
            "$ref": "#/components/schemas/AccountIntegrationNewformaKonektOptions"
          }
        }
      },
      "accountIntegrationConnectionKonektCreate": {
        "type": "object",
        "required": [
          "token"
        ],
        "properties": {
          "token": {
            "type": "string",
            "description": "A valid API token for Newforma Konekt"
          }
        }
      },
      "Location": {
        "type": "object",
        "required": [
          "lat",
          "lng"
        ],
        "properties": {
          "lat": {
            "type": "number",
            "format": "double",
            "minimum": -90,
            "maximum": 90
          },
          "lng": {
            "type": "number",
            "format": "double",
            "minimum": -180,
            "maximum": 180
          }
        }
      },
      "ProjectStatsInfo": {
        "type": "object",
        "description": "Statistics about the project. By default all fields are included.\nUse the query parameters `countScans`, `countTags`, and `countWorkzones` to control which fields are returned.\nWhen all query parameters are set to `false`, `statsInfo` is `null`.\n\n**Upcoming change:** In a future release, all `count*` query parameters will default to `false`,\nmeaning `statsInfo` will be `null` by default. Clients that need statistics should start passing the\ndesired `count*` parameters explicitly set to `true`.\n",
        "properties": {
          "scanCount": {
            "type": "integer"
          },
          "scanSize": {
            "type": "integer"
          },
          "tagCount": {
            "type": "integer"
          },
          "workzoneCount": {
            "type": "integer",
            "description": "Number of workzones in a project (includes root workzone)"
          }
        }
      },
      "BlobName": {
        "type": "string",
        "description": "A `BlobName`: the actual filename of the file in the blob storage.\n\nTo retrieve a blob, two methods are available:\n- using the unitary endpoint [Download a blob](#tag/Project/operation/getBlob), which will automatically forward\n  to the final URL, which is a pre-signed URL, expiring after 3 hours by default.\n- using the bulk endpoint [Get pre-signed urls for multiple blobs](#tag/Project/operation/getBlobs), which will\n  return the list of pre-signed URLs.\n\nWhile the first option is the easiest, as it forwards automatically to the final URL transparently,\nthe second option should be preferred as much as possible to improve performances.\n"
      },
      "Url": {
        "type": "string",
        "format": "uri",
        "description": "Link that will redirect to 302 signed link to download the corresponding file."
      },
      "WorkzoneUrn": {
        "type": "string",
        "pattern": "^urn:cintoo:workzone:[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$",
        "description": "\"urn:cintoo:workzone:\" followed by an UUIDv4\n"
      },
      "SpatialReferenceProject": {
        "type": "object",
        "required": [
          "authName",
          "code"
        ],
        "properties": {
          "authName": {
            "type": "string",
            "description": "The authority defining the used code (IGNF, NKG, OGC, IAU_2015, EPSG, ESRI)"
          },
          "code": {
            "type": "string",
            "description": "The code of the geographic reference to be used for this project"
          }
        }
      },
      "Project": {
        "type": "object",
        "required": [
          "id",
          "type",
          "accountId",
          "subscriptionId",
          "isdemo",
          "region",
          "name",
          "description",
          "ownerId",
          "location",
          "modificationInfo",
          "statsInfo",
          "rootWorkzoneId",
          "permissions"
        ],
        "x-tags": [
          "Project"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/ProjectUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "project"
            ]
          },
          "accountId": {
            "$ref": "#/components/schemas/AccountUrn"
          },
          "subscriptionId": {
            "$ref": "#/components/schemas/SubscriptionUrn"
          },
          "isdemo": {
            "type": "boolean"
          },
          "region": {
            "type": "string",
            "description": "Region.Id (can be found in accounts.regions.id) hosting the project data",
            "example": "default"
          },
          "name": {
            "type": "string",
            "description": "Named displayed for the project",
            "example": "New Project"
          },
          "description": {
            "type": "string"
          },
          "ownerId": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "modificationInfo": {
            "$ref": "#/components/schemas/ModificationInfo"
          },
          "statsInfo": {
            "type": "object",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectStatsInfo"
              }
            ]
          },
          "coverBlobName": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ]
          },
          "coverUrl": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/Url"
              }
            ]
          },
          "rootWorkzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "spatialReference": {
            "type": "object",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/SpatialReferenceProject"
              }
            ]
          },
          "permissions": {
            "type": "array",
            "items": {
              "description": "list of permissions at project level, for the user doing the request.",
              "type": "string"
            }
          },
          "bimOnRootWz": {
            "type": "boolean",
            "nullable": true,
            "description": "Indicates whether the requesting user has the BIM role on the root workzone of this project.\n- `true`: the user has the BIM role on the root workzone\n- `false`: the user does not have the BIM role on the root workzone\n- `null`: the user does not have permission to see this information (requires `account:projects:manage-me-as-bim` permission)\n"
          }
        }
      },
      "SpatialReference": {
        "type": "object",
        "required": [
          "authName",
          "code"
        ],
        "properties": {
          "authName": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The authority defining the used code (IGNF, NKG, OGC, IAU_2015, EPSG, ESRI)"
          },
          "code": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "The code of the geographic reference to be used for this project"
          }
        }
      },
      "ProjectId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "SubscriptionRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/SubscriptionUrn"
          },
          {
            "$ref": "#/components/schemas/SubscriptionId"
          }
        ]
      },
      "FileUrn": {
        "type": "string",
        "description": "\"urn:cintoo:file:\" followed by an UUIDv4\n"
      },
      "WorkzoneStatsInfo": {
        "type": "object",
        "required": [
          "scanCount",
          "scanSize",
          "tagCount"
        ],
        "properties": {
          "scanCount": {
            "type": "integer"
          },
          "scanSize": {
            "type": "integer"
          },
          "tagCount": {
            "type": "integer"
          }
        }
      },
      "Workzone": {
        "type": "object",
        "required": [
          "id",
          "type",
          "projectId",
          "rootWorkzoneId",
          "name",
          "description",
          "roleIds",
          "modificationInfo",
          "statsInfo"
        ],
        "x-tags": [
          "Workzone"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "workzone"
            ]
          },
          "projectId": {
            "$ref": "#/components/schemas/ProjectUrn"
          },
          "parentId": {
            "allOf": [
              {
                "$ref": "#/components/schemas/WorkzoneUrn"
              },
              {
                "type": "string",
                "nullable": true
              }
            ],
            "description": "`WorkzoneUrn` of the parent Workzone. Null if the work zone is a rootWorkzone."
          },
          "rootWorkzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "name": {
            "type": "string",
            "example": "New Workzone"
          },
          "description": {
            "type": "string"
          },
          "roleIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RoleUrn"
            }
          },
          "coverBlobName": {
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ],
            "type": "string",
            "nullable": true
          },
          "coverUrl": {
            "type": "string",
            "nullable": true
          },
          "modificationInfo": {
            "$ref": "#/components/schemas/ModificationInfo"
          },
          "statsInfo": {
            "$ref": "#/components/schemas/WorkzoneStatsInfo"
          }
        }
      },
      "WorkzoneId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "WorkzoneRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          {
            "$ref": "#/components/schemas/WorkzoneId"
          }
        ]
      },
      "workzoneCreate": {
        "type": "object",
        "required": [
          "name",
          "parentWorkzoneId"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "parentWorkzoneId": {
            "$ref": "#/components/schemas/WorkzoneRef"
          },
          "description": {
            "type": "string"
          },
          "coverUrl": {
            "type": "string"
          }
        }
      },
      "RoleRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/RoleUrn"
          },
          {
            "$ref": "#/components/schemas/RoleId"
          }
        ]
      },
      "Archive": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlob"
          },
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/FileCategoryArchive"
              }
            }
          }
        ]
      },
      "Document": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlob"
          },
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/FileCategoryDocument"
              }
            }
          }
        ]
      },
      "GeoImage": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlob"
          },
          {
            "$ref": "#/components/schemas/FileImported"
          },
          {
            "$ref": "#/components/schemas/FilePlaced"
          },
          {
            "type": "object",
            "required": [
              "type",
              "resolution",
              "blobPreview",
              "urlPreview",
              "panoramaWidth",
              "panoramaHeight"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/FileCategoryGeoImage"
              },
              "resolution": {
                "type": "object",
                "allOf": [
                  {
                    "$ref": "#/components/schemas/Dimension2d"
                  }
                ],
                "description": "The image's resolution: has a `w` and a `h`, respectively for *width* and *height*. This is not the same as `PanoramaWidth` and `PanoramaHeight`\n"
              },
              "scanInfo": {
                "type": "string",
                "nullable": true
              },
              "blobPreview": {
                "$ref": "#/components/schemas/BlobName"
              },
              "urlPreview": {
                "$ref": "#/components/schemas/Url"
              },
              "panoramaWidth": {
                "type": "number",
                "format": "int",
                "description": "The image's *width*, in pixels"
              },
              "panoramaHeight": {
                "type": "number",
                "format": "int",
                "description": "The image's *height*, in pixels"
              },
              "src": {
                "type": "object",
                "nullable": true,
                "description": "Contains metadata usable by the Cintoo Viewer",
                "properties": {
                  "idd": {
                    "type": "object",
                    "nullable": true,
                    "properties": {
                      "scan_id": {
                        "type": "string"
                      },
                      "idd_type": {
                        "type": "string",
                        "example": "Corrosion"
                      }
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "Media": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlob"
          },
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/FileCategoryMedia"
              }
            }
          }
        ]
      },
      "MiscFile": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlob"
          },
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/FileCategoryMiscFile"
              }
            }
          }
        ]
      },
      "Model": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlob"
          },
          {
            "$ref": "#/components/schemas/FileImported"
          },
          {
            "$ref": "#/components/schemas/FileTransformable"
          },
          {
            "type": "object",
            "required": [
              "type",
              "translation"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/FileCategoryModel"
              },
              "translation": {},
              "src": {
                "description": "Metadata attached to the model. Could be present or not.",
                "anyOf": [
                  {
                    "type": "object",
                    "description": "Contains metadata usable by the Cintoo Viewer",
                    "nullable": true
                  },
                  {
                    "type": "object",
                    "properties": {
                      "mfi": {
                        "type": "object",
                        "description": "The MFI location and its format",
                        "required": [
                          "blobName",
                          "format"
                        ],
                        "properties": {
                          "blobName": {
                            "$ref": "#/components/schemas/BlobName"
                          },
                          "format": {
                            "enum": [
                              "json-br-1"
                            ],
                            "description": "the format of the Model MFI"
                          }
                        }
                      }
                    }
                  }
                ]
              }
            }
          }
        ]
      },
      "ModelReport": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlobOptional"
          },
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/FileCategoryModelReport"
              },
              "src": {
                "$ref": "#/components/schemas/FileSrcModelReports"
              }
            }
          }
        ]
      },
      "Scan": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlob"
          },
          {
            "$ref": "#/components/schemas/FileImported"
          },
          {
            "$ref": "#/components/schemas/FileTransformable"
          },
          {
            "type": "object",
            "required": [
              "type",
              "translation",
              "rotation",
              "resolution",
              "blobPreview",
              "urlPreview",
              "panoramaWidth",
              "panoramaHeight",
              "azimuthLeft",
              "azimuthRight",
              "elevationTop",
              "elevationBottom",
              "appliedScaleFactor"
            ],
            "properties": {
              "translation": {},
              "rotation": {},
              "type": {
                "$ref": "#/components/schemas/FileCategoryScan"
              },
              "resolution": {
                "type": "object",
                "allOf": [
                  {
                    "$ref": "#/components/schemas/Dimension2d"
                  }
                ],
                "description": "The scan's resolution: has a `w` and a `h`, respectively for *width* and *height*. This is not the same as `PanoramaWidth` and `PanoramaHeight`\n"
              },
              "scanInfo": {
                "type": "string",
                "nullable": true
              },
              "blobPreview": {
                "$ref": "#/components/schemas/BlobName"
              },
              "urlPreview": {
                "$ref": "#/components/schemas/Url"
              },
              "panoramaWidth": {
                "type": "number",
                "format": "int",
                "description": "The image's *width*, in pixels"
              },
              "panoramaHeight": {
                "type": "number",
                "format": "int",
                "description": "The image's *height*, in pixels"
              },
              "azimuthLeft": {
                "type": "number",
                "format": "float",
                "description": "The max left angle of a scan coverage on the azimuth, in radians.\nFor instance, a scan with 360 degrees coverage will have -π if the `azimuthLeft` is π\n"
              },
              "azimuthRight": {
                "type": "number",
                "format": "float",
                "description": "The max right angle of a scan coverage on the azimuth, in radians.\nFor instance, a scan with 360 degrees coverage will have π if the `azimuthRight` is -π\n"
              },
              "elevationTop": {
                "type": "number",
                "format": "float",
                "description": "The max top angle of a scan coverage on the elevation, in radians. For example, a scan with 180 degrees coverage will have π/2 if the `elevationBottom` is -π/2\n"
              },
              "elevationBottom": {
                "type": "number",
                "format": "float",
                "description": "The max bottom angle of a scan coverage on the elevation, in radians. For example, a scan with 180 degrees coverage will have -π/2 if the `elevationTop` is π/2\n"
              },
              "appliedScaleFactor": {
                "type": "number",
                "format": "int",
                "description": "Scale value applied while the scans are imported through Cintoo Connect. Mainly used for conversion unit between imperial system and metric system.\n"
              },
              "src": {
                "type": "object",
                "nullable": true,
                "description": "Contains metadata usable by the Cintoo Viewer"
              }
            }
          }
        ]
      },
      "SiteMap": {
        "allOf": [
          {
            "$ref": "#/components/schemas/FileBase"
          },
          {
            "$ref": "#/components/schemas/FileBlob"
          },
          {
            "type": "object",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "$ref": "#/components/schemas/FileCategorySiteMap"
              }
            }
          }
        ]
      },
      "FileCategoryGeoImage": {
        "type": "string",
        "enum": [
          "geoImage"
        ],
        "description": "Geo Image files: `.idd`, `.360`"
      },
      "FileCategoryModel": {
        "type": "string",
        "enum": [
          "model"
        ],
        "description": "Model files: `.3ds`, `.dae`, `.dxf`, `.ifc`, `.dwg`, `.rvt`, etc."
      },
      "FileCategoryScan": {
        "type": "string",
        "enum": [
          "scan"
        ],
        "description": "Scan files: `.fls`, `.e57`, etc."
      },
      "FileCategoryModelReport": {
        "type": "string",
        "enum": [
          "modelReport"
        ],
        "description": "Model report files: `.cipm`"
      },
      "FileCategoryDocument": {
        "type": "string",
        "enum": [
          "document"
        ],
        "description": "Document files: `.doc[x]`, `.xls[x]`, `.ppt[x]`, `.txt`, `.rtf`, `.odt`, `.pdt`, `.pub`, `.csv`"
      },
      "FileCategoryMedia": {
        "type": "string",
        "enum": [
          "media"
        ],
        "description": "Media files: `.png`, `.jp[e]g`, `.gif`, `.bmp`, `.tiff`"
      },
      "FileCategoryMiscFile": {
        "type": "string",
        "enum": [
          "miscfile"
        ],
        "description": "Any other type of files"
      },
      "FileCategoryArchive": {
        "type": "string",
        "enum": [
          "archive"
        ],
        "description": "Archive files: `zip`"
      },
      "FileCategorySiteMap": {
        "type": "string",
        "enum": [
          "sitemap"
        ],
        "description": "Site Map files: `.map`"
      },
      "FileCategoryVideo3d": {
        "type": "string",
        "enum": [
          "video3d"
        ],
        "description": "Video3d files: `.mp4`"
      },
      "FileCategoryGaussian": {
        "type": "string",
        "enum": [
          "gaussian"
        ],
        "description": "Gaussian Splatting files: `.ply`, `.spz`"
      },
      "FileCategory": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/FileCategoryGeoImage"
          },
          {
            "$ref": "#/components/schemas/FileCategoryModel"
          },
          {
            "$ref": "#/components/schemas/FileCategoryScan"
          },
          {
            "$ref": "#/components/schemas/FileCategoryModelReport"
          },
          {
            "$ref": "#/components/schemas/FileCategoryDocument"
          },
          {
            "$ref": "#/components/schemas/FileCategoryMedia"
          },
          {
            "$ref": "#/components/schemas/FileCategoryMiscFile"
          },
          {
            "$ref": "#/components/schemas/FileCategoryArchive"
          },
          {
            "$ref": "#/components/schemas/FileCategorySiteMap"
          },
          {
            "$ref": "#/components/schemas/FileCategoryVideo3d"
          },
          {
            "$ref": "#/components/schemas/FileCategoryGaussian"
          }
        ]
      },
      "FileId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "FormatUrn": {
        "type": "string",
        "description": "\"urn:cintoo:format:\" followed by a number\n"
      },
      "FileBase": {
        "type": "object",
        "required": [
          "id",
          "type",
          "api1Id",
          "projectId",
          "workzoneId",
          "name",
          "formatId",
          "size",
          "createdAt",
          "createdBy",
          "updatedAt",
          "updatedBy"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/FileUrn"
          },
          "type": {
            "$ref": "#/components/schemas/FileCategory"
          },
          "api1Id": {
            "$ref": "#/components/schemas/FileId"
          },
          "projectId": {
            "$ref": "#/components/schemas/ProjectUrn"
          },
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "name": {
            "type": "string",
            "example": "fileName"
          },
          "formatId": {
            "$ref": "#/components/schemas/FormatUrn"
          },
          "size": {
            "type": "number",
            "format": "int",
            "minimum": 0,
            "description": "File size in Bytes"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "updatedAt": {
            "type": "string",
            "allOf": [
              {
                "$ref": "#/components/schemas/DateTime"
              }
            ],
            "nullable": true
          },
          "updatedBy": {
            "type": "string",
            "allOf": [
              {
                "$ref": "#/components/schemas/UserUrn"
              }
            ],
            "nullable": true
          }
        }
      },
      "FileBlob": {
        "type": "object",
        "required": [
          "blob",
          "blobName",
          "url"
        ],
        "properties": {
          "blob": {
            "type": "string",
            "deprecated": true,
            "description": "use `blobName` instead. `blob` will be removed the 1st of november 2025",
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ]
          },
          "blobName": {
            "$ref": "#/components/schemas/BlobName"
          },
          "url": {
            "$ref": "#/components/schemas/Url"
          }
        }
      },
      "FileImported": {
        "type": "object",
        "required": [
          "importedAt"
        ],
        "properties": {
          "importedAt": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/DateTime"
              }
            ]
          }
        }
      },
      "Vector3D": {
        "type": "object",
        "required": [
          "x",
          "y",
          "z"
        ],
        "properties": {
          "x": {
            "type": "number",
            "format": "double"
          },
          "y": {
            "type": "number",
            "format": "double"
          },
          "z": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "Quaternion": {
        "type": "object",
        "required": [
          "x",
          "y",
          "z",
          "w"
        ],
        "properties": {
          "x": {
            "type": "number",
            "format": "float"
          },
          "y": {
            "type": "number",
            "format": "float"
          },
          "z": {
            "type": "number",
            "format": "float"
          },
          "w": {
            "type": "number",
            "format": "float"
          }
        }
      },
      "FilePlaced": {
        "type": "object",
        "required": [
          "translation",
          "rotation"
        ],
        "properties": {
          "translation": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Vector3D"
              }
            ],
            "description": "A vector representing the position of the image in the Workzone,\nwith three components in meter: `x`, `y` and `z`\n"
          },
          "rotation": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Quaternion"
              }
            ],
            "description": "A quaternion representing the rotation of the image,\nwith the pivot point being its current position defined by translation.\nIt has four components: `x`, `y`, `z` and `w`\n",
            "nullable": true
          }
        }
      },
      "Dimension2d": {
        "type": "object",
        "required": [
          "w",
          "h"
        ],
        "properties": {
          "w": {
            "type": "integer"
          },
          "h": {
            "type": "integer"
          }
        }
      },
      "FileTransformable": {
        "type": "object",
        "properties": {
          "translation": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Vector3D"
              }
            ],
            "description": "A vector representing the position in the Workzone,\nwith three components in meter: `x`, `y` and `z`\n",
            "nullable": true
          },
          "rotation": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Quaternion"
              }
            ],
            "description": "A quaternion representing the rotation,\nwith the pivot point being its current position defined by translation.\nIt has four components: `x`, `y`, `z` and `w`\n",
            "nullable": true
          },
          "scale": {
            "type": "object",
            "allOf": [
              {
                "$ref": "#/components/schemas/Vector3D"
              }
            ],
            "description": "A vector representing a scale deformation along the three axis\nwith three ratio components : `x`, `y` and `z`\n",
            "nullable": true
          }
        }
      },
      "FileBlobOptional": {
        "type": "object",
        "properties": {
          "blob": {
            "type": "string",
            "nullable": true,
            "deprecated": true,
            "description": "use `blobName` instead. `blob` will be removed the 1st of november 2025",
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ]
          },
          "blobName": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ]
          },
          "url": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/Url"
              }
            ]
          }
        }
      },
      "FileSrcModelReports": {
        "type": "object",
        "required": [
          "model",
          "elements",
          "scans",
          "tolerance"
        ],
        "properties": {
          "model": {
            "$ref": "#/components/schemas/FileUrn"
          },
          "elements": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "scans": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FileUrn"
            }
          },
          "tolerance": {
            "type": "number"
          }
        }
      },
      "File": {
        "type": "object",
        "x-tags": [
          "File"
        ],
        "oneOf": [
          {
            "$ref": "#/components/schemas/Archive"
          },
          {
            "$ref": "#/components/schemas/Document"
          },
          {
            "$ref": "#/components/schemas/GeoImage"
          },
          {
            "$ref": "#/components/schemas/Media"
          },
          {
            "$ref": "#/components/schemas/MiscFile"
          },
          {
            "$ref": "#/components/schemas/Model"
          },
          {
            "$ref": "#/components/schemas/ModelReport"
          },
          {
            "$ref": "#/components/schemas/Scan"
          },
          {
            "$ref": "#/components/schemas/SiteMap"
          }
        ],
        "discriminator": {
          "propertyName": "type",
          "mapping": {
            "archive": "#/components/schemas/Archive",
            "document": "#/components/schemas/Document",
            "geoImage": "#/components/schemas/GeoImage",
            "media": "#/components/schemas/Media",
            "miscfile": "#/components/schemas/MiscFile",
            "model": "#/components/schemas/Model",
            "modelReport": "#/components/schemas/ModelReport",
            "scan": "#/components/schemas/Scan",
            "sitemap": "#/components/schemas/SiteMap"
          }
        }
      },
      "fileUpdate": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minimum": 1,
            "maximum": 255,
            "description": "New name for the file"
          }
        }
      },
      "filesTransformationUpdate": {
        "type": "array",
        "items": {
          "allOf": [
            {
              "$ref": "#/components/schemas/FileTransformable"
            },
            {
              "type": "object",
              "required": [
                "id"
              ],
              "properties": {
                "id": {
                  "$ref": "#/components/schemas/FileUrn"
                }
              }
            }
          ]
        }
      },
      "ShareLinkUrn": {
        "type": "string",
        "description": "\"urn:cintoo:sharelink:\" followed by a string\n"
      },
      "ShareLinkOptions": {
        "type": "object",
        "required": [
          "workzones",
          "notes",
          "issues",
          "measurements",
          "crops",
          "tags"
        ],
        "x-tags": [
          "Share Link"
        ],
        "properties": {
          "workzones": {
            "type": "boolean",
            "description": "when enabled, multiple work zones are shared if specified in `sharedWorkzonesIds`"
          },
          "notes": {
            "type": "boolean",
            "description": "when enabled, annotations of type NOTE are visible using the share link"
          },
          "issues": {
            "type": "boolean",
            "description": "when enabled, annotations of type ISSUE or RESOLVED are visible using the share link"
          },
          "measurements": {
            "type": "boolean",
            "description": "when enabled, measurements are visible using the share link"
          },
          "crops": {
            "type": "boolean",
            "description": "when enabled, crops are visible using the share link"
          },
          "tags": {
            "type": "boolean",
            "description": "when enabled, tags are visible using the share link"
          }
        }
      },
      "SavedViewData": {
        "oneOf": [
          {
            "type": "object",
            "title": "legacy",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "legacy"
                ],
                "description": "internal legacy representation, do not use (subject to changes and deprecation)"
              }
            }
          },
          {
            "type": "object",
            "title": "others",
            "required": [
              "type"
            ],
            "properties": {
              "type": {
                "type": "string",
                "description": "structure will be defined in the future"
              }
            },
            "additionalProperties": true
          }
        ]
      },
      "ShareLink": {
        "type": "object",
        "required": [
          "id",
          "type",
          "name",
          "link",
          "workzoneId",
          "sharedWorkzonesIds",
          "createdBy",
          "createdAt",
          "expiresAt",
          "passwordProtected",
          "membershipRequired",
          "shareOptions",
          "logoBlob",
          "savedView"
        ],
        "x-tags": [
          "Share Link"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/ShareLinkUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "sharelink"
            ]
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "link": {
            "type": "string"
          },
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "sharedWorkzonesIds": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WorkzoneUrn"
            },
            "description": "list of additional shared work zones (only if `workzones` is enabled in the `shareOptions`)"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "expiresAt": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DateTime"
              }
            ],
            "type": "string",
            "nullable": true
          },
          "passwordProtected": {
            "type": "boolean",
            "description": "Indicates if the share link will require a password to be supplied"
          },
          "membershipRequired": {
            "type": "boolean",
            "description": "Indicates if the user must be already logged in to use the share link"
          },
          "shareOptions": {
            "$ref": "#/components/schemas/ShareLinkOptions"
          },
          "logoBlob": {
            "type": "string",
            "nullable": true
          },
          "savedView": {
            "$ref": "#/components/schemas/SavedViewData"
          }
        }
      },
      "ShareLinkPassword": {
        "type": "string",
        "description": "Password must be at least 12 characters long and contain at least 3 of the following:\nuppercase, lowercase, digit, special characters, or be at least 24 characters long with no\ncharacter set constraints\n"
      },
      "shareLinkCreate": {
        "type": "object",
        "required": [
          "name",
          "workzoneId",
          "membershipRequired",
          "shareOptions"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "sharedWorkzonesIds": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/WorkzoneUrn"
            },
            "description": "Additional work zones to share.\nThis is taken into account only if `workzones` is enabled in `shareOptions`.\n"
          },
          "password": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ShareLinkPassword"
              }
            ],
            "type": "string",
            "nullable": true
          },
          "expiresAt": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DateTime"
              }
            ],
            "type": "string",
            "nullable": true
          },
          "logoBlob": {
            "type": "string",
            "nullable": true
          },
          "membershipRequired": {
            "type": "boolean",
            "description": "Indicates if the user must be already logged in to use the share link"
          },
          "shareOptions": {
            "$ref": "#/components/schemas/ShareLinkOptions"
          },
          "savedView": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SavedViewData"
              }
            ],
            "type": "object",
            "nullable": true
          }
        }
      },
      "shareLinkUpdate": {
        "type": "object",
        "required": [
          "name",
          "sharedWorkzonesIds",
          "password",
          "expiresAt",
          "logoBlob",
          "membershipRequired",
          "shareOptions",
          "savedView"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "sharedWorkzonesIds": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/WorkzoneUrn"
            },
            "description": "Additional work zones to share.\nThis is taken into account only if `workzones` is enabled in `shareOptions`.\n"
          },
          "password": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ShareLinkPassword"
              }
            ],
            "type": "string",
            "nullable": true
          },
          "expiresAt": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DateTime"
              }
            ],
            "type": "string",
            "nullable": true
          },
          "logoBlob": {
            "type": "string",
            "nullable": true
          },
          "membershipRequired": {
            "type": "boolean",
            "description": "Indicates if the user must be already logged in to use the share link"
          },
          "shareOptions": {
            "$ref": "#/components/schemas/ShareLinkOptions"
          },
          "savedView": {
            "allOf": [
              {
                "$ref": "#/components/schemas/SavedViewData"
              }
            ],
            "type": "object",
            "nullable": true
          }
        }
      },
      "bulk-files": {
        "type": "object",
        "required": [
          "name",
          "extension",
          "size",
          "md5"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minimum": 1,
            "maximum": 255
          },
          "extension": {
            "type": "string"
          },
          "size": {
            "type": "integer"
          },
          "md5": {
            "type": "string"
          }
        }
      },
      "ProjectRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/ProjectUrn"
          },
          {
            "$ref": "#/components/schemas/ProjectId"
          }
        ]
      },
      "AnnotationUrn": {
        "type": "string",
        "description": "\"urn:cintoo:annotation:\" followed by an UUIDv4\n"
      },
      "Point3D": {
        "type": "object",
        "required": [
          "x",
          "y",
          "z"
        ],
        "properties": {
          "x": {
            "type": "number",
            "format": "double"
          },
          "y": {
            "type": "number",
            "format": "double"
          },
          "z": {
            "type": "number",
            "format": "double"
          }
        }
      },
      "AnnotationCommentUrn": {
        "type": "string",
        "description": "\"urn:cintoo:annotation-comment:\" followed by an UUIDv4\n"
      },
      "AnnotationCommentAttachmentUrn": {
        "type": "string",
        "description": "\"urn:cintoo:annotation-comment-attachment:\" followed by an UUIDv4\n"
      },
      "FileAttribute": {
        "type": "object",
        "properties": {
          "id": {
            "$ref": "#/components/schemas/FileUrn"
          },
          "size": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "formatId": {
            "$ref": "#/components/schemas/FormatUrn"
          },
          "blob": {
            "$ref": "#/components/schemas/BlobName"
          }
        }
      },
      "AnnotationCommentAttachment": {
        "type": "object",
        "required": [
          "id",
          "type"
        ],
        "x-tags": [
          "Annotation"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/AnnotationCommentAttachmentUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "annotation-comment-attachment"
            ]
          },
          "attachedTo": {
            "$ref": "#/components/schemas/AnnotationCommentUrn"
          },
          "file": {
            "$ref": "#/components/schemas/FileAttribute"
          }
        }
      },
      "AnnotationComment": {
        "type": "object",
        "required": [
          "id",
          "type",
          "modificationInfo"
        ],
        "x-tags": [
          "Annotation"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/AnnotationCommentUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "annotation-comment"
            ]
          },
          "modificationInfo": {
            "$ref": "#/components/schemas/ModificationInfo"
          },
          "attachedTo": {
            "$ref": "#/components/schemas/AnnotationUrn"
          },
          "description": {
            "type": "string"
          },
          "descriptionText": {
            "type": "string"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnnotationCommentAttachment"
            }
          }
        }
      },
      "AnnotationAttachmentUrn": {
        "type": "string",
        "description": "\"urn:cintoo:annotation-attachment:\" followed by an UUIDv4\n"
      },
      "AnnotationAttachment": {
        "type": "object",
        "required": [
          "id",
          "type"
        ],
        "x-tags": [
          "Annotation"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/AnnotationAttachmentUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "annotation-attachment"
            ]
          },
          "attachedTo": {
            "$ref": "#/components/schemas/AnnotationUrn"
          },
          "file": {
            "$ref": "#/components/schemas/FileAttribute"
          }
        }
      },
      "AnnotationIntegration": {
        "type": "object",
        "required": [
          "type"
        ],
        "x-tags": [
          "Annotation"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "AUTODESK",
              "NEWFORMA_KONEKT",
              "PROCORE"
            ]
          },
          "url": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "Annotation": {
        "type": "object",
        "required": [
          "id",
          "type",
          "workzoneId",
          "modificationInfo",
          "savedView"
        ],
        "x-tags": [
          "Annotation"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/AnnotationUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "annotation"
            ]
          },
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "modificationInfo": {
            "$ref": "#/components/schemas/ModificationInfo"
          },
          "annotationType": {
            "type": "string",
            "enum": [
              "Private note",
              "Note",
              "Issue",
              "Resolved"
            ]
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "descriptionText": {
            "type": "string"
          },
          "assignedTo": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserUrn"
            }
          },
          "dueDate": {
            "$ref": "#/components/schemas/Date"
          },
          "priority": {
            "type": "integer"
          },
          "number": {
            "type": "integer"
          },
          "position": {
            "$ref": "#/components/schemas/Point3D"
          },
          "normal": {
            "$ref": "#/components/schemas/Point3D"
          },
          "imgBlobName": {
            "type": "string"
          },
          "savedView": {
            "$ref": "#/components/schemas/SavedViewData"
          },
          "modelElementGUIDs": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            }
          },
          "comments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnnotationComment"
            }
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnnotationAttachment"
            }
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "integrations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AnnotationIntegration"
            }
          }
        }
      },
      "annotationCreate": {
        "type": "object",
        "required": [
          "workzoneId",
          "annotationType",
          "title",
          "position",
          "savedView"
        ],
        "properties": {
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "annotationType": {
            "type": "string",
            "enum": [
              "Private note",
              "Note",
              "Issue",
              "Resolved"
            ]
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "assignedTo": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserUrn"
            }
          },
          "dueDate": {
            "type": "string",
            "format": "date"
          },
          "priority": {
            "type": "integer",
            "enum": [
              0,
              1,
              5,
              8,
              10
            ]
          },
          "imgBlobName": {
            "type": "string"
          },
          "position": {
            "$ref": "#/components/schemas/Point3D"
          },
          "normal": {
            "$ref": "#/components/schemas/Point3D"
          },
          "savedView": {
            "$ref": "#/components/schemas/SavedViewData"
          },
          "modelElementGUIDs": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            }
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "string",
              "example": "{blobName}"
            },
            "description": "blob names"
          }
        }
      },
      "AnnotationId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "annotationUpdate": {
        "type": "object",
        "required": [
          "annotationType",
          "title",
          "position"
        ],
        "properties": {
          "annotationType": {
            "type": "string",
            "enum": [
              "Private note",
              "Note",
              "Issue",
              "Resolved"
            ]
          },
          "title": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "assignedTo": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UserUrn"
            }
          },
          "dueDate": {
            "type": "string",
            "format": "date"
          },
          "priority": {
            "type": "integer",
            "enum": [
              0,
              1,
              5,
              8,
              10
            ]
          },
          "imgBlobName": {
            "type": "string"
          },
          "position": {
            "$ref": "#/components/schemas/Point3D"
          },
          "normal": {
            "$ref": "#/components/schemas/Point3D"
          },
          "savedView": {
            "$ref": "#/components/schemas/SavedViewData"
          },
          "modelElementGUIDs": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "string"
            }
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "string",
              "example": "{blobName}"
            },
            "description": "blob names"
          }
        }
      },
      "annotationCommentCreate": {
        "type": "object",
        "required": [
          "description"
        ],
        "properties": {
          "description": {
            "type": "string",
            "minLength": 1
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "string",
              "example": "{blobName}"
            },
            "description": "blob names"
          }
        }
      },
      "annotationCreateIntegrationLinks": {
        "type": "object",
        "required": [
          "integrationTypes"
        ],
        "properties": {
          "annotations": {
            "type": "array",
            "description": "If omitted or null, all annotations of the project will be processed.",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/AnnotationUrn"
            }
          },
          "integrationTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "AUTODESK",
                "NEWFORMA_KONEKT",
                "PROCORE"
              ]
            }
          }
        }
      },
      "AnnotationBulkCreateIntegrationLinksResponse": {
        "type": "object",
        "required": [
          "created"
        ],
        "properties": {
          "created": {
            "type": "object",
            "description": "Each key is an annotation URN, values are integration types initialized for the annotation",
            "additionalProperties": {
              "x-additionalPropertiesName": "urn:cintoo:annotation:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "AUTODESK",
                  "NEWFORMA_KONEKT",
                  "PROCORE"
                ]
              }
            },
            "example": {
              "urn:cintoo:annotation:956b7fb8-ad08-4f63-bed2-f958f0bf2e2c": [
                "AUTODESK",
                "PROCORE"
              ],
              "urn:cintoo:annotation:2d90addd-e3fb-4a0c-b54a-af09e17687e2": [
                "NEWFORMA_KONEKT"
              ]
            }
          }
        }
      },
      "ProjectIntegrationKonekt": {
        "type": "object",
        "x-tags": [
          "Konekt"
        ],
        "required": [
          "projectId",
          "hubId",
          "konektId",
          "options",
          "link",
          "createdAt",
          "createdBy",
          "updatedAt",
          "updatedBy"
        ],
        "properties": {
          "projectId": {
            "$ref": "#/components/schemas/ProjectUrn"
          },
          "hubId": {
            "type": "string",
            "description": "id of the hub on Konekt"
          },
          "konektId": {
            "type": "number",
            "description": "id of the project on Konekt"
          },
          "options": {
            "$ref": "#/components/schemas/ProjectIntegrationNewformaKonektOptions"
          },
          "link": {
            "type": "string"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedBy": {
            "$ref": "#/components/schemas/UserUrn"
          }
        }
      },
      "ProjectIntegrationAutodesk": {
        "type": "object",
        "x-tags": [
          "Autodesk"
        ],
        "required": [
          "projectId",
          "autodeskHubId",
          "autodeskProjectId",
          "link",
          "createdAt",
          "createdBy",
          "updatedAt",
          "updatedBy"
        ],
        "properties": {
          "projectId": {
            "$ref": "#/components/schemas/ProjectUrn"
          },
          "autodeskHubId": {
            "type": "string"
          },
          "autodeskProjectId": {
            "type": "string"
          },
          "link": {
            "type": "string"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedBy": {
            "$ref": "#/components/schemas/UserUrn"
          }
        }
      },
      "ProjectIntegrations": {
        "type": "object",
        "properties": {
          "konekt": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectIntegrationKonekt"
              }
            ],
            "type": "object",
            "nullable": true
          },
          "autodesk": {
            "allOf": [
              {
                "$ref": "#/components/schemas/ProjectIntegrationAutodesk"
              }
            ],
            "type": "object",
            "nullable": true
          }
        }
      },
      "projectIntegrationKonektUpdate": {
        "type": "object",
        "required": [
          "hubId",
          "konektProjectId",
          "options"
        ],
        "properties": {
          "hubId": {
            "type": "string",
            "description": "id of the hub on Konekt"
          },
          "konektProjectId": {
            "type": "number",
            "description": "id of the project on Konekt"
          },
          "options": {
            "$ref": "#/components/schemas/ProjectIntegrationNewformaKonektOptions"
          }
        }
      },
      "projectIntegrationKonektCreate": {
        "type": "object",
        "required": [
          "hubId",
          "konektProjectId",
          "options"
        ],
        "properties": {
          "hubId": {
            "type": "string",
            "description": "id of the hub on Konekt"
          },
          "konektProjectId": {
            "type": "number",
            "description": "id of the project on Konekt"
          },
          "options": {
            "$ref": "#/components/schemas/ProjectIntegrationNewformaKonektOptions"
          }
        }
      },
      "projectIntegrationAutodeskUpdate": {
        "type": "object",
        "required": [
          "autodeskHubId",
          "autodeskProjectId"
        ],
        "properties": {
          "autodeskHubId": {
            "type": "string"
          },
          "autodeskProjectId": {
            "type": "string"
          }
        }
      },
      "projectIntegrationAutodeskCreate": {
        "type": "object",
        "required": [
          "autodeskHubId",
          "autodeskProjectId"
        ],
        "properties": {
          "autodeskHubId": {
            "type": "string"
          },
          "autodeskProjectId": {
            "type": "string"
          }
        }
      },
      "CropUrn": {
        "type": "string",
        "description": "\"urn:cintoo:crop:\" followed by an UUIDv4\n"
      },
      "Crop": {
        "type": "object",
        "required": [
          "id",
          "workzoneId",
          "name",
          "crop",
          "actualCrop",
          "rotation",
          "cameraType",
          "cameraState",
          "scan",
          "createdBy",
          "createdAt",
          "updatedBy",
          "updatedAt"
        ],
        "x-tags": [
          "Crop"
        ],
        "properties": {
          "id": {
            "readOnly": true,
            "$ref": "#/components/schemas/CropUrn"
          },
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "name": {
            "type": "string"
          },
          "crop": {
            "type": "string",
            "description": "Description of the plans defining the bounding box of the crop in the scene"
          },
          "actualCrop": {
            "type": "string",
            "description": "Description of the plans defining the bounding box of the crop related to the camera"
          },
          "rotation": {
            "type": "string",
            "description": "Description about the rotation of the crop inside the camera"
          },
          "layers": {
            "type": "string",
            "nullable": true,
            "description": "Scans related to the crop"
          },
          "cameraType": {
            "type": "string",
            "description": "Details about the camera (overview, ground, scan, arcrotate)"
          },
          "cameraState": {
            "type": "string",
            "description": "Description of source and direction of the camera of the scene"
          },
          "scan": {
            "type": "string",
            "description": "root scan for the crop"
          },
          "thumbnailBlobName": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ]
          },
          "thumbnailUrl": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/Url"
              }
            ]
          },
          "oview": {
            "type": "number",
            "nullable": true
          },
          "settings": {
            "type": "string",
            "nullable": true
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          }
        }
      },
      "cropCreate": {
        "type": "object",
        "required": [
          "workzoneId",
          "name",
          "crop",
          "actualCrop",
          "rotation",
          "cameraType",
          "cameraState",
          "scan"
        ],
        "properties": {
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneRef"
          },
          "name": {
            "type": "string"
          },
          "crop": {
            "type": "string",
            "description": "Description of the plans defining the bounding box of the crop in the scene"
          },
          "actualCrop": {
            "type": "string",
            "description": "Description of the plans defining the bounding box of the crop related to the camera"
          },
          "rotation": {
            "type": "string",
            "description": "Description about the rotation of the crop inside the camera"
          },
          "layers": {
            "type": "string",
            "nullable": true,
            "description": "Scans related to the crop"
          },
          "cameraType": {
            "type": "string",
            "description": "Details about the camera (overview, ground, scan, arcrotate)"
          },
          "cameraState": {
            "type": "string",
            "description": "Description of source and direction of the camera of the scene"
          },
          "scan": {
            "type": "string",
            "description": "root scan for the crop"
          },
          "thumbnailBlobName": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ]
          },
          "oview": {
            "type": "number",
            "nullable": true
          },
          "settings": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "CropId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "cropUpdate": {
        "type": "object",
        "required": [
          "workzoneId",
          "name",
          "crop",
          "actualCrop",
          "rotation",
          "cameraType",
          "cameraState",
          "scan"
        ],
        "properties": {
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneRef"
          },
          "name": {
            "type": "string"
          },
          "crop": {
            "type": "string",
            "description": "Description of the plans defining the bounding box of the crop in the scene"
          },
          "actualCrop": {
            "type": "string",
            "description": "Description of the plans defining the bounding box of the crop related to the camera"
          },
          "rotation": {
            "type": "string",
            "description": "Description about the rotation of the crop inside the camera"
          },
          "layers": {
            "type": "string",
            "nullable": true,
            "description": "Scans related to the crop"
          },
          "cameraType": {
            "type": "string",
            "description": "Details about the camera (overview, ground, scan, arcrotate)"
          },
          "cameraState": {
            "type": "string",
            "description": "Description of source and direction of the camera of the scene"
          },
          "scan": {
            "type": "string",
            "description": "root scan for the crop"
          },
          "thumbnailBlobName": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ]
          },
          "oview": {
            "type": "number",
            "nullable": true
          },
          "settings": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "MeasurementUrn": {
        "type": "string",
        "description": "\"urn:cintoo:measurement:\" followed by an UUIDv4\n"
      },
      "Vector3": {
        "type": "array",
        "minItems": 3,
        "maxItems": 3,
        "items": {
          "type": "number"
        }
      },
      "Vector4": {
        "type": "array",
        "minItems": 4,
        "maxItems": 4,
        "items": {
          "type": "number"
        }
      },
      "TagDataCameraState": {
        "title": "Camera State",
        "type": "object",
        "properties": {
          "position": {
            "$ref": "#/components/schemas/Vector3"
          },
          "target": {
            "$ref": "#/components/schemas/Vector3"
          },
          "rotation": {
            "$ref": "#/components/schemas/Vector3"
          },
          "overviewAngle": {
            "type": "string",
            "maxLength": 10
          },
          "viewDirection": {
            "type": "string",
            "maxLength": 10
          },
          "rotationQuaternion": {
            "$ref": "#/components/schemas/Vector4"
          },
          "fov": {
            "type": "number"
          },
          "overviewScale": {
            "type": "number"
          },
          "ortho": {
            "type": "boolean"
          },
          "camType": {
            "type": "string",
            "maxLength": 10
          }
        },
        "additionalProperties": false
      },
      "Measurement": {
        "type": "object",
        "required": [
          "id",
          "type",
          "workzoneId",
          "name"
        ],
        "x-tags": [
          "Measurement"
        ],
        "properties": {
          "id": {
            "type": "string",
            "$ref": "#/components/schemas/MeasurementUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "measurement"
            ]
          },
          "workzoneId": {
            "type": "string",
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "name": {
            "description": "The name of the measurement",
            "type": "string"
          },
          "startPoint": {
            "type": "object",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/Point3D"
              }
            ]
          },
          "endPoint": {
            "type": "object",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/Point3D"
              }
            ]
          },
          "length": {
            "type": "number",
            "nullable": true,
            "format": "double"
          },
          "height": {
            "type": "number",
            "nullable": true,
            "format": "double"
          },
          "width": {
            "type": "number",
            "nullable": true,
            "format": "double"
          },
          "thumbnailBlobName": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/BlobName"
              }
            ]
          },
          "cameraState": {
            "type": "object",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/TagDataCameraState"
              }
            ]
          },
          "scanId": {
            "description": "Reference to the scan which has been used for this measurement",
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/FileUrn"
              }
            ]
          },
          "createdAt": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/DateTime"
              }
            ]
          },
          "createdBy": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/UserUrn"
              }
            ]
          },
          "isDeleted": {
            "type": "boolean"
          },
          "deletedAt": {
            "type": "string",
            "nullable": true,
            "allOf": [
              {
                "$ref": "#/components/schemas/DateTime"
              }
            ]
          }
        }
      },
      "TagListUrn": {
        "type": "string",
        "description": "\"urn:cintoo:tag-list:\" followed by an UUIDv4\n"
      },
      "TagListMetadataDefinition": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100,
            "pattern": "^[^\\s](.*[^\\s])?$",
            "description": "must not start or end with a space, forbidden keywords are:\n- \"id\"\n- \"description\"\n- \"cameraState\"\n- \"model\"\n- \"x\"\n- \"y\"\n- \"z\"\n- \"size\"\n- \"xMin\"\n- \"xMax\"\n- \"yMin\"\n- \"yMax\"\n- \"zMin\"\n- \"zMax\"\n- \"scanUuids\"\n- \"subId\"\n- \"nature\"\n- \"confidence\"\n- \"needValidation\"\n",
            "not": {
              "enum": [
                "id",
                "description",
                "cameraState",
                "model",
                "x",
                "y",
                "z",
                "size",
                "xMin",
                "xMax",
                "yMin",
                "yMax",
                "zMin",
                "zMax",
                "scanUuids",
                "subId",
                "nature",
                "confidence",
                "needValidation"
              ]
            }
          }
        }
      },
      "TagListAttachment": {
        "type": "object",
        "required": [
          "id",
          "name",
          "pages"
        ],
        "properties": {
          "id": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "blob": {
            "type": "string"
          },
          "pages": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "index"
              ],
              "properties": {
                "id": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "index": {
                  "type": "integer"
                },
                "scale": {
                  "type": "number"
                },
                "width": {
                  "type": "number"
                },
                "height": {
                  "type": "number"
                },
                "name": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 256
                },
                "hidden": {
                  "type": "boolean"
                }
              }
            }
          }
        }
      },
      "TagList": {
        "type": "object",
        "x-tags": [
          "Tag List"
        ],
        "required": [
          "id",
          "type",
          "workzoneId",
          "tagListType",
          "name",
          "description",
          "color",
          "metadataDefinition",
          "pending",
          "createdBy",
          "createdAt",
          "updatedBy",
          "updatedAt",
          "tagsVersion"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/TagListUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "tag-list"
            ]
          },
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneUrn"
          },
          "tagListType": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "description": {
            "type": "string",
            "maxLength": 1000
          },
          "color": {
            "type": "string",
            "maxLength": 20
          },
          "metadataDefinition": {
            "type": "array",
            "minItems": 0,
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/TagListMetadataDefinition"
            },
            "description": "Defines for each metadata id a displayable name.\nNote that tags inside the list may have metadata not defined in the list, but only those defined on the\nlist will be displayed on the webapp.\n"
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagListAttachment"
            }
          },
          "pending": {
            "type": "boolean"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "tagsVersion": {
            "type": "integer"
          }
        }
      },
      "tagListCreate": {
        "type": "object",
        "required": [
          "workzoneId",
          "tagListType",
          "name"
        ],
        "properties": {
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneRef"
          },
          "tagListType": {
            "type": "string",
            "minLength": 1,
            "maxLength": 36,
            "description": "The tag list type determines how to display and handle it on the webapp. Currently only `2d` and `3d` are\nsupported by the webapp.\n"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "description": {
            "type": "string",
            "maxLength": 1000,
            "nullable": true
          },
          "color": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "metadataDefinition": {
            "type": "array",
            "nullable": true,
            "minItems": 0,
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/TagListMetadataDefinition"
            }
          },
          "attachments": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/TagListAttachment"
            }
          }
        }
      },
      "TagListId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "TagListRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/TagListUrn"
          },
          {
            "$ref": "#/components/schemas/TagListId"
          }
        ]
      },
      "tagListUpdate": {
        "type": "object",
        "required": [
          "workzoneId",
          "tagListType",
          "name"
        ],
        "properties": {
          "workzoneId": {
            "$ref": "#/components/schemas/WorkzoneRef"
          },
          "tagListType": {
            "type": "string",
            "minLength": 1,
            "maxLength": 36,
            "description": "The tag list type determines how to display and handle it on the webapp. Currently only `2d` and `3d` are\nsupported by the webapp.\n"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "description": {
            "type": "string",
            "maxLength": 1000,
            "nullable": true
          },
          "color": {
            "type": "string",
            "maxLength": 20,
            "nullable": true
          },
          "metadataDefinition": {
            "type": "array",
            "nullable": true,
            "minItems": 0,
            "maxItems": 50,
            "items": {
              "$ref": "#/components/schemas/TagListMetadataDefinition"
            }
          },
          "attachments": {
            "type": "array",
            "nullable": true,
            "items": {
              "$ref": "#/components/schemas/TagListAttachment"
            }
          }
        }
      },
      "FileRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/FileUrn"
          },
          {
            "$ref": "#/components/schemas/FileId"
          }
        ]
      },
      "TagUrn": {
        "type": "string",
        "description": "\"urn:cintoo:tag:\" followed by an UUIDv4\n"
      },
      "TagBoundingBox": {
        "title": "Bounding Box",
        "description": "[xMin, yMin, zMin, xMax, yMax, zMax]:\n* (xMin, yMin, zMin) min position\n* (xMax, yMax, zMax) max position\n",
        "type": "array",
        "minItems": 6,
        "maxItems": 6,
        "items": {
          "type": "number",
          "format": "float"
        }
      },
      "TagOrientedBoundingBox": {
        "title": "Oriented Bounding Box",
        "description": "[xPos, yPos, zPos, xQuat, yQuat, zQuat, wQuat, xScale, yScale, zScale]:\n* (xPos, yPos, zPos) position of the center of the box, in meters\n* (xQuat, yQuat, zQuat, wQuat) rotation (as a quaternion) of the box, using the center of the box as a pivot\n* (xScale, yScale, zScale) scale of the box, in meters\n",
        "type": "array",
        "minItems": 10,
        "maxItems": 10,
        "items": {
          "type": "number",
          "format": "float"
        }
      },
      "TagDataModelAxisAlignedList": {
        "title": "Tag Data Model Using Bounding Box List",
        "type": "object",
        "required": [
          "type",
          "list"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "AxisAlignedList"
            ]
          },
          "list": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagBoundingBox"
            },
            "minItems": 2,
            "maxItems": 1000
          }
        },
        "additionalProperties": false
      },
      "TagDataModelBinarizedAxisAlignedList": {
        "title": "Tag Data Model Using Binary Bounding Box List",
        "type": "object",
        "required": [
          "type",
          "binary"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "BinarizedAxisAlignedList"
            ]
          },
          "binary": {
            "type": "string",
            "maxLength": 32000
          }
        },
        "additionalProperties": false
      },
      "TagSharedOrientedBoundingBox": {
        "title": "Tag Oriented Bounding Box List With Shared Orientation",
        "type": "array",
        "minItems": 16,
        "maxItems": 505,
        "items": {
          "type": "number"
        }
      },
      "TagDataModelOrientedList": {
        "title": "Tag Data Model Using Oriented Bounding Box List",
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "OrientedList"
            ]
          },
          "list": {
            "type": "array",
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/TagBoundingBox"
            }
          },
          "groupedOBBList": {
            "type": "array",
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/TagSharedOrientedBoundingBox"
            }
          },
          "orientedBoundingBoxList": {
            "type": "array",
            "maxItems": 500,
            "items": {
              "$ref": "#/components/schemas/TagOrientedBoundingBox"
            }
          }
        }
      },
      "TagDataModel2DKonva": {
        "title": "Tag 2d Data Model Using Konva Shapes",
        "type": "object",
        "required": [
          "type",
          "data"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "konva"
            ]
          },
          "data": {
            "type": "string"
          }
        }
      },
      "TagDataNature": {
        "title": "Tag Data Nature",
        "type": "string",
        "enum": [
          "AI",
          "file",
          "manual",
          "model"
        ]
      },
      "TagDataCustomFields": {
        "title": "Tag Data Custom Fields",
        "type": "array",
        "minItems": 0,
        "maxItems": 10,
        "items": {
          "type": "object",
          "properties": {
            "name": {
              "type": "string",
              "maxLength": 50
            },
            "value": {
              "type": "string",
              "maxLength": 1000
            }
          },
          "required": [
            "name",
            "value"
          ],
          "additionalProperties": false
        }
      },
      "TagDataMetadata": {
        "title": "Tag Data Metadata",
        "type": "array",
        "minItems": 0,
        "maxItems": 50,
        "items": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256,
              "description": "Id of the metadata.\nIt is not mandatory that the id exist on the tag list, however only those defined on the tag list\nwill be displayed on the webapp.\n"
            },
            "value": {
              "type": "string",
              "maxLength": 1000
            }
          },
          "required": [
            "id",
            "value"
          ],
          "additionalProperties": false
        }
      },
      "TagData": {
        "title": "Tag Data",
        "description": "For more information about how the geometry of a tag is represented, see the dedicated section [Understand Tag Data](#tag/understand_tag_data)",
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "description": "Tag external ID, reference of the tag. Displayed in TagList",
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "subId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "uuid": {
            "$ref": "#/components/schemas/Uuid"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 50
          },
          "pageId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "pageLinkId": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256
          },
          "tagLinkIds": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 256
            }
          },
          "boundingBox": {
            "$ref": "#/components/schemas/TagBoundingBox"
          },
          "orientedBoundingBox": {
            "$ref": "#/components/schemas/TagOrientedBoundingBox"
          },
          "model": {
            "anyOf": [
              {
                "$ref": "#/components/schemas/TagDataModelAxisAlignedList"
              },
              {
                "$ref": "#/components/schemas/TagDataModelBinarizedAxisAlignedList"
              },
              {
                "$ref": "#/components/schemas/TagDataModelOrientedList"
              },
              {
                "$ref": "#/components/schemas/TagDataModel2DKonva"
              }
            ]
          },
          "class": {
            "type": "string",
            "maxLength": 50,
            "example": "pump"
          },
          "cameraState": {
            "$ref": "#/components/schemas/TagDataCameraState"
          },
          "unit": {
            "type": "number"
          },
          "functionalSystem": {
            "type": "string",
            "maxLength": 50
          },
          "description": {
            "type": "string",
            "maxLength": 1000
          },
          "url": {
            "type": "string",
            "maxLength": 1000,
            "format": "uri"
          },
          "confidence": {
            "type": "number",
            "format": "float"
          },
          "scanUuids": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Uuid"
            }
          },
          "needValidation": {
            "type": "boolean"
          },
          "nature": {
            "$ref": "#/components/schemas/TagDataNature"
          },
          "customFields": {
            "$ref": "#/components/schemas/TagDataCustomFields"
          },
          "metadata": {
            "$ref": "#/components/schemas/TagDataMetadata"
          }
        },
        "additionalProperties": false
      },
      "Tag": {
        "type": "object",
        "x-tags": [
          "Tag"
        ],
        "required": [
          "id",
          "type",
          "tagListId",
          "tagListType",
          "createdBy",
          "createdAt",
          "updatedBy",
          "updatedAt",
          "isDeleted",
          "deletedBy",
          "deletedAt",
          "tagsVersion",
          "data"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/TagUrn"
          },
          "type": {
            "type": "string",
            "enum": [
              "tag"
            ]
          },
          "tagListId": {
            "$ref": "#/components/schemas/TagListUrn"
          },
          "tagListType": {
            "type": "string"
          },
          "createdBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "createdAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "updatedBy": {
            "$ref": "#/components/schemas/UserUrn"
          },
          "updatedAt": {
            "$ref": "#/components/schemas/DateTime"
          },
          "isDeleted": {
            "type": "boolean"
          },
          "deletedBy": {
            "allOf": [
              {
                "$ref": "#/components/schemas/UserUrn"
              }
            ],
            "type": "string",
            "nullable": true
          },
          "deletedAt": {
            "allOf": [
              {
                "$ref": "#/components/schemas/DateTime"
              }
            ],
            "type": "string",
            "nullable": true
          },
          "tagsVersion": {
            "type": "integer"
          },
          "data": {
            "$ref": "#/components/schemas/TagData"
          }
        }
      },
      "TagId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Uuid"
          }
        ],
        "example": "8196e320-8a4d-4d29-b0a9-077cd7ed3368"
      },
      "TagRef": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/TagUrn"
          },
          {
            "$ref": "#/components/schemas/TagId"
          }
        ]
      },
      "tagsBulkRequest": {
        "type": "object",
        "properties": {
          "create": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "data"
              ],
              "properties": {
                "data": {
                  "$ref": "#/components/schemas/TagData"
                }
              }
            }
          },
          "update": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "id",
                "data"
              ],
              "properties": {
                "id": {
                  "$ref": "#/components/schemas/TagRef"
                },
                "data": {
                  "$ref": "#/components/schemas/TagData"
                }
              }
            }
          },
          "delete": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagRef"
            }
          }
        }
      },
      "tagsBulkResponse": {
        "type": "object",
        "required": [
          "tagsVersion",
          "created",
          "updated",
          "deleted"
        ],
        "properties": {
          "tagsVersion": {
            "type": "integer"
          },
          "created": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "updated": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tag"
            }
          },
          "deleted": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TagUrn"
            }
          }
        }
      },
      "tagsMoveBulkRequest": {
        "type": "array",
        "items": {
          "type": "object",
          "required": [
            "sourceTagListId",
            "tagsIds"
          ],
          "properties": {
            "sourceTagListId": {
              "$ref": "#/components/schemas/TagListRef"
            },
            "tagsIds": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/TagRef"
              }
            },
            "metadataIdMapping": {
              "type": "array",
              "nullable": true,
              "items": {
                "type": "object",
                "required": [
                  "sourceId",
                  "targetId"
                ],
                "properties": {
                  "sourceId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "metadata id in the source tag list"
                  },
                  "targetId": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "metadata id in the target tag list"
                  }
                }
              }
            }
          }
        }
      },
      "tagsMoveBulkResponse": {
        "type": "array",
        "items": {
          "type": "object",
          "required": [
            "tagList",
            "updatedTags"
          ],
          "properties": {
            "tagList": {
              "$ref": "#/components/schemas/TagList"
            },
            "updatedTags": {
              "type": "array",
              "items": {
                "$ref": "#/components/schemas/Tag"
              }
            }
          }
        }
      },
      "Permission": {
        "type": "object",
        "required": [
          "name"
        ],
        "x-tags": [
          "Permissions"
        ],
        "properties": {
          "name": {
            "type": "string"
          }
        }
      },
      "Id": {
        "type": "number",
        "readOnly": true
      },
      "FormatId": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Id"
          }
        ],
        "example": 5
      },
      "FileFormat": {
        "type": "object",
        "x-tags": [
          "File"
        ],
        "required": [
          "id",
          "name",
          "description",
          "extension",
          "icon",
          "canBeUploaded",
          "shareUrlType",
          "categoryName",
          "categoryDescription",
          "categoryType"
        ],
        "properties": {
          "id": {
            "$ref": "#/components/schemas/FormatId"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "extension": {
            "type": "string"
          },
          "icon": {
            "type": "string"
          },
          "canBeUploaded": {
            "type": "boolean"
          },
          "shareUrlType": {
            "type": "string"
          },
          "categoryName": {
            "type": "string"
          },
          "categoryDescription": {
            "type": "string"
          },
          "categoryType": {
            "type": "string"
          }
        }
      },
      "SpatialReferenceValue": {
        "type": "object",
        "required": [
          "authName",
          "code",
          "deprecated",
          "name"
        ],
        "properties": {
          "authName": {
            "type": "string",
            "description": "The authority defining the used code (IGNF, NKG, OGC, IAU_2015, EPSG, ESRI)"
          },
          "code": {
            "type": "string",
            "description": "The code of the geographic reference to be used for this project"
          },
          "deprecated": {
            "type": "boolean",
            "description": "If true, the spatialReference cannot be used to define any project anymore (only available for already settled projects)"
          },
          "name": {
            "type": "string",
            "description": "Description about the location of the SpatialReference"
          }
        }
      },
      "AIDetectionClass": {
        "type": "object",
        "required": [
          "name",
          "category"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Identifier of the AI detection class"
          },
          "category": {
            "type": "string",
            "description": "Category associated with the class"
          }
        }
      },
      "AutodeskConnection": {
        "type": "object",
        "x-tags": [
          "Autodesk"
        ],
        "required": [
          "hubs"
        ],
        "properties": {
          "email": {
            "type": "string",
            "nullable": true
          },
          "userName": {
            "type": "string",
            "nullable": true
          },
          "firstName": {
            "type": "string",
            "nullable": true
          },
          "lastName": {
            "type": "string",
            "nullable": true
          },
          "hubs": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "autodeskId",
                "name",
                "projects"
              ],
              "properties": {
                "autodeskId": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "projects": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "autodeskId",
                      "name"
                    ],
                    "properties": {
                      "autodeskId": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "TenantSettingKey": {
        "type": "string",
        "description": "Available tenant setting keys:\n- `mfaEnabled` (boolean): Whether multi-factor authentication is enabled for the tenant\n",
        "enum": [
          "mfaEnabled"
        ],
        "example": "mfaEnabled"
      }
    },
    "responses": {
      "UnexpectedError": {
        "description": "unexpected error",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "examples": {
              "400": {
                "value": {
                  "status": 400,
                  "title": "Bad Request"
                }
              },
              "401": {
                "value": {
                  "status": 401,
                  "title": "Unauthorized"
                }
              },
              "403": {
                "value": {
                  "status": 403,
                  "title": "Forbidden"
                }
              },
              "404": {
                "value": {
                  "status": 404,
                  "title": "Not Found"
                }
              },
              "405": {
                "value": {
                  "status": 405,
                  "title": "Method Not Allowed"
                }
              },
              "406": {
                "value": {
                  "status": 406,
                  "title": "Not Acceptable"
                }
              }
            }
          }
        }
      }
    },
    "securitySchemes": {
      "oauth2": {
        "type": "oauth2",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://aec.cintoo.com/oauth/authorize",
            "tokenUrl": "https://aec.cintoo.com/oauth/token",
            "scopes": {},
            "refreshUrl": "https://aec.cintoo.com/oauth/token"
          }
        }
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "General",
      "tags": [
        "errors_list",
        "internal_information",
        "token_management",
        "Permissions",
        "Authentication"
      ]
    },
    {
      "name": "Resources",
      "tags": [
        "Resources"
      ]
    },
    {
      "name": "Tenant",
      "tags": [
        "Tenant"
      ]
    },
    {
      "name": "Account",
      "tags": [
        "Account",
        "Subscription",
        "Role",
        "User",
        "Group"
      ]
    },
    {
      "name": "Subscription",
      "tags": [
        "Usage Report"
      ]
    },
    {
      "name": "Project",
      "tags": [
        "Project",
        "Members",
        "Workzone"
      ]
    },
    {
      "name": "Project Data",
      "tags": [
        "File",
        "Annotation",
        "Saved View",
        "Share Link",
        "Crop",
        "Measurement",
        "Tag List",
        "Tag",
        "Video360"
      ]
    },
    {
      "name": "Jobs",
      "tags": [
        "Progress Monitoring",
        "Import Model",
        "Export Scene",
        "Segmentation"
      ]
    },
    {
      "name": "Integrations",
      "tags": [
        "Integrations",
        "Konekt",
        "Autodesk",
        "Procore"
      ]
    },
    {
      "name": "Tutorials",
      "tags": [
        "tuto_upload_file",
        "understand_tag_data"
      ]
    }
  ]
}