{
  "openapi": "3.1.0",
  "info": {
    "title": "Limble API V2",
    "version": "1.0.0",
    "description": "Getting Started!\n\nWelcome to Limble CMMS’s API documentation.\n\n**Pagination limits:** Pagination `limit` parameters are enforced server-side. Requests with a `limit` value exceeding the endpoint's maximum will receive a `422 Unprocessable Entity` response. Requests with a missing or non-positive `limit` default to 1000.\n\nYou can use this documentation to configure connections to the Limble CMMS API over https using RESTful standards.\n\nUsing the API you can get information about the following portions of your system:\n\n- Assets\n\n- Locations\n\n- Parts (Current quantities and Usage)\n\n- Tasks (Work Orders, Preventive Maintenance, Work Requests, etc.)\n\n- Users\n\n- Vendors\n\n- Roles\n\n- Teams\n\n- Purchase Orders\n\n- General Ledgers\n\n- Budgets\n\n- Priorities\n\n- Tags\n\n- Statuses\n\n- Bills\n\n- Regions\n\n- Webhooks\n\n- Units of Measure(UOM)\n\nPlease use the correct Limble API URL to connect to our API based on the region or the type of your Limble Account.\n\n| **Limble Account (Region/Type)** | **Limble API URL** |\n| --- | --- |\n| Default | api.limblecmms.com |\n| Canada | ca-api.limblecmms.com |\n| Australia | au-api.limblecmms.com |\n| Europe | eu-api.limblecmms.com |\n| 21CFR | 21cfr-api.limblecmms.com |\n\n---\n\n# Authentication\n\nTo protect your information the Limble CMMS API uses BASIC authorization standards.\n\nEvery call to the API must include an authorization header with your base 64 encoded id and secret.\n\nClient ID\n\nYour Client ID is your unique customer identification.\n\nClient Secret\n\nYour Client Secret is used to authenticate the Client ID on each API call. This is something that must be kept secret.\n\n> How do I get my Client ID and Client Secret? \n\nTo obtain your Client ID and Client Secret login to your Limble account as a **Super Administrator** and go to **Settings** -> **Configuration**, on this page scroll down to the **API Settings** section and click **Generate API Keys**. Keep this information **secret**, you will only be able to see your Client Secret once upon initial generation. If you lose your secret you will need to regenerate it and update your integration accordingly.\n\n> Example Header \nAuthorization: Basic \\[BASE64 ENCODED YOUR_CLIENT_ID:YOUR_CLIENT_SECRET \n\nBelow is a code example for PHP:\n\n```\n$curl = curl_init();\n$id = 'your_client_id';\n$secret = 'your_client_id';\n$headers = array(\n'Content-Type:application/json',\n'Authorization: Basic '. base64_encode($id.':'.$secret)\n);\ncurl_setopt($ch, CURLOPT_HTTPHEADER, $headers);\ncurl_setopt_array($curl, array(\nCURLOPT_URL => 'https://api.limblecmms.com:443/v2/tasks/',\nCURLOPT_RETURNTRANSFER => true,\nCURLOPT_ENCODING => \"\",\nCURLOPT_MAXREDIRS => 10,\nCURLOPT_TIMEOUT => 0,\nCURLOPT_FOLLOWLOCATION => false,\nCURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\nCURLOPT_CUSTOMREQUEST => \"GET\",\n));\n$response = curl_exec($curl);\n$err = curl_error($curl);\ncurl_close($curl);\nif ($err) {\necho \"cURL Error #:\" . $err;\n} else {\necho $response;\n} ?>\n\n```\n\nBelow is a code example for NodeJS:\n\n```\nconst https = require('https');\nconst id = 'your_client_id';\nconst secret = 'your_client_secret';\nconst options = {\n'method': 'GET',\n'hostname': 'api.limblecmms.com',\n'path': '/v2/tasks/?',\n'headers': {\n'Authorization': 'Basic ' + Buffer.from(`${credentials.id}:${credentials.secret}`).toString('base64')\n}\n};\nconst req = https.request(options, function (res) {\nconst chunks = [];\nres.on(\"data\", function (chunk) {\nchunks.push(chunk);\n});\nres.on(\"end\", function (chunk) {\nconst body = Buffer.concat(chunks);\nconsole.log(body.toString());\n});\nres.on(\"error\", function (error) {\nconsole.error(error);\n});\n});\nreq.end();\n\n```\n\n---\n\n# Error Codes\n\n- HTTP 400 - Data Validation Error - Malformed JSON input or incorrect data type.\n\n- HTTP 403 - Forbidden - The resource cannot be accessed.\n\n- HTTP 404 - Resource not found - The resource you are targeting does not exist.\n\n- HTTP 409 - Resource Conflict - A resource already exists with those parameters.\n\n- HTTP 422 - Unprocessable Entity - The syntax of the request is correct but cannot be processed due to semantic errors.\n\n- HTTP 429 - Too Many Requests - See the rate limiting section below.\n\n- HTTP 500 - Internal Server Error - Contact Limble for assistance.\n\n- HTTP 501 - Method Not Support - Limble's API only supports GET, POST, PATCH, PUT, and DELETE.\n\n---\n\n# Pagination\n\nMany list endpoints accept a `limit` query parameter to control the number of records returned per page.\n\nEach endpoint enforces a server-side maximum:\n\n- Requests with a `limit` that exceeds the endpoint's maximum will receive a `422 Unprocessable Entity` response with a message indicating the requested value and the allowed maximum.\n\n- Requests with a missing or non-positive `limit` (e.g. `limit=0`) default to 1000.\n\n- Requests with a `limit` within the allowed maximum are unaffected.\n\n## Pagination response headers\n\n**Offset mode** (`?page=N`): returns `Last-Page`, `Next-Page` (if applicable), and `Previous-Page` (if applicable) headers with full URLs for adjacent pages.\n\n**Cursor mode** (no `page` param): returns `X-Has-More: true|false` indicating whether additional records exist beyond the current page. When `X-Has-More` is `true`, also returns `Next-Page` with a ready-to-use URL (the `cursor` parameter set to the last record's ID) to fetch the next batch.\n\n---\n\n# Success Codes\n\n- HTTP 200 - OK - Everything was successful. PUTs, PATCHs and DELETEs on success always return an empty 200 OK.\n\n- HTTP 201 - CREATED - This is used on POST calls when new resouces are created. If a new resource was created Limble will always pass back a GET URL in the location header so a developer can easily GET the new resource.\n\n---\n\n# Overriding HTTP methods\n\nSome systems may support only the `POST` and `GET` HTTP methods. This restriction prevents using other HTTP methods such as `PUT`, `PATCH` and `DELETE`. RESTful web API implementations can work around this restriction by letting the client override the HTTP method via the custom HTTP headers.\n\nThe Limble API supports **Method Overrides** by using a `POST` request and setting the `X-HTTP-Method-Override` header with a method string value. The header value can be `PATCH` or `PUT`. This will allow Limble API users to use `PATCH` and `PUT` endpoints by sending `POST` requests to these endpoints and overriding them with the respective HTTP method.\n\n# Webhooks\n\nReceive data on certain events such as Tasks being completed.\n\nLimble's webhooks allow you to receive data whenever specific events occur.\n\nFor example, you may need to run your own script whenever a Task is completed.\n\nLimble supports adding multiple webhooks that can be triggered when actions are carried out on:\n\n- Tasks\n\n- Assets\n\n- Asset Fields\n\n- Purchase Orders\n\n- Purchase Order Items\n\nWhen an event occurs, Limble sends an HTTP POST request to a URL endpoint you configure.\n\nYou can configure this URL in the Limble Web App under:\n\n**Settings → Configuration → API Settings**\n\nAll data sent is JSON-encoded, and Limble includes the following fields in the request headers for validation:\n\n- `signature`\n\n- `timestamp`\n\n- `token`\n\nYou may register multiple webhooks for the same event type.\n\n### Important: API Key Requirement for Webhooks\n\nTo receive webhooks, the customer must have at least one active **limbleAPI key** created in API Settings.\n\n- Webhooks **will not function** without at least one valid `limbleAPI` key.\n\n- Limble uses the **first-created** **`limbleAPI`** **key** (by creation date) to generate the **signature** included in webhook headers.\n\n- The receiving system must use this key to verify the authenticity of incoming webhook requests.\n\nIf a customer has multiple `limbleAPI` keys, **only the oldest one** will be used for signing webhook requests.\n\n### Response Time and Retry Behavior\n\nYour server must respond to webhook POST requests within **10 seconds**.\n\nIf it does not, Limble will attempt to retry the webhook request.\n\nLimble handles server responses as follows:\n\n- If the server returns **200 OK**, Limble considers the webhook successful and will not retry.\n\n- If the server returns **406 Not Acceptable**, Limble considers the webhook received but intentionally ignored — no retry will occur.\n\n- For any other response (e.g., 500, timeout, etc.), Limble will retry the request.\n\n**Retry schedule:**\n\n- After 10 minutes\n\n- After 1 hour\n\n- After 2 hours\n\n- After 4 hours\n\nAfter the final retry attempt, the webhook will be **automatically disabled**.\n\n### Re-enabling a Disabled Webhook\n\nTo re-enable a disabled webhook:\n\n1. Go to **Settings → Configuration → API Settings** in the Limble Web App. \nFind the webhook and use the option to **Re-enable** the API endpoint.\n\n2. Alternatively, send a `PATCH` request using the **Update Webhook** endpoint and set `enabled = true`.\n\n### Assets\n\nBelow is an example payload you might be sent when an event occurs on an asset:\n\n```\n{\n\"assetID\": 10748, \n\"status\": \"CREATED\",\n\"category\": \"asset\", \n\"user\": \"bob@limblecmms.com\" \n}\n\n```\n\nOnce the Payload is received you can use the Get Assets API call to get the most recent Asset data. The following is a list of all the possible statuses that a webhook might be set to:\n\nCREATED | An Asset is created\nDELETED | An Asset was deleted\nCHANGED ASSET NAME | An asset has been renamed\n\n### Asset Field\n\nBelow is an example payload you might be sent when an event occurs on an asset field:\n\n```\n{\n\"valueID\": 46490,\n\"status\": \"DELETED\",\n\"category\": \"assetField\",\n\"user\": \"bob@limblecmms.com\"\n}\n\n```\n\nOnce the Payload is received you can use the Get Asset Field API call to get the most recent Asset Field data. The following is a list of all the possible statuses that a webhook might be set to:\n\nADDED | An Asset Field was added to an Asset\nDELETED | An Asset Field was deleted from an Asset\nUPDATED | An Asset Field was updated on an Asset\n\n### Location\n\nBelow is an example payload you might be sent when an event occurs on an location field:\n\n```\n{\n\"valueID\": 46490,\n\"status\": \"DELETED\",\n\"category\": \"location\",\n\"user\": \"bob@limblecmms.com\"\n}\n\n```\n\nOnce the Payload is received you can use the Get Location API call to get the most recent Location data. The following is a list of all the possible statuses that a webhook might be set to:\n\nCREATED | An Location was added\nDELETED | An Location was deleted\nUPDATED | An Location was updated\n\n### Parts\n\nFor Parts, you may receive a webhook that looks like this:\n\n```\n{ \n\"partID\": 3456,\n\"status\": \"CREATED\",\n\"category\": \"part\",\n\"user\": \"bob@limblecmms.com\"\n}\n\n```\n\nAll possible statuses for Parts webhooks are as follows:\n\nCREATED | A Part was created.\nDELETED | A Part was deleted.\nLOCATION UPDATED | A Part had its location updated.\nSUPPLIER UPDATED | A Part had its supplier updated.\nPRICE UPDATED | A Part had its price updated.\nNAME UPDATED | A Part had its name updated.\nQUANTITY INCREASED | The quantity of a part increased.\nQUANTITY DECREASED | The quantity of a part decreased.\n\n### Purchase Order\n\nIf you have enabled purchasing webhooks, you may receive a webhook for POs that looks like this:\n\n```\n{ \n\"poID\": 8203,\n\"status\": \"READY TO RECEIVE\",\n\"category\": \"po\",\n\"user\": \"bob@limblecmms.com\"\n}\n\n```\n\nPossible statuses for PO webhooks are:\n\nCREATED | A PO was created.\nSETUP | A PO has been reset and now has the setup status.\nCHANGE STATUS | A PO has been approved and now has a custom status.\nREADY TO RECEIVE | A PO now has the Ready to Receive status.\nPARTIALLY RECEIVED | A PO has received any number of items and now has the Partially Received status.\nFULLY RECEIVED | A PO has received all of its items and now has the Fully Received status.\nCLOSED | A PO has had all items received and all bills paid and now has the Closed status.\nDELETED | A PO was deleted.\nCHANGE BUDGET | A PO has been assigned a new budget.\nCHANGE VENDOR | A PO has been assigned a new vendor.\nCHANGE NUMBER | A PO's PO Number has been modified.\nCHANGE BILL-TO | A PO's bill-to field has been modified.\nCHANGE SHIP-TO | A PO's ship-to field has been modified.\nCHANGE NOTES TO VENDOR | A PO's \"Notes to Vendor\" field has been modified.\nCHANGE CUSTOM FIELD | Any of a PO's custom fields has been modified.\nCHANGE ASSIGNMENT | A PO has had its assignment (user, team, multi-user) modified.\nCHANGE DATE | A PO's created date has been modified.\nCHANGE DELIVERY DATE | A PO's expected delivery date has been modified.\nDISAPPROVED PURCHASE REQUEST | A Purchase Request PO has been disapproved.\nREOPENED PURCHASE REQUEST | A disapproved Purchase Request PO has been reopened.\nDISAPPROVED STEP | A PO has had its workflow step disapproved and been sent back a step.\n\n### Purchase Order Items\n\nFor PO Items, you may receive a webhook that looks like this:\n\n```\n{ \n\"poItemID\": 8203,\n\"status\": \"RECEIVED\",\n\"category\": \"poItem\",\n\"user\": \"bob@limblecmms.com\"\n}\n\n```\n\nAll possible statuses for PO Item webhooks are as follows:\n\nCREATED | A PO Item was created.\nDELETED | A PO Item was deleted.\nRECEIVED | Some quantity of a PO Item was marked as received.\nCHANGE GL | A PO Item has been assigned a new GL or its GL has been removed.\nCHANGE DESCRIPTION | A PO Item has had its description modified.\nCHANGE QUANTITY | A PO Item has had its quantity modified.\nCHANGE RATE | A PO Item has had its rate (price) modified.\nCHANGE TAX | A PO Item has had its tax percentage modified.\nCHANGE DISCOUNT | A PO Item has had its discount percentage modified.\nCHANGE SHIPPING | A PO Item has had its shipping cost modified.\n\n### Tasks\n\nBelow is an example payload you might be sent when an event occurs on a Task:\n\n```\n{\n\"taskID\": 8203, // The unique identifier for the item the webhook event describes\n\"status\": \"COMPLETE\", // The status (e.g. task created, task complete, etc.) -- see below for a full list of possible statuses.\n\"category\": \"task\", // The category of item that triggered the webhook to fire (e.g. task, po, poItem).\n\"user\": \"bob@limblecmms.com\" // The user whose action caused the webhook to fire.\n}\n\n```\n\nOnce the Payload is received you can use the Get Tasks API call to get the most recent Task data. The following is a list of all the possible statuses that a webhook might be set to:\n\nCREATED | A Task was created\nDELETED | A Task was deleted\nCHANGED DUE DATE | A Task changed due date\nCHANGED ASSIGNMENT | A Task changed assignment\nCOMPLETE | A Task was completed.\nCHANGED COMPLETED TASK | A Task that is completed was changed.\nCOMPLETED TASK REOPENED | A task that was completed was reopened and is now open.\nCHANGED TASK NAME | A task has been renamed.\nCHANGED TASK DESCRIPTION | The description of a task has been changed.\nADDED COMMENT TO TASK | A comment was added to a task.\nCUSTOM TAG ADDED TO TASK | A custom tag was added to a task.\nCUSTOM TAG REMOVED FROM TASK | A custom tag was removed from task.\nLOGGED TIME ON TASK | A time entry was added to a task.\n\n### Task Instruction\n\nBelow is an example payload you might be sent when an event occurs on an location field:\n\n```\n{\n\"instructionID\": 46490,\n\"status\": \"Updated\",\n\"category\": \"instruction\",\n\"user\": \"bob@limblecmms.com\"\n}\n\n```\n\nOnce the Payload is received you can use the Get Instruction API call to get the task instruction data. The following is a list of all the possible statuses that a webhook might be set to:\n\nCREATED | A Task Instruction was added\nDELETED | A Task Instruction was deleted\nUPDATED | A Task Instruction was updated\nLABEL UPDATED | A Task Instruction's label was updated\nDESCRIPTION UPDATED | A Task Instruction's description was updated\nPARENT RESPONSE UPDATED | The response of a Task Instruction's parent item was updated\nSORT ORDER UPDATED | The sort order of a Task Instruction was updated.\n\n## Securing Webhooks\n\nTo ensure the authenticity and integrity of webhook events each webhook is \nsigned with a signature as well as some other data described below:\n\ntimestamp | int | A standard unix time stamp\ntoken | string | , randomly generated string that is an integrity check of the, payload.,\nsignature | String | A string generated by the HMAC algorithm\n\nTo verify the webhook is originating from LimbleCMMS you will need to:\n\n- Concatenate the timestamp and token\n\n- Encode your private API key (oldest Limble API Key) with the SHA256 algorithm\n\n- Encode the timestamp and token value with the HMAC algorithm using your hashed private key and the SHA256 method.\n\n- Compare the resulting digest to the signature provided in your webhook \nheader\n\n## Validation Code Examples\n\nCode samples to verify webhook data.\n\nPHP\n\n```\nfunction verify($timestamp, $signature, $apiKey, $token)\n//hash private key\n$apiKey = hash('sha256', $apiKey);\n$generated_signature = hash_hmac('sha256', $timestamp . $token, $apiKey);\nif($generated_signature === $signature) {\nreturn true;\n} else {\nreturn false;\n}\n} \n\n```\n\nNodeJS\n\n```\nvar crypto = require('crypto');\nconst verify = (apiKey, token, timestamp, signature) => {\n//hash private key\nconst apiKey = crypto.createHash('sha256').update(apiKey).digest('hex');\nconst value = timestamp+token;\nconst generated_signature = crypto.createHmac('sha256',apiKey).update(value).digest('hex');\nif(signature === generated_signature){\nreturn true;\n} else {\nreturn false;\n}\n};\n\n```\n\n---\n\n# Rate limit\n\nTo help protect against run-away scripts, clients who make an inordinate \nnumber of calls over a period of time may be temporarily blocked from \naccessing the service. The limits are defined in the table below. If you \nreceive an error indicating that you have exceeded the call limit, please \nwait and try again later. If you need higher limits please reach out to your dedicated account manager.\n\n## Per Hour\n\nGET | 4000 calls per hour. | 360 calls per minute.\nPATCH | 2000 calls per hour. | 240 calls per minute.\nPOST | 1000 calls per hour. | 240 calls per minute.\nPUT | 1000 calls per hour. | 240 calls per minute.\nDELETE | 100 calls per hour. | 60 calls per minute.\nBATCH REQUEST | 20 calls per hour | 5 calls per minute\n\nEvery API response is accompanied by the following set of headers to identify the status of your consumption. API calls are rate-limited on two windows of time: per-minute and per-hour. For example, if you made a request at 13:42:42, that request will expire from your per-minute window at 13:43:42 and from your per-hour window at 14:42:42.\n\nX-RateLimit-Limit | The maximum number of requests that the consumer is permitted to make per hour.\nX-RateLimit-Remaining | The number of requests remaining in the current per-hour window.\nX-RateLimit-First-Call | The time your first call was made in the current per-hour window.\nX-RateLimit-TTL | The time until more request resources become available (This only displays when you've hit your limit).\nX-RateLimit-Minute-Limit | The maximum number of requests that the consumer is permitted to make per minute.\nX-RateLimit-Minute-Remaining | The number of requests remaining in the current per-minute window.\nX-RateLimit-Minute-First-Call | The time your first call was made in the current per-minute window.\nX-RateLimit-Minute-TTL | The time until more request resources become available (This only displays when you've hit your limit).\n\n# Pagination\n\nCurrently pagination using OrderBy and cursor is supported only by **GET Tasks** and **GET Assets**. Pagination using Limit and Page is supported by many other GET endpoints including **GET Tasks** and **GET Assets**.\n\nPagination can be implemented by using the orderBy, cursor, limit and page query parameters. \n**Note: cursor and page cannot be used simultaneously for pagination.**\n\n## Pagination using Limit and Page\n\nThis uses limit and page query parameters. For a given limit and page results will be paginated. If orderBy query parameter is given the results will be ordered and paginated accordingly.\n\nThe page parameter is **required** and can be greater than or equal to 1 for this pagination method. The default limit is 100 but can be changed. The max limit is 1000.\n\nThe response headers contain information about the Previous, Next and Last Page of the result based on the limit.\n\nThe result will be empty when for a given limit, the given page does not exist. For example, if there are 100 Assets in total and limit is set at 10, only pages 1-10 are possible. An empty result will be given for page numbers greater than 10.\n\nThis pagination method is supported by various GET endpoints. Please refer to the examples for those GET endpoints for more information.\n\n## Pagination using OrderBy and Cursor\n\n**Note**: If you're implementing pagination for the first time for **GET Tasks** or **GET Assets** please follow **Pagination Using Limit and Page** as the use of **Cursor** will be deprecated in the next API version.\n\nThis uses orderBy and cursor query parameters. Generally, in all of our GET endpoints, the cursor parameter ensures that the ID will be greater than the value of cursor. This makes sense when we're ordering the results ascending by ID.\n\nIn GET Assets, when we're fetching a set of assets and ordering by lastEdited (ascending) or -lastEdited (descending), the cursor parameter will instead ensure that we're returning a set of results that begin at the next asset in the order, regardless of whether its **ID is greater or less than the value of cursor**.\n\nIf the value of cursor does not match an existing assetID, then the result set will be empty, because there is no lastEdited value to compare to. **When providing orderBy and cursor, the value of cursor must be a real assetID or the result set will be empty.**\n\nThe same applies for GET Tasks when using cursor and ordering by createdDate, dateCompleted and due.\n\n---\n\n## Machine-Readable OpenAPI Spec\n\nA machine-readable OpenAPI JSON spec is served directly from the API at `/openapi.json` (no authentication required):\n\n`https://api.limblecmms.com/openapi.json`"
  },
  "servers": [
    {
      "url": "{{server}}:{{port}}"
    }
  ],
  "security": [
    {
      "BasicAuth": []
    }
  ],
  "paths": {
    "/v2/me": {
      "get": {
        "operationId": "getMe",
        "summary": "Me",
        "responses": {
          "200": {
            "description": "Me",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Me"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Me"
        ],
        "description": "Identifies the current customer. This route can be used to test that authentication to the Limble API was successful.\n\nReturn data description\n\ncustomerName | The name of the customer that your API keys are valid for.\ncustomerPlan | The Limble plan the customer is currently subscribed to. The customerPlan can have one of following values:, starter, professional, business, enterprise, legacy - The plan the customer is currently subscribed to has been deprecated., For more information about various plans please visit the Limble website."
      }
    },
    "/v2/assets/{assetID}/image": {
      "put": {
        "operationId": "putAssetsByAssetIDImage",
        "summary": "Add Asset Main Image",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Image"
        ],
        "description": "Each asset can have one main image associated with it.  This request allows you to set that image."
      },
      "parameters": [
        {
          "name": "assetID",
          "in": "path",
          "required": true,
          "description": "assetID of the asset you are removing the main image from.",
          "schema": {
            "type": "string"
          },
          "example": "{{assetID}}"
        }
      ],
      "delete": {
        "operationId": "deleteAssetsByAssetIDImage",
        "summary": "Delete Asset Main Image",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Image"
        ],
        "description": "This request removes the main image from the asset."
      }
    },
    "/v2/assets/fields": {
      "get": {
        "operationId": "getAssetsFields",
        "summary": "Asset Fields",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific field by name. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "Model"
          },
          {
            "name": "fields",
            "in": "query",
            "description": "This parameter can be used to get a single Asset Fields or a list of Asset Fields in a comma-separated list.",
            "schema": {
              "type": "integer"
            },
            "example": 107
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Asset Fields for Assets that were last edited after the unix timestamp passed into the start parameter. For example, all Assets that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1555105636
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Asset Fields for Assets that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1555105636
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what id you want to start receiving results at. e.g. passing 137 here will only get you asset fields with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter can be used to get a group of asset fields in a location in a comma-separated list.",
            "schema": {
              "type": "integer"
            },
            "example": 163
          },
          {
            "name": "value",
            "in": "query",
            "description": "This parameter is used to only get specific fields by value. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "F150"
          },
          {
            "name": "assetName",
            "in": "query",
            "description": "This parameter is used to only get specific fields by asset name. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%fork%"
          },
          {
            "name": "fieldType[0]",
            "in": "query",
            "description": "This parameter is used to only get specific fields by type. This parameter expects an array of strings \"Text, Date, Pictures, Documents, Number, Currency, Dropdown\"",
            "schema": {
              "type": "string"
            },
            "example": "Text"
          },
          {
            "name": "fieldType[1]",
            "in": "query",
            "description": "This parameter is used to only get specific fields by type. This parameter expects an array of strings \"Text, Date, Pictures, Documents, Number, Currency, Dropdown\"",
            "schema": {
              "type": "string"
            },
            "example": "Documents"
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "values",
            "in": "query",
            "description": "This parameter is used to get asset fields by their valueID. This parameter expects a comma delimited list of Value IDs.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "assets",
            "in": "query",
            "description": "This parameter can be used to get a group of asset fields for a specific set of asset ids in a comma-separated list.",
            "schema": {
              "type": "integer"
            },
            "example": 171
          }
        ],
        "responses": {
          "200": {
            "description": "Asset Fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "fieldID": {
                        "type": "integer"
                      },
                      "assetID": {
                        "type": "integer"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "field": {
                        "type": "string"
                      },
                      "value": {
                        "type": "null"
                      },
                      "valueID": {
                        "type": "integer"
                      },
                      "fieldType": {
                        "type": "string"
                      },
                      "lastEdited": {
                        "type": "integer"
                      },
                      "locked": {
                        "type": "boolean"
                      },
                      "files": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "fileName": {
                              "type": "string"
                            },
                            "link": {
                              "type": "string",
                              "format": "uri"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "fieldID": 27,
                    "assetID": 1022,
                    "locationID": 163,
                    "field": "Manual",
                    "value": null,
                    "valueID": 45346,
                    "fieldType": "Documents",
                    "lastEdited": 1572028803,
                    "locked": false,
                    "files": [
                      {
                        "fileName": "guide.pdf",
                        "link": "https://content.limblecmms.com/upload-36/assets/163/1022/45346/guide.pdf?Expires=1572372505&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jb250ZW50LmxpbWJsZWNtbXMuY29tL3VwbG9hZC0zNi9hc3NldHMvMTYzLzEwMjIvNDUzNDYvMS5wZGYiLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE1NzIzNzI1MDV9fX1dfQ__&Signature=BqvWWjq-bk03MJ1~GxAHIRh0J1qK6NkiD~GcE9R1awh8xhrVUhOgvrZapSjMCe8dqKOsri7qYc~CytaQgD-NmqmWK4du4khv-hU~LmXQ-nDFnbUCs4SHo0QOtHieFX7x0Hs6DkioLdPHlvZsgb7bXyHXJMyMwhQThfAXR6WjfIjDpggsdEnUeyeEMI9tg1SLZOnCI64oWze56EGDNk1VQ6s0RcwPCjAsYebRjkr9crktS9x0Xt7WySL0UZeWUK-gbte3tjC52xDUvOeLsXw19JvA4Dx9GCWRTQu1R4kRMh4Phy7iR62kZTaJGP-Hb8OimGs95DUF-cniGOsMgQrXmQ__&Key-Pair-Id=APKAIH5A42E3EPKJRHFQ"
                      },
                      {
                        "fileName": "parts-guide.pdf",
                        "link": "https://content.limblecmms.com/upload-36/assets/163/1022/45346/parts-guide.pdf?Expires=1572372505&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jb250ZW50LmxpbWJsZWNtbXMuY29tL3VwbG9hZC0zNi9hc3NldHMvMTYzLzEwMjIvNDUzNDYvMS0xLnBkZiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTU3MjM3MjUwNX19fV19&Signature=sMg0S7HCdz8KeMVvXQW~KsZWGGolD5K4QFhKD2jcn90QIL5xqhKDTwZbyUdYWWr7aJLleMXBAW3iBxIxfp58bBcbfqDPQsWlseO~zRFIoORGHgozwvZ9V8gA0-UvlYFLVX1dLiZIzxRh3UXqXEU1uNRLehSGcJbaWc6TTvfCGuRrg4b8FUE8MVyyQBMtFBZ4aI82ggwkQWVu3~P2Vjltd5QNmArd2XJdrx2FtPxrhpupdoQdW0fd4dpwADjGzUQzlAmVA~1rzzWERDzIC29wQaT4GuOJIJ3cePQZHjw9KCxetYcsu4W-38BXmAybmMmLDvmOk61PDVaDhCcLkA4ycw__&Key-Pair-Id=APKAIH5A42E3EPKJRHFQ"
                      },
                      {
                        "fileName": "2018-ELANTRA-AD-OM.pdf",
                        "link": "https://content.limblecmms.com/upload-36/assets/163/1022/45346/2018-ELANTRA-AD-OM.pdf?Expires=1572372505&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jb250ZW50LmxpbWJsZWNtbXMuY29tL3VwbG9hZC0zNi9hc3NldHMvMTYzLzEwMjIvNDUzNDYvMjAxOC1FTEFOVFJBLUFELU9NLnBkZiIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTU3MjM3MjUwNX19fV19&Signature=jClvv7jCkK5hB~2DEp9GYe7xpo2SPkDo2XFNsrBHMX3f8vynCPtN~zi0HELdE5XdSnhtNRO4dgMzy9n0nB~uBzR-8lvSxKflAG9Hk~5ch9lW8uO1LosfG8ixt9qyKTLI5gcMkXBLH42l~M094fGyjUEDROZ2f7aiFTyGK-kX4KLvGctFdbAL-AsiIAQusrE1AbUTFkEmlQlJVn4S8sUcQNYUDMY1uXhoW6g3fN7RO5vdC8t-WKkLHauJLy5hBeAWvbpmG0G1-5KGvB3n3LRCJHIN~cNDs1vWyZo0BH-fUauai3T2fRPd8rsspW2cagtnqeanHg78pffQARGaEoMneA__&Key-Pair-Id=APKAIH5A42E3EPKJRHFQ"
                      }
                    ]
                  },
                  {
                    "fieldID": 37,
                    "assetID": 1022,
                    "locationID": 163,
                    "field": "Gallons",
                    "value": null,
                    "valueID": 45377,
                    "fieldType": "Number",
                    "lastEdited": 1572028803,
                    "locked": true,
                    "files": []
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "This request gets detailed information about asset fields such as Make, Model and any other custom field.\n\nThis call also returns \"files\" which is an array of objects that have a file name and a link you can use to download that file. All links are only valid for 15 minutes, a new call will generate a new link.\n\n**Note:** this endpoint supports pagination. Please refer to the [**Pagination**](#pagination) section for more information."
      },
      "post": {
        "operationId": "postAssetsFields",
        "summary": "New Asset Suggested Field",
        "responses": {
          "201": {
            "description": "New Asset Suggested Field",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/assets/fields/?fields=643"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "fieldID": {
                      "type": "string",
                      "format": "color"
                    }
                  }
                },
                "example": {
                  "fieldID": "643"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "This request creates a new Suggested Field.\n\nSuggested Fields are the full list of possible Fields that can be added to Assets at that Location.\n\nParameter: locationID, Type: Int, Required?: Required, Description: The location ID of the Asset to add the new Field to.\nParameter: name, Type: String, Required?: Required, Description: The name of the new Field. Some custom field names such as \"Asset\" are not allowed and reserved for internal use. This will result in a 409 error.\nParameter: fieldType, Type: Int, Required?: Required, Description: The type of the new Field. You can choose from Text (1), Date (2), Pictures (3), Documents (4), Number (5), Currency (6), Dropdown (7).\n\nParameter: options, Type: Array of objects with a \"name\" property, Required?: Optional (only valid when fieldType is 7), Description: Initial list of options for a Dropdown field. Each option must have a \"name\" string."
      }
    },
    "/v2/assets/fields/suggested": {
      "get": {
        "operationId": "getAssetsFieldsSuggested",
        "summary": "Asset Suggested Fields",
        "parameters": [
          {
            "name": "fields",
            "in": "query",
            "description": "This parameter can be used to get a single Asset Fields or a list of Asset Fields in a comma-separated list.",
            "schema": {
              "type": "integer"
            },
            "example": 16
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific field by name. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%S%"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what id you want to start receiving results at. e.g. passing 137 here will only get you asset fields with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get fields at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 163
          }
        ],
        "responses": {
          "200": {
            "description": "Asset Suggested Fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "fieldID": {
                        "type": "integer"
                      },
                      "fieldType": {
                        "type": "string"
                      },
                      "fieldName": {
                        "type": "string"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "options": {
                        "type": "array",
                        "description": "Present only when fieldType is \"Dropdown\". Contains the list of available options for the dropdown field.",
                        "items": {
                          "$ref": "#/components/schemas/DropdownOption"
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "fieldID": 16,
                    "fieldType": "Text",
                    "fieldName": "Serial No.",
                    "locationID": 163
                  },
                  {
                    "fieldID": 42,
                    "fieldType": "Dropdown",
                    "fieldName": "Status",
                    "locationID": 163,
                    "options": [
                      {
                        "name": "Active"
                      },
                      {
                        "name": "Inactive"
                      }
                    ]
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "This request gets all possible fields an Asset can pick from when deciding which fields it should have.  \n\nTo understand this concept, let's pretend you have the following assets:  \n\nYour first Asset (a Truck) has the fields Make, Model, and VIN.  \n\nYour second Asset (a HVAC) has the fields Make, Model, and Serial Number.  \n\nThis would mean there are 4 suggested fields that exist:  Make, Model, VIN and Serial Number.  If I added a third new asset I could pick from any of the 4 suggested fields.\n\nSuggested fields are the full list of possible fields that can be added to assets at that location."
      }
    },
    "/v2/assets/fields/history": {
      "get": {
        "operationId": "getAssetsFieldsHistory",
        "summary": "Asset Field History",
        "parameters": [
          {
            "name": "assets",
            "in": "query",
            "description": "This parameter can be used to get a single Asset or a list of Assets in a comma-separated list.",
            "schema": {
              "type": "string"
            },
            "example": "4864, 4865"
          },
          {
            "name": "fields",
            "in": "query",
            "description": "This parameter can be used to get a single Asset Fields or a list of Asset Fields in a comma-separated list.",
            "schema": {
              "type": "string"
            },
            "example": "321, 202"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Asset Fields for Assets that were last edited after the unix timestamp passed into the start parameter. For example, all Assets that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1555105636
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Asset Fields for Assets that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1555105636
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a cursor that selects what id you want to start receiving results at. e.g. passing 137 here will only get you asset fields with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          }
        ],
        "responses": {
          "200": {
            "description": "Asset Field History",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "fieldID": {
                        "type": "integer"
                      },
                      "field": {
                        "type": "string"
                      },
                      "value": {
                        "type": "string",
                        "format": "utc-millisec"
                      },
                      "valueID": {
                        "type": "integer"
                      },
                      "dateUpdated": {
                        "type": "string",
                        "format": "utc-millisec"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "fieldID": 323,
                    "field": "Custom Field 4",
                    "value": "23",
                    "valueID": 24683,
                    "dateUpdated": "1528597316"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "Any time an Asset's field is changed an entry is inserted into a history.  \n\nThis request allows you to pull that information so you can see trends over time."
      }
    },
    "/v2/assets/{assetID}/fields": {
      "put": {
        "operationId": "putAssetsByAssetIDFields",
        "summary": "Attach Field to Asset",
        "responses": {
          "200": {
            "description": "Attach Field to Asset",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valueID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "valueID": "45350"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "This request attaches a Suggested Field to an Asset. The field and asset must belong to the same location.\n\nFor example, let's say I have an Asset called Truck - 001. This Truck doesn't have any Fields attached to it, but I want to track its Make so I can set that this Truck is a Dodge. This is the request I would use to attach the Make Field to the Truck and then I would use the Update Asset Field Value request to set it to Dodge.\n\nParameter: locationID, Type: Int, Required?: Required, Description: The ID of the Location the Asset exists at.\nParameter: fieldID, Type: Int, Required?: Required, Description: The ID of the existing Field to add to the Asset."
      },
      "parameters": [
        {
          "name": "assetID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "example": "{{assetID}}"
        }
      ]
    },
    "/v2/assets/fields/{valueID}": {
      "delete": {
        "operationId": "deleteAssetsFieldsByValueID",
        "summary": "Delete Asset Field",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "This request deletes a field attached to an Asset."
      },
      "parameters": [
        {
          "name": "valueID",
          "in": "path",
          "required": true,
          "description": "valueID of the field you are removing.",
          "schema": {
            "type": "integer"
          },
          "example": 45612
        }
      ],
      "patch": {
        "operationId": "patchAssetsFieldsByValueID",
        "summary": "Update Asset Field Value",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "This request updates the value of a Field that is attached to an Asset. \n\nParameter: value, Type: Varies depending on the Field's type, Required?: Required, Description: The value that will be written to the field, overwriting the previous value and creating an entry in the field history. \"value\" must correspond to the fieldType of the field. For example, if the field is a \"number\" fieldType, then \"value\" must be a number."
      }
    },
    "/v2/assets/logs/file/{fileID}": {
      "delete": {
        "operationId": "deleteAssetsLogsFileByFileID",
        "summary": "Delete Asset Log File",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Logs",
          "Files"
        ],
        "description": "This requests deletes a file attached to a log."
      },
      "parameters": [
        {
          "name": "fileID",
          "in": "path",
          "required": true,
          "description": "The ID of the file to be deleted.",
          "schema": {
            "type": "integer"
          },
          "example": 58
        }
      ]
    },
    "/v2/assets/{assetID}/logs/{logID}/file": {
      "put": {
        "operationId": "putAssetsByAssetIDLogsByLogIDFile",
        "summary": "Add Asset Log File",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Logs",
          "Files"
        ],
        "description": "This request adds files to a log.\n\nReturn data description\n\nfileID | The ID of the file attached to the log."
      },
      "parameters": [
        {
          "name": "assetID",
          "in": "path",
          "required": true,
          "description": "The ID of the asset the log belongs to.",
          "schema": {
            "type": "integer"
          },
          "example": 1
        },
        {
          "name": "logID",
          "in": "path",
          "required": true,
          "description": "The ID of the log to attach the file to.",
          "schema": {
            "type": "integer"
          },
          "example": 7257
        }
      ]
    },
    "/v2/assets/{assetID}/logs": {
      "get": {
        "operationId": "getAssetsByAssetIDLogs",
        "summary": "Asset Logs",
        "parameters": [
          {
            "name": "logs",
            "in": "query",
            "description": "This parameter is used to only get specific logs. This parameter accepts a comma delimited list of logIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 16
          },
          {
            "name": "users",
            "in": "query",
            "description": "This parameter is used to only get logs created by specific users. This parameter accepts a comma delimited list of userIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 341
          },
          {
            "name": "logEntry",
            "in": "query",
            "description": "This is a parameter used to string search for manual log entry. This parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%bro%"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get logs that were last edited after the unix timestamp passed into the start parameter. ",
            "schema": {
              "type": "integer"
            },
            "example": 1506274400
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get logs that were last edited before the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1506274900
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what ID you want to start receiving results at. ",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Asset Logs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LogEntry"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Logs"
        ],
        "description": "This request returns logs created manually by users and automatically created (where userID=0) by certain actions taken on the asset. Logs related to tasks completed on an Asset will not be returned.\n\n**Note:** this endpoint supports pagination. Please refer to the [**Pagination**](#pagination) section for more information.\n\nReturn data description\n\nlogID | The unique logID of the log.\ndateCreated | The date the log was created as a UNIX timestamp.\nassetD | The ID of the asset the log belongs to.\nlogEntry | The log entry for the asset.\nuserID | The ID of the user that created the log.\nlogFiles | An array of objects that have a fileID, fileName and a link that can used to download the files attached to the log. All links are only valid for 15 minutes, a new call will generate a new link."
      },
      "parameters": [
        {
          "name": "assetID",
          "in": "path",
          "required": true,
          "description": "The ID of the asset the log will be created for.",
          "schema": {
            "type": "integer"
          },
          "example": 1
        }
      ],
      "post": {
        "operationId": "postAssetsByAssetIDLogs",
        "summary": "New Asset Log",
        "responses": {
          "201": {
            "description": "New Asset Log",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "1000"
              },
              "X-RateLimit-Minute-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "240"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "997"
              },
              "X-RateLimit-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1684346312"
              },
              "X-RateLimit-Minute-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "237"
              },
              "X-RateLimit-Minute-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1684346312"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "logID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "logID": 29777
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Logs"
        ],
        "description": "This requests creates a manual log entry for an asset.\n\nuserID | Int | Optional | The ID of the user creating the log. If userID is not given a log entry with userID=0 will be created.\nlogEntry | String | Required | Details of the log.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userID": {
                    "type": "integer"
                  },
                  "logEntry": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "userID": 342,
                "logEntry": "Creating a log"
              }
            }
          }
        }
      }
    },
    "/v2/assets/logs/{logID}": {
      "patch": {
        "operationId": "patchAssetsLogsByLogID",
        "summary": "Update Asset Log",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Logs"
        ],
        "description": "This requests updates a manual log entry for an asset.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "logEntry": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "logEntry": "Changing log"
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "logID",
          "in": "path",
          "required": true,
          "description": "The ID of the log to be deleted.",
          "schema": {
            "type": "integer"
          },
          "example": 7257
        }
      ],
      "delete": {
        "operationId": "deleteAssetsLogsByLogID",
        "summary": "Delete Asset Log",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Logs"
        ],
        "description": "This requests deletes a manual log entry for an asset."
      }
    },
    "/v2/assets/fields/{fieldID}/options": {
      "get": {
        "operationId": "getAssetsFieldOptions",
        "summary": "Get Asset Dropdown Field Options",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "responses": {
          "200": {
            "description": "List of options for the dropdown field.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                },
                "example": {
                  "options": [
                    {
                      "name": "Active"
                    },
                    {
                      "name": "Inactive"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "Returns the list of available options for a Dropdown custom field on assets."
      },
      "post": {
        "operationId": "postAssetsFieldOptions",
        "summary": "Append Asset Dropdown Field Option(s)",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "title": "Single option",
                    "type": "object",
                    "required": [
                      "name"
                    ],
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "The name of the option to append."
                      }
                    }
                  },
                  {
                    "title": "Multiple options",
                    "type": "object",
                    "required": [
                      "options"
                    ],
                    "properties": {
                      "options": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "$ref": "#/components/schemas/DropdownOption"
                        },
                        "description": "List of options to append."
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Option(s) appended successfully. Returns the full updated options list. Existing options are preserved; only the new names are added.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "Appends one or more options to a Dropdown custom field on assets. Existing options are preserved. Returns 409 if any incoming name duplicates an existing option or another name in the same request (comparison is case-insensitive and trimmed). To replace the entire list, use PUT instead.\n"
      },
      "put": {
        "operationId": "putAssetsFieldOptions",
        "summary": "Replace Asset Dropdown Field Options",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "options"
                ],
                "properties": {
                  "options": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/DropdownOption"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Options replaced successfully. The full new options list is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "Replaces the entire list of options for a Dropdown custom field on assets. All existing options are discarded and replaced with the provided list. Returns 409 if the provided list contains duplicate names (case-insensitive). To append without replacing, use POST instead.\n"
      }
    },
    "/v2/assets/fields/{fieldID}/options/{optionName}": {
      "delete": {
        "operationId": "deleteAssetsFieldOption",
        "summary": "Delete Asset Dropdown Field Option",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          },
          {
            "name": "optionName",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The URL-encoded name of the option to delete."
          }
        ],
        "responses": {
          "204": {
            "description": "Option deleted successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Fields"
        ],
        "description": "Removes a single option from a Dropdown custom field on assets by name (URL-encoded). Returns 404 if the option does not exist."
      }
    },
    "/v2/assets/fields/batch/update": {
      "post": {
        "operationId": "postAssetsFieldsBatchUpdate",
        "summary": "Batch Update Asset Fields",
        "responses": {
          "200": {
            "description": "Some field values are not updated.",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "20"
              },
              "X-RateLimit-Minute-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "5"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "16"
              },
              "X-RateLimit-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1681935325"
              },
              "X-RateLimit-Minute-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "4"
              },
              "X-RateLimit-Minute-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1681935418"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "updates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "value": {
                            "type": "string"
                          },
                          "valueID": {
                            "type": "integer"
                          },
                          "success": {
                            "type": "boolean"
                          }
                        }
                      }
                    },
                    "success": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "updates": [
                    {
                      "value": "Fix this",
                      "valueID": 43676,
                      "success": true
                    },
                    {
                      "value": "31",
                      "valueID": 27050,
                      "success": true
                    },
                    {
                      "value": "Integrated Module",
                      "valueID": 24898,
                      "success": true
                    },
                    {
                      "value": "94",
                      "valueID": 46456,
                      "success": true
                    },
                    {
                      "value": "57",
                      "valueID": 46457,
                      "success": true
                    },
                    {
                      "value": "31",
                      "valueID": 46458,
                      "success": true
                    },
                    {
                      "value": "100",
                      "valueID": 45474,
                      "success": true
                    },
                    {
                      "value": "12",
                      "valueID": 45476,
                      "success": true
                    },
                    {
                      "value": "22",
                      "valueID": 45477,
                      "success": true
                    },
                    {
                      "value": "33",
                      "valueID": 45478,
                      "success": true
                    },
                    {
                      "value": "59",
                      "valueID": 45479,
                      "success": true
                    },
                    {
                      "value": "Five",
                      "valueID": 46014,
                      "success": false
                    },
                    {
                      "value": "9",
                      "valueID": 46460,
                      "success": true
                    },
                    {
                      "value": "9",
                      "valueID": 46461,
                      "success": true
                    }
                  ],
                  "success": false
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Batch"
        ],
        "description": "This request will update multiple asset fields values at a time. The request expects an array of asset fields values. The array needs to have atleast two asset field values and atmost 100 asset field values. The request expects an array made up of asset field values that need to be updated. Only asset fields values of type Text (1), Date (2), Number (5) and Currency (6) can be updated using this request.\n\nThe response returns `{ sucess:true }` if all field values are updated successfully. The response returns `{ sucess: false }` and an `updates` array that gives details of which field values were updated and the `reason` for field values that were not updated successfully. Please refer to the examples for more information.\n\nvalueID | Integer | Required | The valueID of the asset field value\nvalue | Based on the type of value | Required | The value that needs to be updated",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "value": {
                      "type": "string"
                    },
                    "valueID": {
                      "type": "integer"
                    }
                  }
                }
              },
              "example": [
                {
                  "value": "Fix this",
                  "valueID": 43676
                },
                {
                  "value": "31",
                  "valueID": 27050
                },
                {
                  "value": "Integrated Module",
                  "valueID": 24898
                },
                {
                  "value": "94",
                  "valueID": 46456
                },
                {
                  "value": "57",
                  "valueID": 46457
                },
                {
                  "value": "31",
                  "valueID": 46458
                },
                {
                  "value": "100",
                  "valueID": 45474
                },
                {
                  "value": "12",
                  "valueID": 45476
                },
                {
                  "value": "22",
                  "valueID": 45477
                },
                {
                  "value": "33",
                  "valueID": 45478
                },
                {
                  "value": "59",
                  "valueID": 45479
                },
                {
                  "value": "5",
                  "valueID": 46014
                },
                {
                  "value": "9",
                  "valueID": 46460
                },
                {
                  "value": "9",
                  "valueID": 46461
                }
              ]
            }
          }
        }
      }
    },
    "/v2/assets/parts": {
      "get": {
        "operationId": "getAssetsParts",
        "summary": "Asset Parts",
        "parameters": [
          {
            "name": "assets",
            "in": "query",
            "description": "This parameter is used to only get specific Assets. This parameter expects a comma delimited list of Asset IDs.",
            "schema": {
              "type": "string"
            },
            "example": "172,253"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 3
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 3
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what ID you want to start receiving results at. Without ordering, this will return results with an ID greater than the value of cursor. With ordering, this will return results starting at the next item in the order, regardless of whether its ID is greater than or lesser than the value of cursor.",
            "schema": {
              "type": "integer"
            },
            "example": 49
          },
          {
            "name": "parts",
            "in": "query",
            "description": "This parameter is used to only get specific Parts. This parameter accepts a comma delimited list of part IDs.",
            "schema": {
              "type": "string"
            },
            "example": "46,172"
          },
          {
            "name": "relations",
            "in": "query",
            "description": "This parameter is used to only get specific relations. This parameter expects a comma delimited list of relation IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,10"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get relations that were last edited after the unix timestamp passed into the start parameter. For example, all relations that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1334570141
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get relations that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1784570141
          }
        ],
        "responses": {
          "200": {
            "description": "Asset Parts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/AssetPart"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets",
          "Parts"
        ],
        "description": "This request returns a list of Part Asset Relations with top level information such as part, asset, qty, last edited, etc.\n\n**Note:** this endpoint supports pagination. Please refer to the [Pagination](#pagination) section for more information.\n\nReturn data description\n\nrelationID | The Relations ID. e.g. 1\npartID | The ID of the Part in this Relation\nassetID | The ID of the Asset in this Relation\nqty | The qty of the Part related to this Asset\ncreatedAt | The unix timestamp at which this Relation was created\nlastEdited | The unix timestamp at which this Relation last saw a change\nassociationType | The method used to create this Relation. At this time, only \"manual\" is supported"
      }
    },
    "/v2/assets": {
      "get": {
        "operationId": "getAssets",
        "summary": "Assets",
        "parameters": [
          {
            "name": "assets",
            "in": "query",
            "description": "This parameter is used to only get specific Assets. This parameter expects a comma delimited list of Asset IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "name",
            "in": "query",
            "description": "This is a parameter used to string search for a name or partial name of an asset this parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%test%"
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get Assets at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 73
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Assets that were last edited after the unix timestamp passed into the start parameter. For example, all Assets that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1541796014
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Assets that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1541796014
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what ID you want to start receiving results at. Without ordering, this will return results with an ID greater than the value of cursor. With ordering, this will return results starting at the next item in the order, regardless of whether its ID is greater than or lesser than the value of cursor.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "parentAssetID",
            "in": "query",
            "description": "This parameter can be used to get asset(s) children using the Parent's ID. This parameter accepts a comma delimited list of Asset IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 2317
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "This parameter is used to order results by their lastEdited property instead of the default ordering by ascending assetID. CANNOT be provided alongside the cursor parameter. to paginate in this ordering, use the start or end parameters.",
            "schema": {
              "type": "string"
            },
            "example": "-lastEdited"
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "geoLocation",
            "in": "query",
            "description": "This parameter is used to filter results that contain a geoLocation property. By default it is false and will return **all** assets with and without geoLocation property. If true, it will only return assets with a geoLocation property.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          }
        ],
        "responses": {
          "200": {
            "description": "Pagination using Page & Limit",
            "headers": {
              "Last-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/assets/?limit=5&orderBy=-lastEdited&page=279"
              },
              "Next-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/assets/?limit=5&orderBy=-lastEdited&page=4"
              },
              "Previous-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/assets/?limit=5&orderBy=-lastEdited&page=2"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Asset"
                  }
                },
                "example": [
                  {
                    "assetID": 10836,
                    "name": "Health Berkshire",
                    "startedOn": 1632949149,
                    "lastEdited": 1632949149,
                    "parentAssetID": 0,
                    "locationID": 205,
                    "hoursPerWeek": 40,
                    "meta": {
                      "fields": "/v2/assets/fields/?assets=10836",
                      "tasks": "/v2/tasks/?assets=10836"
                    },
                    "workRequestPortal": "https://app.limblestaging.com/#!/problem/fdle6w36/205/10836",
                    "image": []
                  },
                  {
                    "assetID": 10835,
                    "name": "Walks",
                    "startedOn": 1632949148,
                    "lastEdited": 1632949149,
                    "parentAssetID": 0,
                    "locationID": 205,
                    "hoursPerWeek": 40,
                    "meta": {
                      "fields": "/v2/assets/fields/?assets=10835",
                      "tasks": "/v2/tasks/?assets=10835"
                    },
                    "workRequestPortal": "https://app.limblestaging.com/#!/problem/fdle6w36/205/10835",
                    "image": []
                  },
                  {
                    "assetID": 10834,
                    "name": "Executive Springs Phased",
                    "startedOn": 1632949148,
                    "lastEdited": 1632949148,
                    "parentAssetID": 0,
                    "locationID": 205,
                    "hoursPerWeek": 40,
                    "meta": {
                      "fields": "/v2/assets/fields/?assets=10834",
                      "tasks": "/v2/tasks/?assets=10834"
                    },
                    "workRequestPortal": "https://app.limblestaging.com/#!/problem/fdle6w36/205/10834",
                    "image": []
                  },
                  {
                    "assetID": 10833,
                    "name": "functionalities",
                    "startedOn": 1632949148,
                    "lastEdited": 1632949148,
                    "parentAssetID": 0,
                    "locationID": 205,
                    "hoursPerWeek": 40,
                    "meta": {
                      "fields": "/v2/assets/fields/?assets=10833",
                      "tasks": "/v2/tasks/?assets=10833"
                    },
                    "workRequestPortal": "https://app.limblestaging.com/#!/problem/fdle6w36/205/10833",
                    "image": []
                  },
                  {
                    "assetID": 10832,
                    "name": "AGP magnetic Handmade",
                    "startedOn": 1632949148,
                    "lastEdited": 1632949148,
                    "parentAssetID": 0,
                    "locationID": 205,
                    "hoursPerWeek": 40,
                    "meta": {
                      "fields": "/v2/assets/fields/?assets=10832",
                      "tasks": "/v2/tasks/?assets=10832"
                    },
                    "workRequestPortal": "https://app.limblestaging.com/#!/problem/fdle6w36/205/10832",
                    "image": []
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets"
        ],
        "description": "This request returns a list of Assets with top level information such as name, last edited, etc.\n\n**Note:** this endpoint supports pagination. Please refer to the [Pagination](#pagination) section for more information.\n\nReturn data description\n\nmeta | Requests to gather more information on an Asset such as Fields for the Asset or what Tasks are assigned to the Asset\nstartedOn | The date when this Asset was started on. This property is used to help determine runtime which is used in MTBF.\nlastEdited | A UNIX timestamp of when this Asset was last edited.\nparentAssetID | The Asset that is the parent of this Asset. If the value is 0 that means this Asset does not have a parent.\nlocationID | The ID of the location this asset is located at.\nhoursPerWeek | The number of hours this Asset runs per week. This is used to determine runtime which is used in MTBF. If the value is -1 then the Asset uses the Location's hoursPerWeek setting.\nworkRequestPortal | The url work requestors can use to submit problems with this Asset.\nimage | Array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link.\ngeoLocation | The location of an asset on a Map."
      },
      "post": {
        "operationId": "postAssets",
        "summary": "New Asset",
        "responses": {
          "201": {
            "description": "New Asset",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/assets/?assets=10728"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "assetID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "assetID": "10728"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets"
        ],
        "description": "This request creates a new blank Asset.\n\nParameter: name, Type: String, Required?: Required, Description: The new name of the Asset.\nParameter: hoursPerWeek, Type: Integer, Required?: Optional, Description: The new hours of operation per week for this Asset. Use -1 to disable this feature.\nParameter: parentAssetID, Type: Int, Required?: Optional, Description: The asset's parent. This makes it so assets can be nested in the web application.\nParameter: locationID, Type: Int, Required?: Required, Description: The ID of the location this asset is located at.\nParameter: geoLocation, Type: geoJSON, Required?: Optional, Description: The geoJSON Feature object that can be used to locate an asset on a Map."
      }
    },
    "/v2/assets/{assetID}": {
      "delete": {
        "operationId": "deleteAssetsByAssetID",
        "summary": "Delete Asset",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets"
        ],
        "description": "This request removes an Asset from your Limble account."
      },
      "patch": {
        "operationId": "patchAssetsByAssetID",
        "summary": "Patch Asset",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets"
        ],
        "description": "This request updates an Asset's top level information. See Update Asset Field Value to update an Asset Field's value.\n\nname | String | Optional | The new name of the Asset.\nhoursPerWeek | Integer | Optional | The new hours of operation per week for this Asset. Use -1 to disable this feature and have it default to the Locations hours of operation.\nparentAssetID | Int | Optional | The asset's parent. This must be another asset ID and is used to display an Asset hierarchy. You can not have assets be their own ancestor.\nstartedOn | Int | Optional | The new date this Asset was created. Must be a unix, timestamp.\ngeoLocation | geoJSON | Optional | The geoJSON Feature object that can be used to locate an asset on a Map. To remove geoLocation from an Asset pass an empty object ( {})."
      },
      "parameters": [
        {
          "name": "assetID",
          "in": "path",
          "required": true,
          "description": "The value of the asset that needs to be updated",
          "schema": {
            "type": "integer"
          },
          "example": 10728
        }
      ]
    },
    "/v2/assets/{assetID}/move": {
      "patch": {
        "operationId": "patchAssetsByAssetIDMove",
        "summary": "Move Asset to another Location",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "2000"
              },
              "X-RateLimit-Minute-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "240"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "1995"
              },
              "X-RateLimit-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1684352145"
              },
              "X-RateLimit-Minute-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "238"
              },
              "X-RateLimit-Minute-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1684352297"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "moved": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "moved": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Assets"
        ],
        "description": "This request moves an existing asset from it's current location to another location. An parent asset that has one or more children assets cannot be moved.\n\nA child asset can be moved and will be created as a top level asset in the other location.\n\nlocationID | Int | Required | The locationID of the location the asset needs to be moved to.\ntransferParts | boolean | Optional | A boolean representing whether parts associated with the asset should be moved to the location as well., Defaults to true.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "locationID": {
                    "type": "integer"
                  },
                  "transferParts": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "locationID": 73,
                "transferParts": true
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "assetID",
          "in": "path",
          "required": true,
          "description": "The value of the asset that needs to be moved",
          "schema": {
            "type": "integer"
          },
          "example": 14113
        }
      ]
    },
    "/v2/locations": {
      "post": {
        "operationId": "postLocations",
        "summary": "New Location",
        "responses": {
          "201": {
            "description": "New Location",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/locations/?locations=2187"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "locationID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "locationID": "2187"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Locations"
        ],
        "description": "This request creates a new Location.\n\n**Body parameter descriptions**\n\nname | String | Required | The new name of the Location.\ntimezone | string | Required | The timezone this location resides in. This accepts a standard tz database name, see here.\nphone | string | Required | The phone number associated with this location.\nweeklyOperationHours | Int | Optional | The hours per week this location operates.\naddress | string | Optional | The physical address of this location.\naddress2 | string | Optional | The physical address of this location.\ngeoLocation | geoJSON | Optional | The geoJSON Feature object that can be used to locate a Limble location on a Map.\nextraNotificationsEmail | string | Optional | Include an email address to receive notifications for the location.\ncurrencyCode | string | Optional | The ISO code for the currency at this location. For example: \"USD\".\nregionID | integer | Optional | The region to assign this location to. Omit to leave unassigned. Use 0 for unassigned."
      },
      "get": {
        "operationId": "getLocations",
        "summary": "Locations",
        "parameters": [
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get locations in the list provided. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 73
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific locations by name. This parameter expects a string full name of a location or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%NY%"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what locationID you want to start receiving results at. e.g. passing 137 here will only get you locations with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "regions",
            "in": "query",
            "description": "This parameter is used to get locations that belong to a region.\nThis parameter expects a regionID a location may belong to.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "geoLocation",
            "in": "query",
            "description": "This parameter is used to filter results that contain a geoLocation property. By default it is false and will return **all** locations with and without geoLocation property. If true, it will only return locations with a geoLocation property.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "Locations",
            "headers": {
              "Last-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/locations/?locations=73&name=%NY%&limit=1&page=1"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Location"
                  }
                },
                "example": [
                  {
                    "locationID": 73,
                    "name": "NY - Facility 1",
                    "regionID": 0,
                    "timezone": "America/Denver",
                    "weeklyOperationHours": 40,
                    "address": null,
                    "address2": null,
                    "phone": null,
                    "metaField1": null,
                    "metaField2": null,
                    "metaField3": null,
                    "geoLocation": null,
                    "workRequestPortal": "https://app.limblestaging.com/loc-problem/fdle6w36/73",
                    "currencyCode": "USD"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Locations"
        ],
        "description": "This request returns your Locations in Limble.\n\n**Note:** this endpoint supports pagination. Please refer to the [**Pagination**](https://desktop.postman.com/?desktopVersion=9.31.0&userId=16480856&teamId=206430) section for more information.\n\n**Note:** this endpoint supports pagination. Please refer to the [Pagination](https://desktop.postman.com/?desktopVersion=9.31.0&userId=16480856&teamId=206430) section for more information.\n\nEndFragment\n\n**Return data description**\n\nname | The name of the Location\nregionID | The ID of the region the Location is part of. A regionID of 0 means the location is not a part of any region.\ntimezone | The Timezone the location is set at.List of Timezones\nweeklyOperationHours | The number of hours your Assets run at this location per week. This is used to help calculate MTBF.\nworkRequestPortal | This is a URL you can use to submit Work Requests to this Location.\ngeoLocation | The location of a Limble location on a Map.\ncurrencyCode | The ISO code for the currency at this location."
      }
    },
    "/v2/locations/{locationID}": {
      "patch": {
        "operationId": "patchLocationsByLocationID",
        "summary": "Update Location",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Locations"
        ],
        "description": "This request updates a Location.\n\n**Body parameter descriptions**\n\nname | String | Optional | The new name of the Location.\ntimezone | string | Optional | The timezone this location resides in. This accepts a standard tz database name, see here.\nphone | string | Optional | The phone number associated with this location.\nweeklyOperationHours | Int | Optional | The number of hours your Assets run at this location per week. This is used to help calculate MTBF.\naddress | string | Optional | The physical address of this location.\naddress2 | string | Optional | The physical address of this location.\ngeoLocation | geoJSON | Optional | The geoJSON Feature object that can be used to locate a Limble location on a Map., To remove geoLocation from a Limble Location pass an empty object ( {}).\ncurrencyCode | string | Optional | The ISO code for the currency at this location. For example: \"USD\".\nregionID | integer | Optional | Assign, reassign, or unassign this location's region. Use 0 to unassign."
      },
      "parameters": [
        {
          "name": "locationID",
          "in": "path",
          "required": true,
          "description": "locationID of the location you are removing.",
          "schema": {
            "type": "string"
          },
          "example": "{{locationID}}"
        }
      ],
      "delete": {
        "operationId": "deleteLocationsByLocationID",
        "summary": "Delete Location",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Locations"
        ],
        "description": "This request removes a Location from your Limble account.  This will also remove everything else at this locaiton including Assets, Parts, Tasks, etc.  Be VERY careful using this call."
      }
    },
    "/v2/parts/{partID}/image": {
      "put": {
        "operationId": "putPartsByPartIDImage",
        "summary": "Add Part Image",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Images"
        ],
        "description": "This request adds the main image for a Part."
      },
      "parameters": [
        {
          "name": "partID",
          "in": "path",
          "required": true,
          "description": "partID of the part you are removing the image for.",
          "schema": {
            "type": "string"
          },
          "example": "{{partID}}"
        }
      ],
      "delete": {
        "operationId": "deletePartsByPartIDImage",
        "summary": "Delete Part Image",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Images"
        ],
        "description": "This request removes the main image from a Part."
      }
    },
    "/v2/parts/categories": {
      "post": {
        "operationId": "postPartsCategories",
        "summary": "Create Part Category",
        "responses": {
          "201": {
            "description": "Create Part Category",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/parts/categories/?categories=21"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "categoryID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "categoryID": 21
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Categories"
        ],
        "description": "Creates a part category to help you organize your parts.\n\nParameter: name, Type: string, Required?: Required, Description: The name of your new part category (i.e. \"Lawn Mower Parts\")"
      },
      "get": {
        "operationId": "getPartsCategories",
        "summary": "Get Categories",
        "parameters": [
          {
            "name": "categories",
            "in": "query",
            "description": "This parameter is used to only get specific part categories. This parameter accepts a comma delimited list of categoryIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to string search part categories names either partial or full name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "Electronics"
          }
        ],
        "responses": {
          "200": {
            "description": "Get Categories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "categoryID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "categoryID": 1,
                    "name": "Electronics"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Categories"
        ]
      }
    },
    "/v2/parts/categories/{categoryID}": {
      "patch": {
        "operationId": "patchPartsCategoriesByCategoryID",
        "summary": "Update Part Category",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Categories"
        ],
        "description": "This request updates a Part Category's name.\n\nParameter: name, Type: string, Required?: Required, Description: The name of your new part category (i.e. \"Filters\")"
      },
      "parameters": [
        {
          "name": "categoryID",
          "in": "path",
          "required": true,
          "description": "categoryID of the category you wish to remove.",
          "schema": {
            "type": "string"
          },
          "example": "{{categoryID}}"
        }
      ],
      "delete": {
        "operationId": "deletePartsCategoriesByCategoryID",
        "summary": "Delete Part Category",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Categories"
        ],
        "description": "This request will remove the Part Category from all Parts and from possible Categories."
      }
    },
    "/v2/parts/fields": {
      "get": {
        "operationId": "getPartsFields",
        "summary": "Part Fields",
        "parameters": [
          {
            "name": "fields",
            "in": "query",
            "description": "This parameter is used to only get specific fields by ID. This parameter expects a comma delimited list of fieldIDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2"
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific field by name. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%text%"
          },
          {
            "name": "parts",
            "in": "query",
            "description": "This parameter is used to only get part fields for a specific Part. This parameter expects a partID.",
            "schema": {
              "type": "integer"
            },
            "example": 2992
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get part fields for parts that were last edited after the unix timestamp passed into the start parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1580016200
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get parts fields for part fields that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1610602900
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what fieldID you want to start receiving results at. e.g. passing 137 here will only get you vendor fields with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 5
          },
          {
            "name": "value",
            "in": "query",
            "description": "This parameter is used to only get specific field by value. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%3%"
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "string"
            },
            "example": "38469,38472"
          },
          {
            "name": "values",
            "in": "query",
            "description": "This parameter is used to get part fields by their valueID. This parameter expects a comma delimited list of Value IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 27
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "Part Fields",
            "headers": {
              "x-ratelimit-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "4000"
              },
              "x-ratelimit-minute-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "360"
              },
              "x-ratelimit-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "3987"
              },
              "x-ratelimit-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1719246455"
              },
              "x-ratelimit-minute-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "359"
              },
              "x-ratelimit-minute-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1719247579"
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "example": "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "fieldID": {
                        "type": "integer"
                      },
                      "partID": {
                        "type": "integer"
                      },
                      "fieldName": {
                        "type": "string"
                      },
                      "value": {
                        "type": "null"
                      },
                      "valueID": {
                        "type": "integer"
                      },
                      "fieldType": {
                        "type": "string"
                      },
                      "lastEdited": {
                        "type": "integer"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "files": {
                        "type": "array"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "fieldID": 16706,
                    "partID": 1,
                    "fieldName": "newFields-Part",
                    "value": null,
                    "valueID": 6048543,
                    "fieldType": "Text",
                    "lastEdited": 1718405951,
                    "locationID": 38469,
                    "files": []
                  },
                  {
                    "fieldID": 30021,
                    "partID": 1,
                    "fieldName": "height",
                    "value": null,
                    "valueID": 11328670,
                    "fieldType": "Number",
                    "lastEdited": 1718405951,
                    "locationID": 38469,
                    "files": []
                  },
                  {
                    "fieldID": 30022,
                    "partID": 1,
                    "fieldName": "width",
                    "value": null,
                    "valueID": 11328671,
                    "fieldType": "Number",
                    "lastEdited": 1718405951,
                    "locationID": 38469,
                    "files": []
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "This request gets detailed information about custom set Part Fields.\n\nThis request will return an array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link.\n\n**Note:** this endpoint supports pagination. Please refer to the [**Pagination**](#pagination) section for more information."
      },
      "post": {
        "operationId": "postPartsFields",
        "summary": "New Part Suggested Field",
        "responses": {
          "201": {
            "description": "New Vendor Suggested Field",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/vendors/fields/?fields=5"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "fieldID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "fieldID": "5"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "This request adds a new Field to the list of Suggested Fields that can later be attached to Parts.\n\nParameter: locationID, Type: Int, Required?: Required, Description: The location ID of the Location to add the new Field to.\nParameter: name, Type: String, Required?: Required, Description: The name of the new Field. Some custom field names such as \"Part Name\" are not allowed and reserved for internal use. This will result in a 409 error.\nParameter: fieldType, Type: Int, Required?: Required, Description: The type of the new Field. You can choose from Text (1), Date (2), Pictures (3), Documents (4), Number (5), Currency (6), Dropdown (7).\n\nParameter: options, Type: Array of objects with a \"name\" property, Required?: Optional (only valid when fieldType is 7), Description: Initial list of options for a Dropdown field. Each option must have a \"name\" string."
      }
    },
    "/v2/parts/fields/suggested": {
      "get": {
        "operationId": "getPartsFieldsSuggested",
        "summary": "Part Suggested Fields",
        "parameters": [
          {
            "name": "fields",
            "in": "query",
            "description": "This parameter can be used to get a single Part Fields or a list of Part Fields in a comma-separated list.",
            "schema": {
              "type": "string"
            },
            "example": "1,2"
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific field by name. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%text%"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what fieldID you want to start receiving results at. e.g. passing 137 here will only get you vendor fields with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Part Suggested Fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "fieldID": {
                        "type": "integer"
                      },
                      "fieldType": {
                        "type": "string"
                      },
                      "fieldName": {
                        "type": "string"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "options": {
                        "type": "array",
                        "description": "Present only when fieldType is \"Dropdown\". Contains the list of available options for the dropdown field.",
                        "items": {
                          "$ref": "#/components/schemas/DropdownOption"
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "fieldID": 1,
                    "fieldType": "Pictures",
                    "fieldName": "pic",
                    "locationID": 330
                  },
                  {
                    "fieldID": 2,
                    "fieldType": "Text",
                    "fieldName": "testText",
                    "locationID": 330
                  },
                  {
                    "fieldID": 3,
                    "fieldType": "Dropdown",
                    "fieldName": "Condition",
                    "locationID": 330,
                    "options": [
                      {
                        "name": "New"
                      },
                      {
                        "name": "Used"
                      }
                    ]
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "This request gets all possible fields a Part can pick from when deciding which fields it should have."
      }
    },
    "/v2/parts/fields/{valueID}": {
      "patch": {
        "operationId": "patchPartsFieldsByValueID",
        "summary": "Update Part Field Value",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "This request updates a Part's field value.\n\nParameter: value, Type: Depends on fieldType, Required?: Required, Description: The value that will be written to the field. \"value\" must correspond to the fieldType of the field. For example, if the field is a \"number\" fieldType, then \"value\" must be a number."
      },
      "parameters": [
        {
          "name": "valueID",
          "in": "path",
          "required": true,
          "description": "valueID of the field you are removing.",
          "schema": {
            "type": "integer"
          },
          "example": 172
        }
      ],
      "delete": {
        "operationId": "deletePartsFieldsByValueID",
        "summary": "Delete Part Field",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "This request deletes a custom field attached to a Part."
      }
    },
    "/v2/parts/{partID}/fields": {
      "put": {
        "operationId": "putPartsByPartIDFields",
        "summary": "Attach Field to Part",
        "responses": {
          "201": {
            "description": "Attach Field to Vendor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valueID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "valueID": "4"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "This request attaches a Suggested Field to a Part."
      },
      "parameters": [
        {
          "name": "partID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1030
        }
      ]
    },
    "/v2/parts/{partID}/logs": {
      "get": {
        "operationId": "getPartsByPartIDLogs",
        "summary": "Part Logs",
        "parameters": [
          {
            "name": "logs",
            "in": "query",
            "description": "This parameter is used to only get specific logs. This parameter accepts a comma delimited list of logIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 21524
          },
          {
            "name": "sources",
            "in": "query",
            "description": "This parameter is used to only get logs for a specific sourceID. This parameter accepts a comma delimited list of sourceIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 4
          },
          {
            "name": "users",
            "in": "query",
            "description": "This parameter is used to only get logs created by specific users. This parameter accepts a comma delimited list of userIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 340
          },
          {
            "name": "logEntry",
            "in": "query",
            "description": "This is a parameter used to string search for manual log entry (sourceID: 4). This parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%new%"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get logs that were last edited after the unix timestamp passed into the start parameter. ",
            "schema": {
              "type": "integer"
            },
            "example": 1663018000
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get logs that were last edited before the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1663018900
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 10
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what ID you want to start receiving results at. ",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Part Logs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PartLogEntry"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Logs"
        ],
        "description": "This request returns the log entries for a part.\n\n**Note:** this endpoint supports pagination. Please refer to the [Pagination](#pagination) section for more information.\n\nReturn data description\n\nlogID | The unique logID of the log.\ndateCreated | The date the log was created as a UNIX timestamp.\npartID | The partID the log belongs to.\nsourceID | The sourceID of the source of the log. The sourceID can be as follows:, 1: Part name was changed., 2: Part Number was changed., 3: Parts were added/removed., 4: Manual log entry., 5: Parts were used on a Task., 6: Part Price was changed., 7: Stale threshold was manually changed., 8: Part Qty threshold was manually changed., 11: Part Qty threshold status was changed., 13: Part Location was changed., 14: Part Vendor was changed., 15: Part Image was changed., 18: Parts were received on a Bill., 19: Part Maximum Part Qty was manually changed., 20: Some of a PO Item Received Qty was used during manual Part Qty adjustment\nlogEntry | The log entry for the part.\nuserID | The ID of the user that created the log.\nassociatedID | The ID of the item associated with this log, if any. Current examples include:, sourceID: 5, associatedID type: Task, sourceID: 18, associatedID type: Bill, sourceID: 20, associatedID type: Bill"
      },
      "parameters": [
        {
          "name": "partID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 159
        }
      ],
      "post": {
        "operationId": "postPartsByPartIDLogs",
        "summary": "New Part Log",
        "responses": {
          "201": {
            "description": "New Part Log",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "1000"
              },
              "X-RateLimit-Minute-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "240"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "994"
              },
              "X-RateLimit-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1684346312"
              },
              "X-RateLimit-Minute-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "239"
              },
              "X-RateLimit-Minute-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1684346687"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "logID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "logID": 43002
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Logs"
        ],
        "description": "This request creates a manual log entry for a part.\n\nThis request adds a new Field to the list of Suggested Fields that can later be attached to Parts.\n\nuserID | Int | Required | The ID of the user creating the log.\nlogEntry | String | Required | Details of the log.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userID": {
                    "type": "integer"
                  },
                  "logEntry": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "userID": 342,
                "logEntry": "Creating a log"
              }
            }
          }
        }
      }
    },
    "/v2/parts/logs/{logID}": {
      "patch": {
        "operationId": "patchPartsLogsByLogID",
        "summary": "Update Part Log",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Logs"
        ],
        "description": "This requests updates a manual log entry. Only logs with a sourceID=4 can be updated.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "logEntry": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "logEntry": "Changing log"
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "logID",
          "in": "path",
          "required": true,
          "description": "The ID of the log to be deleted.",
          "schema": {
            "type": "integer"
          },
          "example": 21524
        }
      ],
      "delete": {
        "operationId": "deletePartsLogsByLogID",
        "summary": "Delete Part Log",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Logs"
        ],
        "description": "This request deletes manual log entries (sourceID=4)."
      }
    },
    "/v2/parts/logs": {
      "get": {
        "operationId": "getPartsLogs",
        "summary": "All Part Logs",
        "parameters": [
          {
            "name": "logs",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "sources",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 20
          },
          {
            "name": "users",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "logEntry",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "start",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "end",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "parts",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 5
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "All Part Logs",
            "headers": {
              "x-ratelimit-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "4000"
              },
              "x-ratelimit-minute-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "360"
              },
              "x-ratelimit-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "3992"
              },
              "x-ratelimit-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1719246455"
              },
              "x-ratelimit-minute-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "359"
              },
              "x-ratelimit-minute-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1719247424"
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "example": "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "logID": {
                        "type": "integer"
                      },
                      "dateCreated": {
                        "type": "integer"
                      },
                      "partID": {
                        "type": "integer"
                      },
                      "sourceID": {
                        "type": "integer"
                      },
                      "logEntry": {
                        "type": "string"
                      },
                      "userID": {
                        "type": "integer"
                      },
                      "associatedID": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "logID": 72,
                    "dateCreated": 1715279617,
                    "partID": 1,
                    "sourceID": 20,
                    "logEntry": "1 used from Bill during Manual Qty adjustment.",
                    "userID": 230530,
                    "associatedID": 304723
                  },
                  {
                    "logID": 102,
                    "dateCreated": 1718406015,
                    "partID": 2,
                    "sourceID": 20,
                    "logEntry": "1 used from Bill during Manual Qty adjustment.",
                    "userID": 230530,
                    "associatedID": 323880
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Logs"
        ],
        "description": "This request returns all part logs across your Limble account.\n\n**Note:** this endpoint supports pagination. Please refer to the [Pagination](#pagination) section for more information.\n\nReturn data description\n\nlogID | The unique logID of the log.\ndateCreated | The date the log was created as a UNIX timestamp.\npartID | The partID the log belongs to.\nsourceID | The sourceID of the source of the log. The sourceID can be as follows:, 1: Part name was changed., 2: Part Number was changed., 3: Parts were added/removed., 4: Manual log entry., 5: Parts were used on a Task., 6: Part Price was changed., 7: Stale threshold was manually changed., 8: Part Qty threshold was manually changed., 11: Part Qty threshold status was changed., 13: Part Location was changed., 14: Part Vendor was changed., 15: Part Image was changed., 18: Parts were received on a Bill., 19: Part Maximum Part Qty was manually changed., 20. Some of a PO Item Received Qty was used during manual Part Qty adjustment\nlogEntry | The log entry for the part.\nuserID | The ID of the user that created the log.\nassociatedID | The ID of the item associated with this log, if any. Current examples include:, sourceID: 5, associatedID type: Task, sourceID: 18, associatedID type: Bill, sourceID: 20, associatedID type: Bill"
      }
    },
    "/v2/parts/{partID}/purchasables": {
      "get": {
        "operationId": "getPartsByPartIDPurchasables",
        "summary": "Get Purchasables",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "nameStartsWith",
            "in": "query",
            "description": "Filter purchasables that have a name which starts with this string.",
            "schema": {
              "type": "string"
            },
            "example": "Box of"
          }
        ],
        "responses": {
          "200": {
            "description": "Get Purchasables",
            "headers": {
              "x-ratelimit-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "4000"
              },
              "x-ratelimit-minute-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "360"
              },
              "x-ratelimit-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "3992"
              },
              "x-ratelimit-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1734557517"
              },
              "x-ratelimit-minute-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "359"
              },
              "x-ratelimit-minute-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1734560048"
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "example": "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "purchasableID": {
                        "type": "integer"
                      },
                      "partID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      },
                      "size": {
                        "type": "integer"
                      },
                      "orderUnitCode": {
                        "type": "string"
                      },
                      "sizeUnitCode": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "purchasableID": 10,
                    "partID": 1,
                    "name": "Drum of 10 liters",
                    "size": 10,
                    "orderUnitCode": "drum",
                    "sizeUnitCode": "liter"
                  },
                  {
                    "purchasableID": 15,
                    "partID": 1,
                    "name": "By the gallon",
                    "size": 1,
                    "orderUnitCode": "gallon",
                    "sizeUnitCode": "gallon"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Purchasables"
        ],
        "description": "This endpoint makes an HTTP GET request to retrieve a part's purchasable data. The response of this request is documented as a JSON schema.\n\nReturn data description\n\n| **Property** | **Description** |\n| --- | --- |\n| partID | The ID of the part the purchasable belongs to. |\n| name | The name of the purchasable. |\n| size | The size of the purchasable. |\n| orderUnitCode | The unit that describes how this purchasable is ordered. E.g. \"by the box\", or \"by the foot\". |\n| sizeUnitCode | The unit that qualifies the size value. E.g. this tells you whether this purchasable is 10 liters, or cans, or feet, etc. |"
      },
      "parameters": [
        {
          "name": "partID",
          "in": "path",
          "required": true,
          "description": "The ID of the part you need purchasables for.",
          "schema": {
            "type": "integer"
          },
          "example": 11
        }
      ]
    },
    "/v2/parts/vendors/associations": {
      "get": {
        "operationId": "getPartsVendorsAssociations",
        "summary": "Get Part Vendor Associations",
        "parameters": [
          {
            "name": "parts",
            "in": "query",
            "description": "This parameter is used to only get associations for specific parts. This parameter accepts a comma delimited list of part IDs.",
            "schema": {
              "type": "string"
            },
            "example": "158,159"
          },
          {
            "name": "vendors",
            "in": "query",
            "description": "This parameter is used to only get associations for specific vendors. This parameter accepts a comma delimited list of vendor IDs.",
            "schema": {
              "type": "string"
            },
            "example": "12,34"
          },
          {
            "name": "vendorPartNumber",
            "in": "query",
            "description": "This parameter is used to search for associations by vendor part number. This parameter expects a string with the wildcard % for partial matching.",
            "schema": {
              "type": "string"
            },
            "example": "%ABC%"
          },
          {
            "name": "vendorName",
            "in": "query",
            "description": "This parameter is used to search for associations by vendor name. This parameter expects a string with the wildcard % for partial matching.",
            "schema": {
              "type": "string"
            },
            "example": "%Acme%"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get associations that were last updated after the unix timestamp passed into the start parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1700000000
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get associations that were last updated before the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1800000000
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what relationID you want to start receiving results at. This will return results with a relationID greater than the value of cursor.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time. Supports up to 1000 results.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "This parameter is used to order results. Accepted values: relationID, -relationID, createdAt, -createdAt, updatedAt, -updatedAt, partName, -partName, vendorName, -vendorName. Prefix with - for descending order.",
            "schema": {
              "type": "string"
            },
            "example": "relationID"
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "Get Part Vendor Associations",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "relationID": {
                        "type": "integer"
                      },
                      "partID": {
                        "type": "integer"
                      },
                      "vendorID": {
                        "type": "integer"
                      },
                      "vendorPartNumber": {
                        "type": "string"
                      },
                      "partPrice": {
                        "type": "number"
                      },
                      "createdAt": {
                        "type": "integer"
                      },
                      "updatedAt": {
                        "type": "integer"
                      },
                      "partName": {
                        "type": "string"
                      },
                      "number": {
                        "type": "string"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "vendorName": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "relationID": 1,
                    "partID": 158,
                    "vendorID": 12,
                    "vendorPartNumber": "ABC-001",
                    "partPrice": 9.99,
                    "createdAt": 1700000000,
                    "updatedAt": 1700100000,
                    "partName": "Air Filter",
                    "number": "25x25x1",
                    "locationID": 163,
                    "vendorName": "Acme Supply Co."
                  },
                  {
                    "relationID": 2,
                    "partID": 159,
                    "vendorID": 34,
                    "vendorPartNumber": "",
                    "partPrice": 0,
                    "createdAt": 1700050000,
                    "updatedAt": 1700050000,
                    "partName": "Oil Filter",
                    "number": "OF-500",
                    "locationID": 163,
                    "vendorName": "Parts Depot"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Vendor Associations"
        ],
        "description": "Returns a paginated list of vendor-part associations for the customer.\n\n**Note:** this endpoint supports both cursor-based and page-based pagination. Please refer to the [**Pagination**](#pagination) section for more information.\n\nReturn data description\n\nProperty: relationID, Description: The unique ID of this vendor-part association.\nProperty: partID, Description: The ID of the associated part.\nProperty: vendorID, Description: The ID of the associated vendor.\nProperty: vendorPartNumber, Description: The vendor's part number for this part, if provided.\nProperty: partPrice, Description: The vendor's price for this part, if provided.\nProperty: createdAt, Description: Unix timestamp of when this association was created.\nProperty: updatedAt, Description: Unix timestamp of when this association was last updated.\nProperty: partName, Description: The name of the associated part.\nProperty: number, Description: The part's internal part number.\nProperty: locationID, Description: The ID of the location this part belongs to.\nProperty: vendorName, Description: The name of the associated vendor."
      },
      "post": {
        "operationId": "postPartsVendorsAssociations",
        "summary": "Create Part Vendor Association",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "partID",
                  "vendorID"
                ],
                "properties": {
                  "partID": {
                    "type": "integer",
                    "description": "The ID of the part to associate."
                  },
                  "vendorID": {
                    "type": "integer",
                    "description": "The ID of the vendor to associate."
                  }
                }
              },
              "example": {
                "partID": 158,
                "vendorID": 12
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/parts/vendors/associations?parts=158&vendors=12"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "relationID": {
                      "type": "integer"
                    },
                    "partID": {
                      "type": "integer"
                    },
                    "vendorID": {
                      "type": "integer"
                    },
                    "associationType": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "relationID": 45,
                  "partID": 158,
                  "vendorID": 12,
                  "associationType": "manual"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Vendor Associations"
        ],
        "description": "Creates a new manual vendor-part association. The part and vendor must both exist and the vendor must be accessible at the part's location.\n\nReturns `201 Created` with the new association details. Returns `409 Conflict` if the association already exists."
      }
    },
    "/v2/parts/vendors/associations/{relationID}": {
      "delete": {
        "operationId": "deletePartsVendorsAssociationsByRelationID",
        "summary": "Delete Part Vendor Association",
        "responses": {
          "204": {
            "description": "Delete Part Vendor Association"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/AssociationNotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Vendor Associations"
        ],
        "description": "Deletes a vendor-part association by its `relationID`. Only manually created associations (associationType: `manual`) can be deleted through this endpoint.\n\nReturns `204 No Content` on success. Returns `404 Not Found` if the association does not exist or does not belong to your account."
      },
      "parameters": [
        {
          "name": "relationID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/v2/parts": {
      "get": {
        "operationId": "getParts",
        "summary": "Parts",
        "parameters": [
          {
            "name": "parts",
            "in": "query",
            "description": "This parameter is used to only get specific Parts. This parameter accepts a comma delimited list of part IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2"
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get Parts at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 73
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific parts. This parameter expects a string either a full name of a part or a partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%blade%"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Parts that were last edited after the unix timestamp passed into the start parameter. For example, all Parts that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1564895015
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Parts that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1564895015
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what partID you want to start receiving results at. e.g. passing 137 here will only get you parts with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "numbers",
            "in": "query",
            "description": "This parameter is used to only get parts with part numbers that match the list provided. This parameter accepts a comma delimited list of Part Numbers.",
            "schema": {
              "type": "string"
            },
            "example": "25x25x1 - Vendor b - location 2"
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information. ",
            "schema": {
              "type": "integer"
            },
            "example": 2
          }
        ],
        "responses": {
          "200": {
            "description": "Parts",
            "headers": {
              "Last-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/parts/?locations=163&name=%Filter%&start=1564895015&end=1636670380&cursor=0&limit=100&numbers=25x25x1%20-%20Vendor%20b%20-%20location%202&page=1"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Part"
                  }
                },
                "example": [
                  {
                    "partID": 159,
                    "number": "25x25x1 - Vendor b - location 2",
                    "name": "Filter",
                    "generalStock": -14,
                    "unitCode": "each",
                    "generalPrice": 5.99,
                    "category": "Air Filters",
                    "categoryID": 7,
                    "locationID": 163,
                    "location": "Bin 002",
                    "minQtyStatus": 1,
                    "minQtyThreshold": 10,
                    "maxQtyThreshold": -1,
                    "staleThreshold": -1,
                    "staleStatus": 0,
                    "lastEdited": 1636670374,
                    "userID": 0,
                    "teamID": 436,
                    "stockOnHand": -11,
                    "pos": [
                      {
                        "quantity": 2,
                        "quantityUsed": 2,
                        "price": 5.99,
                        "poItemID": 8
                      },
                      {
                        "quantity": 8,
                        "quantityUsed": 5,
                        "price": 5.99,
                        "poItemID": 11
                      }
                    ],
                    "image": []
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts"
        ],
        "description": "This request returns a list of Parts with top level information such as name, last edited, etc.\n\n**Note:** this endpoint supports pagination. Please refer to the [Pagination](#pagination) section for more information.\n\nReturn data description\n\nnumber | The Part's Number. e.g. 25x25x1\nname | The Part's Name. e.g. Filter\ngeneralStock | How many of this Part you have in stock. Not including purchase orders.\nunitCode | The unit code displayed for the part. This represents the unit of measure assigned to the part (e.g., \"kg\", \"lb\", \"each\", etc.). If no unit is assigned, this field will be null.\ngeneralPrice | The default price of this part. Not considering purchase oder prices.\ncategory | The category this Part belongs to\nlocation | The Location of this Part. e.g. Shelf A\nminQtyStatus | Is the Part currently under the min quantity threshold. 0 = false, 1 = true.\nminQtyThreshold | The number at which reordering of this part is triggered. -1 means this feature is turned off.\nmaxQtyThreshold | The number to bring the parts quantity back to. For example, if my inventory is at 4 and my maxQtyThreshold is 20 I will be reordering 16 parts to bring my inventory back up to the max quantity.\nstaleThreshold | This value is how many days will need to go without a User using this Part by before this Part is considering stale.\nstaleStatus | Is the Part stale or not. 0 = false, 1 = true.\nuserID | The user that will receive threshold notifications and Tasks if thresholds are hit.\nteam | The team that will receive threshold notifications and Tasks if thresholds are hit.\nstockOnHand | General Stock plus any unused, received PO Quantities for this part. This matches the 'Qty' value seen in the CMMS Part Management page.\npos | Array of purchase order objects. price and quantity do not effect generalStock and generalPrice listed above.\nimage | Array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link."
      },
      "post": {
        "operationId": "postParts",
        "summary": "Create Part",
        "responses": {
          "201": {
            "description": "Create Part",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/parts/?parts=2941"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "partID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "partID": 2941
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts"
        ],
        "description": "This request adds new Parts to inventory list.\n\n| Parameter | Type | Required? | Description |\n|-----------|------|-----------|-------------|\n| locationID | Int | Required | The location of the Part to be updated. Must be the Location's unique ID number. |\n| name | String | Required | The new name of the Part. |\n| number | String | Optional | The new number of the Part. |\n| generalStock | number | Optional | How many of this Part are now in stock. Not including purchase orders. |\n| generalPrice | number | Optional | The new price of the Part. Not considering purchase order prices. |\n| unitCode | String | Optional | The unit code to assign to the part. If the unit code is not found, the request will return a 404 error. |\n| supplier | String | Optional | The new supplier of the Part. |\n| location | String | Optional | The new location of the Part (i.e. bin). |\n| categoryID | int | Optional | The category this part is in. (i.e. Electronics). |\n| staleThreshold | Int | Optional | The Stale Threshold setting allows you to set how many days need to go by without a Work Order or Task using this Part. For example, if the Stale Threshold is set at 30 and a Part does not get used by a Work Order or Task within 30 days, then the Part clock indicator will change color to red. If you wish to turn off this feature, assign a value of -1. |\n| minQtyThreshold | Int | Optional | The Minimum Part Qty Threshold setting allows you to set a limit on how low you want this Part's qty to get. For example, if a Part Qty is lower than the Part Qty Threshold, a Task will be assigned to the Manager of the location to order new Parts. If you wish to turn off this feature, assign a value of -1. |\n| maxQtyThreshold | Int | Optional | The Max Part Quantity Threshold number is used to determine what level you would like to bring your stock back to when you need to reorder a part. For example if I have 4 parts and my Maximum Part Qty Threshold is set to 20, I will have a task letting me know to order 16 more parts. If you wish to disable this feature please have a value of -1 entered. |\n| minQtyStatus | Boolean | Optional | This indicates if you are understocked or not. |\n| staleStatus | Boolean | Optional | This indicates if the part has gone stale or not. This value cannot be changed by regular user interaction it is changed automatically by Limble. |\n| assignment | Int | Optional. Required if 'assignmentType' is used. | The user or team to which the task will be assigned. Must be a user or team that exists at the specified location. Must be the unique ID number of the user or team. If this parameter is set, the assignmentType parameter must also be set. |\n| assignmentType | Enum | Optional. Required if 'assignment' is used. | Specifies whether this task will be assigned to a 'user' or a 'team'. Those two strings are the only accepted input. If this parameter is set, the assignment parameter must also be set. |\n\nA 409 is returned when the location requires unique part names or part numbers and the supplied name or number already exists at that location."
      }
    },
    "/v2/parts/fields/{fieldID}/options": {
      "get": {
        "operationId": "getPartsFieldOptions",
        "summary": "Get Part Dropdown Field Options",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "responses": {
          "200": {
            "description": "List of options for the dropdown field.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                },
                "example": {
                  "options": [
                    {
                      "name": "New"
                    },
                    {
                      "name": "Used"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "Returns the list of available options for a Dropdown custom field on parts."
      },
      "post": {
        "operationId": "postPartsFieldOptions",
        "summary": "Append Part Dropdown Field Option(s)",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "title": "Single option",
                    "type": "object",
                    "required": [
                      "name"
                    ],
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "The name of the option to append."
                      }
                    }
                  },
                  {
                    "title": "Multiple options",
                    "type": "object",
                    "required": [
                      "options"
                    ],
                    "properties": {
                      "options": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "$ref": "#/components/schemas/DropdownOption"
                        },
                        "description": "List of options to append."
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Option(s) appended successfully. Returns the full updated options list. Existing options are preserved; only the new names are added.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "Appends one or more options to a Dropdown custom field on parts. Existing options are preserved. Returns 409 if any incoming name duplicates an existing option or another name in the same request (comparison is case-insensitive and trimmed). To replace the entire list, use PUT instead.\n"
      },
      "put": {
        "operationId": "putPartsFieldOptions",
        "summary": "Replace Part Dropdown Field Options",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "options"
                ],
                "properties": {
                  "options": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/DropdownOption"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Options replaced successfully. The full new options list is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "Replaces the entire list of options for a Dropdown custom field on parts. All existing options are discarded and replaced with the provided list. Returns 409 if the provided list contains duplicate names (case-insensitive). To append without replacing, use POST instead.\n"
      }
    },
    "/v2/parts/fields/{fieldID}/options/{optionName}": {
      "delete": {
        "operationId": "deletePartsFieldOption",
        "summary": "Delete Part Dropdown Field Option",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          },
          {
            "name": "optionName",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The URL-encoded name of the option to delete."
          }
        ],
        "responses": {
          "204": {
            "description": "Option deleted successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts",
          "Fields"
        ],
        "description": "Removes a single option from a Dropdown custom field on parts by name (URL-encoded). Returns 404 if the option does not exist."
      }
    },
    "/v2/parts/{partID}": {
      "patch": {
        "operationId": "patchPartsByPartID",
        "summary": "Update Part",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts"
        ],
        "description": "This request updates an Part's information such as a Part's quantity.\n\nlocationID | Int | Required | The location of the Part to be updated. Must be the Location's unique ID number.\nname | String | Optional | The new name of the Part.\nnumber | String | Optional | The new number of the Part.\ngeneralStock | number | Optional | How many of this Part are now in stock. Not including purchase orders.\ngeneralPrice | number | Optional | The new price of the Part. Not considering purchase order prices.\nunitCode | String | Optional | Update the part's unit by providing a unit code. If the unit code is not found, the request will return a 404 error. The unit of measure cannot be changed if the part has purchasables associated with it or is referenced in open purchase orders - in these cases, the request will return a 400 error.\nsupplier | String | Optional | The new supplier of the Part.\nlocation | String | Optional | The new location of the Part (i.e. bin).\ncategoryID | int | Optional | The category this part is in. (i.e. Electronics).\nstaleThreshold | Int | Optional | The Stale Threshold setting allows you to set how many days need to go by without a Work Order or Task using this Part. For example, if the Stale Threshold is set at 30 and a Part does not get used by a Work Order or Task within 30 days, then the Part clock indicator will change color to red. If you wish to turn off this feature, assign a value of -1.\nminQtyThreshold | Int | Optional | The Minimum Part Qty Threshold setting allows you to set a limit on how low you want this Part's qty to get. For example, if a Part Qty is lower than the Part Qty Threshold, a Task will be assigned to the Manager of the location to order new Parts. If you wish to turn off this feature, assign a value of -1.\nmaxQtyThreshold | Int | Optional | The Max Part Quantity Threshold number is used to determine what level you would like to bring your stock back to when you need to reorder a part. For example if I have 4 parts and my Maximum Part Qty Threshold is set to 20, I will have a task letting me know to order 16 more parts. If you wish to disable this feature please have a value of -1 entered.\nminQtyStatus | Boolean | Optional | This indicates if you are understocked or not.\nstaleStatus | Boolean | Optional | This indicates if the part has gone stale or not. This value cannot be changed by regular user interaction it is change automatically by limble.\nassignment | Int | Optional. Required if 'assignmentType' is used. | The user or team to which the task will be assigned., Must be a user or team that exists at the specified location. Must be the unique ID number of the user or team. If this parameter is set, the assignmentType parameter must also be set.,\nassignmentType | Enum | Optional. Required if 'assignment' is used. | Specifies wether this task will be assigned to a 'user' or a 'team'. Those two strings are the only accepted input. If this parameter is set, the assignment parameter must also be set.,"
      },
      "parameters": [
        {
          "name": "partID",
          "in": "path",
          "required": true,
          "description": "partID of the part you are removing.",
          "schema": {
            "type": "string"
          },
          "example": "{{partID}}"
        }
      ],
      "delete": {
        "operationId": "deletePartsByPartID",
        "summary": "Delete Part",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts"
        ],
        "description": "This request removes a Part from your inventory list."
      }
    },
    "/v2/parts/usage": {
      "get": {
        "operationId": "getPartsUsage",
        "summary": "Parts Usage",
        "parameters": [
          {
            "name": "parts",
            "in": "query",
            "description": "This parameter is used to only get specific Parts. This parameter accepts a comma delimited list of part IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "tasks",
            "in": "query",
            "description": "This parameter is used to only get Parts at a specific group of Tasks. This parameter accepts a comma delimited list of Task IDs.",
            "schema": {
              "type": "string"
            },
            "example": "8,10"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Parts that were last edited after the unix timestamp passed into the start parameter. For example, all Assets that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1457663400
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Parts that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1457663400
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to string search part names either partial or full name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%Pro%"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what partID you want to start receiving results at. e.g. passing 137 here will only get you part usage records with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Parts Usage",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "meta": {
                        "type": "object",
                        "properties": {
                          "task": {
                            "type": "string"
                          },
                          "part": {
                            "type": "string"
                          }
                        }
                      },
                      "partID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      },
                      "taskID": {
                        "type": "integer"
                      },
                      "usedCount": {
                        "type": "integer"
                      },
                      "usedPrice": {
                        "type": "integer"
                      },
                      "usedOn": {
                        "type": "integer"
                      },
                      "poItemID": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "meta": {
                      "task": "/v2/tasks/?tasks=2",
                      "part": "/v2/parts/?parts=4"
                    },
                    "partID": 2,
                    "name": "X1161P Projector Lamp",
                    "taskID": 8,
                    "usedCount": 0,
                    "usedPrice": 0,
                    "usedOn": 0,
                    "poItemID": 0
                  },
                  {
                    "meta": {
                      "task": "/v2/tasks/?tasks=3",
                      "part": "/v2/parts/?parts=5"
                    },
                    "partID": 3,
                    "name": "Stain Cleaner",
                    "taskID": 10,
                    "usedCount": 0,
                    "usedPrice": 0,
                    "usedOn": 0,
                    "poItemID": 0
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Parts"
        ],
        "description": "This request gets your Parts usage log.\n\nReturn data description\n\nProperty: meta, Description: A call which can be used to quickly look up the Task that this part's usage was recorded on.\nProperty: name, Description: The name of the part used.\nProperty: taskID, Description: The associated Task where this part was used.\nProperty: usedCount, Description: The number of parts that were used.\nProperty: usedPrice, Description: The price per 1 part.\nProperty: usedOn, Description: The date when the part was used. This is a unix timestamp.\nProperty: poItemID, Description: The unique ID of the PO item associated with this usage record."
      }
    },
    "/v2/tasks/{taskID}/invoices/{invoiceID}/file": {
      "put": {
        "operationId": "putTasksByTaskIDInvoicesByInvoiceIDFile",
        "summary": "Attach a file to an invoice",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Invoices",
          "Files"
        ],
        "description": "This request will attach a text or image file to an invoice on an **open** Task (i.e. task status=0)."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "description": "The taskID of the invoice you want remove the file from.",
          "schema": {
            "type": "integer"
          },
          "example": 15188
        },
        {
          "name": "invoiceID",
          "in": "path",
          "required": true,
          "description": "The invoiceID of the invoice you want to remove the file from.",
          "schema": {
            "type": "integer"
          },
          "example": 311
        }
      ],
      "delete": {
        "operationId": "deleteTasksByTaskIDInvoicesByInvoiceIDFile",
        "summary": "Delete file from Invoice",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Invoices",
          "Files"
        ],
        "description": "This request removes a file attached to an invoice on an open Task (i.e. task status = 0)."
      }
    },
    "/v2/tasks/invoices": {
      "get": {
        "operationId": "getTasksInvoices",
        "summary": "Invoices",
        "parameters": [
          {
            "name": "invoices",
            "in": "query",
            "description": "This parameter is used to only get specific invoices or invoices. This parameter accepts a comma delimited list of invoice IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "tasks",
            "in": "query",
            "description": "This parameter is used to only get invoices on a task or tasks. This parameter accepts a comma delimited list of task IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 8250
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get invoices that were logged after the unix timestamp passed into the start parameter. For example, all Invoices that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1459391400
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get invoices that were logged *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1518826313
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what invoiceID you want to start receiving results at. e.g. passing 137 here will only get you tasks with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Invoices",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "meta": {
                        "type": "object",
                        "properties": {
                          "task": {
                            "type": "string"
                          }
                        }
                      },
                      "invoiceID": {
                        "type": "integer"
                      },
                      "file": {
                        "type": "string"
                      },
                      "cost": {
                        "type": "number"
                      },
                      "taskID": {
                        "type": "integer"
                      },
                      "lastEdited": {
                        "type": "integer"
                      },
                      "description": {
                        "type": "null"
                      },
                      "completedDate": {
                        "type": "integer"
                      },
                      "poItemID": {
                        "type": "integer"
                      },
                      "invoiceFiles": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "fileName": {
                              "type": "string"
                            },
                            "link": {
                              "type": "string",
                              "format": "uri"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "meta": {
                      "task": "/v2/tasks/?tasks=40"
                    },
                    "invoiceID": 2,
                    "file": "home-depot-receipt.pdf",
                    "cost": 261.78,
                    "taskID": 40,
                    "lastEdited": 1522339851,
                    "description": null,
                    "completedDate": 1459391400,
                    "poItemID": 0,
                    "invoiceFiles": [
                      {
                        "fileName": "home-depot-receipt.pdf",
                        "link": "https://content.limblecmms.com/upload-36/invoices/40/home-depot-receipt.pdf?Expires=1756912910&Key-Pair-Id=APKAIH5A42E3EPKJRHFQ&Signature=MeBymiHtMiuORuBqmQApfPXVgvTjQIl-zpRR6fhIjsrDItx~JGtUQkDW29dEDbzFqXsckIs~EIsd6ORuR8gxWcXXJopX3ZD4WjWjZKjSdz2LluwJRTp4odlTiEE2kZUoheEeIMbHJrRNQoQRPpNhJIXGZp5j5e9pqCR1R1~W3ykq-xRFmkGT7nOE0z-2ilHa9qjrgErSmrxjCRxPt0CFsYdzSySBuz4Fz2mXIDQiwO1cw7SEbnqBbqKEjogjMydy7vdtUC3upG7MF2BT-bOovihxeDksLEKZdmjAwaU-nhiJ4IWW1WGZ05wlHQG~xkYqDVW1R~A20qFA3-Cya0MmgQ__"
                      }
                    ]
                  },
                  {
                    "meta": {
                      "task": "/v2/tasks/?tasks=63"
                    },
                    "invoiceID": 3,
                    "file": "",
                    "cost": 50,
                    "taskID": 63,
                    "lastEdited": 1518826313,
                    "description": null,
                    "completedDate": 1475597795,
                    "poItemID": 0,
                    "invoiceFiles": []
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Invoices"
        ],
        "description": "This request gets all Invoices associated with Tasks."
      }
    },
    "/v2/tasks/{taskID}/invoices": {
      "put": {
        "operationId": "putTasksByTaskIDInvoices",
        "summary": "Attach an Invoice to task",
        "responses": {
          "200": {
            "description": "Attach an Invoice to task",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "invoiceID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "invoiceID": 312
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Invoices"
        ],
        "description": "StartFragment\n\n.expect('Content-Type', /json/);\n\nEndFragment",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cost": {
                    "type": "number"
                  },
                  "description": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "cost": 10.1,
                "description": "testing"
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "description": "The taskID of the task you're attaching an invoice to.",
          "schema": {
            "type": "integer"
          },
          "example": 15188
        }
      ]
    },
    "/v2/tasks/{taskID}/invoices/{invoiceID}": {
      "delete": {
        "operationId": "deleteTasksByTaskIDInvoicesByInvoiceID",
        "summary": "Delete invoice from task",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Invoices"
        ],
        "description": "This request will remove an invoice from an **open** Task (i.e. task status=0)."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "description": "The taskID of the task the invoice is attached to",
          "schema": {
            "type": "integer"
          },
          "example": 15188
        },
        {
          "name": "invoiceID",
          "in": "path",
          "required": true,
          "description": "The invoiceID that needs to be updated",
          "schema": {
            "type": "integer"
          },
          "example": 290
        }
      ],
      "patch": {
        "operationId": "patchTasksByTaskIDInvoicesByInvoiceID",
        "summary": "Update an Invoice",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Invoices"
        ],
        "description": "This request will update an invoice attached to an **open** Task (i.e. task status=0).\n\ncost | Float | Required | The cost on the invoice.\ndescription | String | Required | Brief description for the invoice.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cost": {
                    "type": "integer"
                  },
                  "description": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "cost": 10000,
                "description": "new inovoice"
              }
            }
          }
        }
      }
    },
    "/v2/tasks/{taskID}/instructions/{instructionID}/options": {
      "get": {
        "operationId": "getTasksByTaskIDInstructionsByInstructionIDOptions",
        "summary": "Instruction Options",
        "responses": {
          "200": {
            "description": "Instruction Options",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "instructionOptionID": {
                        "type": "integer"
                      },
                      "instructionOptionOrder": {
                        "type": "integer"
                      },
                      "instruction": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "instructionOptionID": 7096,
                    "instructionOptionOrder": 1,
                    "instruction": "Yes"
                  },
                  {
                    "instructionOptionID": 7097,
                    "instructionOptionOrder": 2,
                    "instruction": "No"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions",
          "Options"
        ],
        "description": "This request gets all the Options for an Instruction Option or Dropdown list associated with a Task."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "description": "taskID of the task you are getting the option/dropdown list.",
          "schema": {
            "type": "integer"
          },
          "example": 11429
        },
        {
          "name": "instructionID",
          "in": "path",
          "required": true,
          "description": "instructionID of the option/dropdown list you are getting the options for.",
          "schema": {
            "type": "integer"
          },
          "example": 49343
        }
      ],
      "post": {
        "operationId": "postTasksByTaskIDInstructionsByInstructionIDOptions",
        "summary": "New Instruction Option",
        "responses": {
          "201": {
            "description": "New Instruction Option",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "instructionOptionID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "instructionOptionID": 7097
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions",
          "Options"
        ],
        "description": "This request will create a new Option for a Dropdown or Option instruction of a task.\n\nParameter: instruction, Type: string, Required?: Required, Description: The text that guides the User for selecting the option.\nParameter: instructionOptionOrder, Type: Int, Required?: Optional, Description: If this is set the option is created at that position of the list. This value cannot be greater than the total number of option present in the list. If not set the option is added to the end of the list.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "instruction": {
                    "type": "string"
                  },
                  "instructionOptionOrder": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "instruction": "Yes",
                "instructionOptionOrder": 1
              }
            }
          }
        }
      }
    },
    "/v2/tasks/instructions/{instructionID}/options/{instructionOptionID}": {
      "delete": {
        "operationId": "deleteTasksInstructionsByInstructionIDOptionsByInstructionOptionID",
        "summary": "Delete Instruction Option",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions",
          "Options"
        ],
        "description": "This request will delete an option from a Dropdown or Option instruction."
      },
      "parameters": [
        {
          "name": "instructionID",
          "in": "path",
          "required": true,
          "description": "instructionID of the instruction whose option you are editing.",
          "schema": {
            "type": "integer"
          },
          "example": 49343
        },
        {
          "name": "instructionOptionID",
          "in": "path",
          "required": true,
          "description": "instructionOptionID of the option you are editing.",
          "schema": {
            "type": "integer"
          },
          "example": 7097
        }
      ],
      "patch": {
        "operationId": "patchTasksInstructionsByInstructionIDOptionsByInstructionOptionID",
        "summary": "Update Instruction Option",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions",
          "Options"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "instruction": {
                    "type": "string"
                  },
                  "instructionOptionOrder": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "instruction": "Not Allowed",
                "instructionOptionOrder": 1
              }
            }
          }
        }
      }
    },
    "/v2/tasks/{taskID}/instructions": {
      "get": {
        "operationId": "getTasksByTaskIDInstructions",
        "summary": "Task Instructions",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what partID you want to start receiving results at. e.g. passing 137 here will only get you parts with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          }
        ],
        "responses": {
          "200": {
            "description": "Pagination using Page & Limit",
            "headers": {
              "Last-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/tasks/103/instructions?limit=2&page=4"
              },
              "Next-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/tasks/103/instructions?limit=2&page=2"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "instructionID": {
                        "type": "integer"
                      },
                      "taskID": {
                        "type": "integer"
                      },
                      "parentInstructionID": {
                        "type": "integer"
                      },
                      "instruction": {
                        "type": "string"
                      },
                      "type": {
                        "type": "integer"
                      },
                      "options": {
                        "type": "array"
                      },
                      "response": {
                        "type": "boolean"
                      },
                      "instructionFiles": {
                        "type": "array"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "instructionID": 767,
                    "taskID": 103,
                    "parentInstructionID": 0,
                    "instruction": "Check Air Oil",
                    "type": 1,
                    "options": [],
                    "response": false,
                    "instructionFiles": []
                  },
                  {
                    "instructionID": 768,
                    "taskID": 103,
                    "parentInstructionID": 0,
                    "instruction": "&lt;b&gt;Check Fly wheel belts&lt;/b&gt;",
                    "type": 1,
                    "options": [],
                    "response": false,
                    "instructionFiles": []
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions"
        ],
        "description": "This request gets all Task Instructions associated with a Task.\n\n**Note:** this endpoint supports pagination. Please refer to the [Pagination](#pagination) section for more information.\n\nReturn data description\n\nparentInstructionID | This is the instructionID of the Instruction's parent. If this value is 0 then this Instruction does not have a parent.\ninstruction | The text that guides a User on what to do on this Instruction.\ntype | The type of the Instruction. See the request Post New Task Instruction to see a list of possible types and their meaning.\ninstructionFiles | Array of objects that have a file name and a link you can use to download that file. All links are only valid for 15 minutes, a new call will generate a new link.\noptions | Array of objects that have an itemOptionID, itemOptionOrder, and itemOptionText.\nresponse | This field is the \"response\" of an instruction i.e. what a user filled out when doing this instruction. The return value changes based on the instruction type:, 1 Check Box - true/false, 2 Radio List - if no option is selected, this will be 0. If an option is selected, this will be a number that maps to the itemOptionID of one of the members of the options array., 3 Text Box - string, 4 Dropdown Box - if no option is selected, this will be 0. If an option is selected, this will be a number that maps to the itemOptionID of one of the members of the options array., 5 Date Picker - unix time stamp, 7 Label - labels will never have a user response, 9 File or Picture Attachment - Array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link., 10 Assign PM - not supported yet., 13 Number - integer, 14 Start WO - not supported yet., 15 Capture Signature - Array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link., 16 Request Approval - Array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link.,\nmeta | This property is useful to get more information related to the Task Instructions. Different instruction types may have different properties in the meta section., Instruction Type:, 14 Start WO - If this instruction is completed on the task, the meta property would have an \"associatedTask\" property on it. The associatedTask gives the route for the task created by this instruction. For example, if task 2 was created by a \"Start WO\" instruction on task 1. In GET Task Instruction for task 1, this instruction would have a meta associatedTask property pointing to task 2."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 80
        }
      ],
      "post": {
        "operationId": "postTasksByTaskIDInstructions",
        "summary": "New Task Instruction",
        "responses": {
          "201": {
            "description": "New Task Instruction",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/tasks/8250/instructions"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "instructionID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "instructionID": 34068
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions"
        ],
        "description": "This request will create a new Instruction for a Task.\n\nParameter: type, Type: Int, Required?: Required, Description: The type of each checklist item., 1 = Check Box; 2 = Option List; 3 = Text Box; 4 = Dropdown List; 5 = Date Picker; 7 = Label; 9 = File or Picture Attachment; 11 = Deadline Date Picker; 13 = Number; 14 = Start WO; 15 = Capture Signature., Item types not listed here are not currently supported. If you would like another item type to be supported, please contact us at product@limblecmms.com.\nParameter: instruction, Type: string, Required?: Required, Description: The text that guides a User on what to do on this Instruction.\nParameter: parentInstructionID, Type: Int, Required?: Required, Description: If this is set this Instruction is a 'child' or sub-instruction. This value is the id of the Instruction's parent. A value of 0 means it does not have a parent.\nParameter: parentInstructionOptionID, Type: Int, Required?: Optional, Description: If type is set to 2,4 and a parentInstructionID of an existing option/dropdown list is set then the parentInstructionOptionID needs to be set as the ID of the option for which a child option/dropdown list needs to be added."
      }
    },
    "/v2/tasks/instructions/{instructionID}": {
      "patch": {
        "operationId": "patchTasksInstructionsByInstructionID",
        "summary": "Update Task Instruction",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "instruction": {
                    "type": "string",
                    "description": "The text that guides a user on what to do on this instruction."
                  },
                  "parentInstructionID": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "The instructionID of this instruction's parent. A value of 0 or null removes the parent (makes this a top-level instruction)."
                  },
                  "response": {
                    "description": "The response value for the instruction. The accepted value depends on the instruction type:\n\n| Type | Accepted value |\n|------|----------------|\n| 1 Checkbox | `true` or `false` |\n| 2 Radio List | `itemOptionID` of the selected option, or `0` to clear |\n| 3 Text Box | string |\n| 4 Dropdown | `itemOptionID` of the selected option, or `0` to clear |\n| 5 Date Picker | Unix timestamp (integer) |\n| 13 Number | number |\n\nSending `response` for any other instruction type returns a 400."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions"
        ],
        "description": "This request updates a Task Instruction.\n\nAll request body properties are optional. Include only the fields you want to update.\n\nThe `response` field is type-dependent — see the request body schema for accepted values per instruction type."
      },
      "parameters": [
        {
          "name": "instructionID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "delete": {
        "operationId": "deleteTasksInstructionsByInstructionID",
        "summary": "Delete Task Instruction",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions"
        ],
        "description": "This request removes a Task Instruction from a Task."
      },
      "get": {
        "operationId": "getTasksInstructionsByInstructionID",
        "summary": "Get Task Instruction by ID",
        "responses": {
          "200": {
            "description": "Success Response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "instructionID": {
                      "type": "integer"
                    },
                    "taskID": {
                      "type": "integer"
                    },
                    "parentInstructionID": {
                      "type": "integer"
                    },
                    "instruction": {
                      "type": "string"
                    },
                    "type": {
                      "type": "integer"
                    },
                    "instructionFiles": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "fileName": {
                            "type": "string"
                          },
                          "downloadLink": {
                            "type": "string",
                            "format": "uri"
                          }
                        }
                      }
                    },
                    "response": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "instructionID": 12345,
                  "taskID": 67890,
                  "parentInstructionID": 0,
                  "instruction": "Check oil levels and record reading",
                  "type": 3,
                  "instructionFiles": [
                    {
                      "fileName": "oil_check_guide.pdf",
                      "downloadLink": "https://example.com/files/oil_check_guide.pdf?expires=1234567890"
                    }
                  ],
                  "response": "Oil level at 75%"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions"
        ],
        "description": "This request retrieves a single Task Instruction by its instructionID.\n\n**Path Parameters:**\n- `instructionID` (required): The ID of the instruction to retrieve\n\n**Return data description:**\n\nReturns a single instruction object with the following properties:\n\n| Property | Description |\n|----------|-------------|\n| instructionID | The unique identifier for this instruction |\n| taskID | The ID of the task this instruction belongs to |\n| parentInstructionID | This is the instructionID of the Instruction's parent. If this value is 0 then this Instruction does not have a parent. |\n| instruction | The text that guides a User on what to do on this Instruction. |\n| type | The type of the Instruction. See the request Post New Task Instruction to see a list of possible types and their meaning. |\n| instructionFiles | Array of objects that have a file name and a link you can use to download that file. All links are only valid for 15 minutes, a new call will generate a new link. |\n| response | This field is the 'response' of an instruction i.e. what a user filled out when completing this instruction. |\n\n**Error Responses:**\n- 404: Instruction not found"
      }
    },
    "/v2/tasks/instructions": {
      "get": {
        "operationId": "getTasksInstructions",
        "summary": "Batch Task Instructions",
        "parameters": [
          {
            "name": "tasks",
            "in": "query",
            "description": "CSV of task IDs ",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3,4,5,6,7"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Page size (1..1000)",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page-based pagination (mutually exclusive with cursor)",
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "Batch Task Instructions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TaskInstruction"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Instructions"
        ],
        "description": "Retrieves instructions across multiple tasks, by taskID.\n\nReturn data description\n\nparentInstructionID | This is the instructionID of the Instruction's parent. If this value is 0 then this Instruction does not have a parent.\ninstruction | The text that guides a User on what to do on this Instruction.\ntype | The type of the Instruction. See the request Post New Task Instruction to see a list of possible types and their meaning.\ninstructionFiles | Array of objects that have a file name and a link you can use to download that file. All links are only valid for 15 minutes, a new call will generate a new link.\noptions | Array of objects that have an itemOptionID, itemOptionOrder, and itemOptionText.\nresponse | This field is the \"response\" of an instruction i.e. what a user filled out when doing this instruction. The return value changes based on the instruction type:, 1 Check Box - true/false, 2 Radio List - if no option is selected, this will be 0. If an option is selected, this will be a number that maps to the itemOptionID of one of the members of the options array., 3 Text Box - string, 4 Dropdown Box - if no option is selected, this will be 0. If an option is selected, this will be a number that maps to the itemOptionID of one of the members of the options array., 5 Date Picker - unix time stamp, 7 Label - labels will never have a user response, 9 File or Picture Attachment - Array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link., 10 Assign PM - not supported yet., 13 Number - integer, 14 Start WO - not supported yet., 15 Capture Signature - Array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link., 16 Request Approval - Array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link.,\nmeta | This property is useful to get more information related to the Task Instructions. Different instruction types may have different properties in the meta section., Instruction Type:, 14 Start WO - If this instruction is completed on the task, the meta property would have an \"associatedTask\" property on it. The associatedTask gives the route for the task created by this instruction. For example, if task 2 was created by a \"Start WO\" instruction on task 1. In GET Task Instruction for task 1, this instruction would have a meta associatedTask property pointing to task 2."
      }
    },
    "/v2/tasks/instructions/{instructionID}/image": {
      "put": {
        "operationId": "putTasksInstructionsByInstructionIDImage",
        "summary": "Task Instruction Image",
        "responses": {
          "200": {
            "description": "Task Instruction Image",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "filename": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "filename": "165040874634324-pic.png"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Images"
        ],
        "description": "This request adds instructional images to an Instruction.\n\nReturn data description\n\nfilename | The name of the file after being uploaded to Limble."
      },
      "parameters": [
        {
          "name": "instructionID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 59271
        }
      ],
      "delete": {
        "operationId": "deleteTasksInstructionsByInstructionIDImage",
        "summary": "Delete Task Instruction Image",
        "parameters": [
          {
            "name": "filename",
            "in": "query",
            "description": "The name of the instruction file that needs to be deleted. This is an optional parameter. If not given, **all** the files attached to an instruction will be deleted.",
            "schema": {
              "type": "string"
            },
            "example": "165040769563793-pic.png"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Images"
        ],
        "description": "This request removes an instructional image from an Instruction."
      }
    },
    "/v2/tasks/{taskID}/image": {
      "put": {
        "operationId": "putTasksByTaskIDImage",
        "summary": "Upload Task Main Image",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Images"
        ],
        "description": "Uploads a main image to a task.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| taskID | path | integer | yes |  | Task identifier |\n| image | form-data | file | yes |  | Image file (≤ 50MB). Types: JPEG, PNG, JPG, GIF |"
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 555
        }
      ],
      "delete": {
        "operationId": "deleteTasksByTaskIDImage",
        "summary": "Delete Task Main Image",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Images"
        ],
        "description": "Deletes the task's main image.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| taskID | path | integer | yes |  | Task identifier |\n\nResponses:\n- 200 OK: Image cleared.\n- 404 Not Found: No image exists for this task."
      }
    },
    "/v2/tasks/labor": {
      "get": {
        "operationId": "getTasksLabor",
        "summary": "Task Labor",
        "parameters": [
          {
            "name": "tasks",
            "in": "query",
            "description": "This parameter is used to only get specific Tasks. This parameter accepts a comma delimited list of task IDs.",
            "schema": {
              "type": "string"
            },
            "example": "6,11"
          },
          {
            "name": "users",
            "in": "query",
            "description": "This parameter is used to only get labor records for a specific user or set of users in a comma delimited list.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get labor that was logged after the unix timestamp passed into the start parameter. For example, all Assets that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1564895015
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get labor that was logged *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1564895015
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what taskID you want to start receiving results at. e.g. passing 137 here will only get you tasks with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to retrieve labor entries for particular locations. This parameter accepts a comma delimited list of location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "This parameter is used to order results by their dateLogged property instead of the default ordering. CANNOT be provided alongside the cursor parameter. to paginate in this ordering, use the start or end parameters.",
            "schema": {
              "type": "string"
            },
            "example": "-dateLogged"
          }
        ],
        "responses": {
          "200": {
            "description": "Task Labor",
            "headers": {
              "X-Has-More": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                },
                "description": "Indicates whether additional records exist beyond the current page.",
                "example": "false"
              },
              "Next-Page": {
                "schema": {
                  "type": "string"
                },
                "description": "Ready-to-use URL for the next page (only present when X-Has-More is true).",
                "example": "/v2/tasks/labor?limit=100&cursor=137"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "meta": {
                        "type": "object",
                        "properties": {
                          "task": {
                            "type": "string"
                          },
                          "user": {
                            "type": "string"
                          }
                        }
                      },
                      "userID": {
                        "type": "integer"
                      },
                      "timeSpent": {
                        "type": "integer"
                      },
                      "userWage": {
                        "type": "integer"
                      },
                      "taskID": {
                        "type": "integer"
                      },
                      "taskName": {
                        "type": "string"
                      },
                      "tashPriorityID": {
                        "type": "integer"
                      },
                      "description": {
                        "type": "null"
                      },
                      "dateLogged": {
                        "type": "integer"
                      },
                      "billableTime": {
                        "type": "null"
                      },
                      "billableRate": {
                        "type": "null"
                      },
                      "categoryID": {
                        "type": "null"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "meta": {
                      "task": "/v2/tasks/?tasks=7",
                      "user": "/v2/users/?users=341"
                    },
                    "userID": 341,
                    "timeSpent": 7200,
                    "userWage": 15,
                    "taskID": 7,
                    "taskName": "Tire Rotation",
                    "tashPriorityID": 1682,
                    "description": null,
                    "dateLogged": 1457559196,
                    "billableTime": null,
                    "billableRate": null,
                    "categoryID": null
                  },
                  {
                    "meta": {
                      "task": "/v2/tasks/?tasks=16",
                      "user": "/v2/users/?users=341"
                    },
                    "userID": 341,
                    "timeSpent": 3660,
                    "userWage": 15,
                    "taskID": 16,
                    "description": null,
                    "dateLogged": 1457569392,
                    "billableTime": null,
                    "billableRate": null,
                    "categoryID": null
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Labor"
        ],
        "description": "This request gets the labor (time spent) on a Task. A single Task can have multiple times logged onto it.\n\nReturn data description\n\nmeta | This property contains shortcuts to other requests that can be used to get more information regarding the Task the labor was logged on and the user who logged the time.\ntaskID | The Task ID associated with this labor entry.\ntimeSpent | The amount of time measure in seconds.\nuserWage | The wage per hour.\ndescription | A description of the labor entry.\ndateLogged | The date that this time was logged on the Task.\nbillableTime | The amount of time that is billable for this Task.\nbillableRate | The rate at which this labor entry is billed at.\ncategoryID | The labor category this entry is associated with.\ntaskName | The name of the task associated with this labor entry.\ntaskPriorityID | The Priority ID of the task this labor entry is associated with.\ntaskPriorityLevel | The Priority value of the task this labor entry is associated with."
      }
    },
    "/v2/tasks/labor/categories": {
      "get": {
        "operationId": "getTasksLaborCategories",
        "summary": "Get Labor Categories",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "description": "This is a parameter used to string search for a name or partial name of a category this parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%tech%"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what taskID you want to start receiving results at. e.g. passing 137 here will only get you tasks with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          }
        ],
        "responses": {
          "200": {
            "description": "Get Labor Categories",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "categoryID": {
                        "type": "integer"
                      },
                      "categoryName": {
                        "type": "string"
                      },
                      "categoryRate": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "categoryID": 1,
                    "categoryName": "Technical",
                    "categoryRate": 100
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Labor"
        ],
        "description": "This request gets the labor categories.\n\nReturn data description\n\nProperty: categoryID, Description: The unique ID for this billing category.\nProperty: categoryName, Description: The name of this billing category.\nProperty: categoryRate, Description: The rate per hour of this billing category."
      }
    },
    "/v2/tasks/{taskID}/parts": {
      "get": {
        "operationId": "getTasksByTaskIDParts",
        "summary": "Get attached parts",
        "responses": {
          "200": {
            "description": "Get attached parts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "partID": {
                        "type": "integer"
                      },
                      "quantity": {
                        "type": "integer"
                      },
                      "usedPrice": {
                        "type": "integer"
                      },
                      "partName": {
                        "type": "string"
                      },
                      "poItemID": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "partID": 2934,
                    "quantity": 1,
                    "usedPrice": 1,
                    "partName": "Lawn Mower Blade",
                    "poItemID": 0
                  },
                  {
                    "partID": 2992,
                    "quantity": 1,
                    "usedPrice": 5,
                    "partName": "Cog",
                    "poItemID": 0
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Parts"
        ],
        "description": "Gets parts attached to a task.\n\nThis request gets parts associated with a task. A single Task can have multiple parts associated with it.\n\nReturn data description\n\nProperty: partID, Description: The partID of the part associated to this task.\nProperty: quantity, Description: The quantity of this part associated to this task.\nProperty: usedPrice, Description: The price of the part at the time of use.\nProperty: partName, Description: The name of the part.\nProperty: poItemID, Description: The unique ID of the PO item associated with this record."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "example": "{{taskID}}"
        }
      ],
      "put": {
        "operationId": "putTasksByTaskIDParts",
        "summary": "Attach part to task",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Parts"
        ],
        "description": "This request associates a part to a task."
      }
    },
    "/v2/tasks/parts": {
      "get": {
        "operationId": "getTasksParts",
        "summary": "Get all attached parts",
        "parameters": [
          {
            "name": "tasks",
            "in": "query",
            "description": "This parameter is used to get parts attached to a list of tasks. This parameter accepts a comma delimited list of task IDs.",
            "schema": {
              "type": "string"
            },
            "example": "5,10,12"
          },
          {
            "name": "parts",
            "in": "query",
            "description": "This parameter is used to get only certain. This parameter accepts a comma delimited list of task IDs.",
            "schema": {
              "type": "string"
            },
            "example": "121,112,553"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what id you want to start receiving results at. e.g. passing 137 here will only get you assets with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 137
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Get all attached parts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "relationID": {
                        "type": "integer"
                      },
                      "partID": {
                        "type": "integer"
                      },
                      "taskID": {
                        "type": "integer"
                      },
                      "quantity": {
                        "type": "integer"
                      },
                      "lastEdited": {
                        "type": "integer"
                      },
                      "usedPrice": {
                        "type": "integer"
                      },
                      "partName": {
                        "type": "string"
                      },
                      "poItemID": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "relationID": 2,
                    "partID": 2,
                    "taskID": 8,
                    "quantity": 1,
                    "lastEdited": 1519084797,
                    "usedPrice": 0,
                    "partName": "X1161P Projector Lamp",
                    "poItemID": 0
                  },
                  {
                    "relationID": 3,
                    "partID": 3,
                    "taskID": 10,
                    "quantity": 5,
                    "lastEdited": 1519084797,
                    "usedPrice": 0,
                    "partName": "Stain Cleaner",
                    "poItemID": 0
                  },
                  {
                    "relationID": 8,
                    "partID": 4,
                    "taskID": 31,
                    "quantity": 1,
                    "lastEdited": 1519084797,
                    "usedPrice": 0,
                    "partName": "Spark Plugs",
                    "poItemID": 0
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Parts"
        ],
        "description": "Gets parts attached to all tasks.\n\nThis request gets parts associated with any task. A single Task can have multiple parts associated with it.\n\nReturn data description\n\nProperty: relationID, Description: The identifier that associates parts to tasks.\nProperty: partID, Description: The partID of the part associated to this task.\nProperty: taskID, Description: The taskID this part is assoicated with.\nProperty: quantity, Description: The quantity of this part associated to this task.\nProperty: lastEdited, Description: The unix timestamp date of the last time this record was edited.\nProperty: usedPrice, Description: The price of the part at the time of use.\nProperty: partName, Description: The name of the part.\nProperty: poItemID, Description: The unique ID of the PO item associated with this record."
      }
    },
    "/v2/tasks/{taskID}/{partID}": {
      "delete": {
        "operationId": "deleteTasksByTaskIDByPartID",
        "summary": "Delete part from task",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Parts"
        ],
        "description": "This request deletes a part from a task."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "example": "{{taskID}}"
        },
        {
          "name": "partID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "example": "{{partID}}"
        }
      ]
    },
    "/v2/tasks/{taskID}/comments": {
      "get": {
        "operationId": "getTasksByTaskIDComments",
        "summary": "Task Comments",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what commentID you want to start receiving results at. e.g. passing 137 here will only get you parts with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Task Comments",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "4000"
              },
              "X-RateLimit-Minute-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "360"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "3691"
              },
              "X-RateLimit-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1694457371"
              },
              "X-RateLimit-Minute-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "359"
              },
              "X-RateLimit-Minute-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1694458796"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "commentID": {
                        "type": "integer"
                      },
                      "comment": {
                        "type": "string",
                        "format": "style"
                      },
                      "commentFiles": {
                        "type": "array"
                      },
                      "timestamp": {
                        "type": "integer"
                      },
                      "userID": {
                        "type": "integer"
                      },
                      "commentEmailAddress": {
                        "type": "null"
                      },
                      "showExternalUsers": {
                        "type": "boolean"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "commentID": 18018,
                    "comment": "Triggered at: 41 Mileage | Schedule set at: Every 15 Mileage",
                    "commentFiles": [],
                    "timestamp": 1694110194,
                    "userID": 340,
                    "commentEmailAddress": null,
                    "showExternalUsers": true
                  },
                  {
                    "commentID": 18019,
                    "comment": "This Task was assigned to Unassigned",
                    "commentFiles": [],
                    "timestamp": 1694110195,
                    "userID": 340,
                    "commentEmailAddress": null,
                    "showExternalUsers": true
                  },
                  {
                    "commentID": 18031,
                    "comment": "This Task's Status was changed from name4 to name4",
                    "commentFiles": [],
                    "timestamp": 1694457643,
                    "userID": 340,
                    "commentEmailAddress": null,
                    "showExternalUsers": true
                  },
                  {
                    "commentID": 18032,
                    "comment": "This Task's Status was changed from name4 to name444",
                    "commentFiles": [],
                    "timestamp": 1694457678,
                    "userID": 340,
                    "commentEmailAddress": null,
                    "showExternalUsers": true
                  },
                  {
                    "commentID": 18057,
                    "comment": "task name",
                    "commentFiles": [],
                    "timestamp": 1694458584,
                    "userID": 340,
                    "commentEmailAddress": null,
                    "showExternalUsers": true
                  },
                  {
                    "commentID": 18058,
                    "comment": "complete the task",
                    "commentFiles": [],
                    "timestamp": 1694458628,
                    "userID": 340,
                    "commentEmailAddress": null,
                    "showExternalUsers": false
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Comments"
        ],
        "description": "This request gets all Task Comments associated with a Task.\n\nReturn data description\n\ncommentID | This is the commentID of comment.\ncomment | The text comment that was entered by the user.\ntimestamp | The date this comment was created. This is a unix timestamp.\nuserID | The ID of the user that made the comment.\ncommentEmailAddress | The email address of the external user that made this comment. This is only populated if the comment was made by an external user via the comment reply system.\nshowExternalUsers | The comment can be seen by external users or not., default value : true\ncommentFiles | Array of objects that have a file name and a link you can use to download that file. All links are only valid for 15 minutes, a new call will generate a new link."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "description": "taskID of the task you are adding a comment to.",
          "schema": {
            "type": "integer"
          },
          "example": 19696
        }
      ],
      "post": {
        "operationId": "postTasksByTaskIDComments",
        "summary": "Add Task Comments",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Comments"
        ],
        "description": "This request adds a comment to a task.\n\ncomment | String | Required | The comment to be added.\nshowExternalUsers | Boolean | Optional | This will show the comment to external users. The default value is true.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "comment": {
                    "type": "string"
                  },
                  "showExternalUsers": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "comment": "complete the task",
                "showExternalUsers": false
              }
            }
          }
        }
      }
    },
    "/v2/tasks/{taskID}/tags": {
      "get": {
        "operationId": "getTasksByTaskIDTags",
        "summary": "Tags",
        "responses": {
          "200": {
            "description": "Tags",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "tags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Tags"
        ],
        "description": "This request gets all Custom Tags associated with a Task.\n\nReturn data description\n\n| Property | Description |\n| --- | --- |\n| tags | An array of custom tags associated with the task. |"
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1160
        }
      ],
      "put": {
        "operationId": "putTasksByTaskIDTags",
        "summary": "PUT Apply Task Tags",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "description": "Invalid input — semicolons in tags, empty tags, etc."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "description": "One or more tags do not exist at the account level."
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Tags"
        ],
        "description": "Applies one or more existing custom tags to a task. Tags must already exist at the account level (see POST /v2/tags to create new tags).\n\nBody:\n- tags: string[] — List of tags, or\n- tag: string — Single tag.\n\nSuccess Response (200):\n- created: true\n- name?: string — Present when a single tag was added; canonical without trailing ';'.\n- sanitizations?: string[] — Applied normalizations.\n- note?: string — Present when input had multiple '@' characters.\n- tags: string[] — Updated canonical tags with trailing ';'.\n\nConflicts (409):\n- Single: { created: false, message: 'Tag already exists', name, tags }\n- Multiple: { created: false, message: 'No new tags to add', tags }\n\nErrors:\n- 404: { created: false, message, invalidTag(s), tags, availableTags } — Tag(s) don't exist at account level.\n- 400: { added: [], message: string } — Invalid input (semicolons, empty tags, etc.).\n\nNotes:\n- Tags MUST exist in the account's tag definitions before they can be applied to tasks.\n- Validation is case-insensitive (e.g., '@urgent' matches '@Urgent').\n- Semicolons in input are rejected.\n- The availableTags field in 404 responses shows which tags can be used."
      }
    },
    "/v2/tasks/{taskID}/tags/{tagRaw}": {
      "delete": {
        "operationId": "deleteTasksByTaskIDTagsByTagRaw",
        "summary": "DELETE Remove Task Tag",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "description": "Invalid input — tag name contains semicolons or is empty."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "description": "Tag not found on this task."
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Tags"
        ],
        "description": "Removes a single custom tag from a task.\n\nPath:\n- tag: string — Tag to remove; may be raw or canonical; server normalizes.\n\nSuccess Response (200):\n- deleted: true\n- name: string — Canonical tag (includes trailing ';').\n- tags: string[] — Updated canonical tags.\n\nErrors:\n- 404: { message: 'Tag not found' }\n- 400: { removed: null, message: string } — Invalid input."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "tagRaw",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ]
    },
    "/v2/work-requests/work-request-submissions": {
      "get": {
        "operationId": "getWorkRequestsWorkRequestSubmissions",
        "summary": "List WR Submissions",
        "parameters": [
          {
            "name": "orderBy",
            "in": "query",
            "description": "This parameter is used to order results by their createdAt, status, requestTitle, workRequestSubmissionID, and location property instead of the default ordering. each property can be flipped reverse by putting a minus before the property e.g. \"-createdAt\".",
            "schema": {
              "type": "string"
            },
            "example": "createdAt"
          },
          {
            "name": "search",
            "in": "query",
            "description": "Free-text search",
            "schema": {
              "type": "string"
            },
            "example": "pump"
          },
          {
            "name": "locationIDs",
            "in": "query",
            "description": "This parameter is used to only get work requests at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "statuses",
            "in": "query",
            "description": "CSV of statuses",
            "schema": {
              "type": "string"
            },
            "example": "open"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Max rows per page. Supports up to 1000 results.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "columns",
            "in": "query",
            "description": "CSV of field names (letters only); forwarded upstream as array",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "createdDateStart",
            "in": "query",
            "description": "ISO 8601 start",
            "schema": {
              "type": "string"
            },
            "example": "2025-06-20T20:51:13.000Z"
          },
          {
            "name": "createdDateEnd",
            "in": "query",
            "description": "ISO 8601 end (≥ start)",
            "schema": {
              "type": "string"
            },
            "example": "2025-06-20T20:51:13.000Z"
          },
          {
            "name": "workRequestIDs",
            "in": "query",
            "description": "CSV of WR IDs",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3"
          },
          {
            "name": "page",
            "in": "query",
            "description": "Page-based pagination (mutually exclusive with cursor)",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Cursor for pagination (forbidden with page)",
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "List of work request submissions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WorkRequestSubmission"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Work Request Submissions"
        ],
        "description": "Lists WR submissions\n\nReturn data description:\n\n| **Property** | **Description** |\n| --- | --- |\n| workRequestSubmissionId | The unique identifier of the work request submission. |\n| status | Pending, Approved or Rejected. |\n| createdByUserId | The unique identifier of the user who created the work request submission. |\n| createdAt | The date the work request submission was created. The timestamp is in the following format: YYYY-MM-DD (2025-07-02) HH:MM:SS (21:36:31) |\n| updatedAt | The date the work request submission was last updated. The timestamp is in the following format: YYYY-MM-DD (2025-07-02) HH:MM:SS (21:36:31) |\n| deletedAt | The date the work request submission was deleted. The timestamp is in the following format: YYYY-MM-DD (2025-07-02) HH:MM:SS (21:36:31) Will be NULL if the submission is not deleted. |\n| reviewedByUserId | The unique identifier of the user who reviewed the submission. |\n| reviewedAt | The date the work request submission was reviewed. The timestamp is in the following format: YYYY-MM-DD (2025-07-02) HH:MM:SS (21:36:31) Will be NULL if the submission has not yet been reviewed |\n| reviewedReason | The predefined reason the work request was declined. |\n| additionalNotes | Any additional notes the person who declined the submission wishes to leave. |\n| locationId | The unique identifier of the location the submission belongs to. |\n| assetId | The unique identifier of the asset associated with the submission. |\n| priorityId | The unique identifier of the priority of the submission. |\n| dueDateUnit | The unit of measure used to communicate when the task will be due. Can be “days” or “hours”. |\n| requestInformation | The information filled out in the Work Request Portal. Includes any of the following fields in JSON format. customerCode requesterName requesterEmail requesterPhone timeUnix customTag customFieldOne customFieldTwo customFieldThree customFieldOneTitle customFieldTwoTitle customFieldThreeTitle customFieldDropdownAnswerOne customFieldDropdownAnswerTwo customFieldDropdownAnswerThree customDropdownTitleOne customDropdownTitleTwo customDropdownTitleThree customDropdownOptionsOne customDropdownOptionsTwo customDropdownOptionsThree geoLocation |\n| customerID | The unique identifier of the customer account. |\n| requestTitle | The title of the submission. |\n| assignedToProfileId | The Limble profile the submission is assigned to. This is used to determine what team or individual is assigned to review the submission. |\n| requestDescription | The description of the problem filled out in the Work Request Portal. |\n| checklistID | The unique identifier of the task generated from the submission when it is approved. Will be NULL if submission status is declined or pending. |\n| requesterName | The name of the person who submitted the work request submission. |"
      },
      "post": {
        "operationId": "postWorkRequestsWorkRequestSubmissions",
        "summary": "Create WR Submission",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "locationID",
                  "dueDateUnit"
                ],
                "properties": {
                  "locationID": {
                    "type": "integer",
                    "description": "The location ID for the work request submission."
                  },
                  "assetID": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "The asset ID associated with the submission."
                  },
                  "parts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "partID": {
                          "type": "number"
                        },
                        "quantity": {
                          "type": "number"
                        }
                      }
                    }
                  },
                  "attachments": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "timeUnix": {
                    "type": "integer",
                    "description": "Unix timestamp for the request."
                  },
                  "priorityID": {
                    "type": [
                      "integer",
                      "null"
                    ],
                    "description": "Priority ID for the submission."
                  },
                  "dueDateUnit": {
                    "type": "string",
                    "description": "Unit for the due date. Can be \"days\" or \"hours\"."
                  },
                  "requesterName": {
                    "type": "string",
                    "description": "Name of the person submitting the request."
                  },
                  "requestTitle": {
                    "type": "string",
                    "description": "Title of the work request submission."
                  },
                  "requestDescription": {
                    "type": "string",
                    "description": "Description of the problem."
                  },
                  "requestInformation": {
                    "type": "object",
                    "description": "Additional information from the Work Request Portal form.",
                    "properties": {
                      "customerCode": {
                        "type": "string"
                      },
                      "requesterName": {
                        "type": "string"
                      },
                      "requesterEmail": {
                        "type": "string"
                      },
                      "requesterPhone": {
                        "type": "string"
                      },
                      "geoLocation": {
                        "type": "string"
                      },
                      "timeUnix": {
                        "type": "integer"
                      },
                      "customFieldOne": {
                        "type": "string"
                      },
                      "customFieldTwo": {
                        "type": "string"
                      },
                      "customFieldThree": {
                        "type": "string"
                      },
                      "customFieldOneTitle": {
                        "type": "string"
                      },
                      "customFieldTwoTitle": {
                        "type": "string"
                      },
                      "customFieldThreeTitle": {
                        "type": "string"
                      }
                    }
                  }
                }
              },
              "example": {
                "locationID": 205,
                "assetID": 10836,
                "dueDateUnit": "days",
                "requesterName": "John Doe",
                "requestTitle": "Broken pump",
                "requestDescription": "The pump on floor 2 is leaking."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Work request submission created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WorkRequestSubmission"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Work Request Submissions"
        ],
        "description": "Creates a new work request submission. The submission enters a pending state and must be approved or declined by a reviewer.\n\n`locationID` and `dueDateUnit` are required. All other fields are optional."
      }
    },
    "/v2/work-requests/work-request-submissions/{workRequestSubmissionID}/approve": {
      "post": {
        "operationId": "postWorkRequestSubmissionsApprove",
        "summary": "Approve WR Submission",
        "responses": {
          "200": {
            "description": "Work request submission approved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Work Request Submissions"
        ],
        "description": "Approves a pending work request submission, generating a task from it."
      },
      "parameters": [
        {
          "name": "workRequestSubmissionID",
          "in": "path",
          "required": true,
          "description": "The ID of the work request submission to approve.",
          "schema": {
            "type": "integer"
          },
          "example": 42
        }
      ]
    },
    "/v2/work-requests/work-request-submissions/{workRequestSubmissionID}/decline": {
      "post": {
        "operationId": "postWorkRequestSubmissionsDecline",
        "summary": "Decline WR Submission",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "declineReason": {
                    "type": "string",
                    "description": "Predefined reason for declining."
                  },
                  "additionalNotes": {
                    "type": "string",
                    "description": "Additional notes from the reviewer."
                  }
                }
              },
              "example": {
                "declineReason": "Duplicate request",
                "additionalNotes": "This issue was already reported under submission"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Work request submission declined",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks",
          "Work Request Submissions"
        ],
        "description": "Declines a pending work request submission.\n\nBoth `declineReason` and `additionalNotes` are optional strings."
      },
      "parameters": [
        {
          "name": "workRequestSubmissionID",
          "in": "path",
          "required": true,
          "description": "The ID of the work request submission to decline.",
          "schema": {
            "type": "integer"
          },
          "example": 42
        }
      ]
    },
    "/v2/tasks": {
      "post": {
        "operationId": "postTasks",
        "summary": "New Task",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "\"Priority Test\""
          },
          {
            "name": "locationID",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 34190
          },
          {
            "name": "due",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1749680211
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "templateID",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 9
          }
        ],
        "responses": {
          "201": {
            "description": "New Task",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/tasks/?tasks=8261"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "taskID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "taskID": 8261
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks"
        ],
        "description": "This request will create an empty Task, assign to a User or Team, etc.\n\nname | String | Required | The name of the Task.\nlocationID | Int | Required | The id of the Location this Task is assigned to. Must be the Location's unique ID number.\ndue | Int | Required | The time at which the Task is due. Must be a unix timestamp.\ntype | Int | Required | The type of Task according to this legend:, 1 = Preventative Maintanance (PM)., 2 = Unplanned Work Order (WO);, 4 = Planned Work Order (WO);, 6 = Work Request (WR)., Task types not listed here are not currently supported., If you would like another Task type to be supported, please contact us., A taskType of 6 prevents the user from assigning a batchID.\ndescription | string | Optional | A brief description about the Task.\nassetID | Int | Optional | The Asset that the Task will be attached to, if any. Must be the unique ID number of the Asset. Omitting this parameter or setting it to zero will not attach the Task to an asset.\nassignment | Int | Optional. Required if 'assignmentType' is used. | The User or Team to which the Task will be assigned. Must be a User or Team that exists at the specified Location. Must be the unique ID number of the user or Team. If this parameter is set, the assignmentType parameter must also be set.\ntemplateID | Int | Optional | The taskID of the task you wish to utilize as a template when posting a new Task. Using this will duplicate all steps in the Template to the newly created task. Templates can be easily viewed and built in Limble's web application.\nassignmentType | Enum | Optional. Required if 'assignment' is used. | Specifies whether this Task will be assigned to a 'user', 'team' or 'multi'. If this parameter is set, the assignment parameter must also be set.\npriority | Int | Optional | Specifies the priority of the Task. Must correspond to a 'priorityLevel' (See GET Priorities) configured in your Limble account.\nestimatedTime | Int | Optional | Updates the estimated time of the task. This is the time it takes to complete the task in minutes.\nscheduledStart | Int | Optional | The scheduled start date of the task. Must be a unix timestamp. Must be 0 or greater.\nscheduledEnd | Int | Optional | The scheduled end date of the task. Must be a unix timestamp. Must be 0 or greater. If both scheduledStart and scheduledEnd are provided, scheduledEnd must be greater than scheduledStart.\nrequestName | string | Optional | Specifies the name of the Work Requestor.\nrequestEmail | string | Optional | Specifies the email address of the Work Requestor.\nrequestPhone | string | Optional | Specifies the phone number of the Work Requestor.\nrequestDescription | string | Optional | Specifies the description of the problem submitted by the Work Requestor.\nmeta1 | string | Optional | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\nmeta2 | string | Optional | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\nmeta3 | string | Optional | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\ngeoLocation | geoJSON | Optional | The geoJSON Feature object that can be used to locate a task on a Map.\nmultiUsers | array | Optional. Required if assignmentType = multi | Array of user IDs to assign to the task. Must contain at least one user ID.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "locationID": {
                    "type": "integer"
                  },
                  "type": {
                    "type": "integer"
                  },
                  "due": {
                    "type": "integer"
                  },
                  "priority": {
                    "type": "integer"
                  },
                  "scheduledStart": {
                    "type": "integer"
                  },
                  "scheduledEnd": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "name": "Priority Test",
                "locationID": 34190,
                "type": 2,
                "due": 1748656599,
                "priority": 3,
                "scheduledStart": 1748650000,
                "scheduledEnd": 1748660000
              }
            }
          }
        }
      },
      "get": {
        "operationId": "getTasks",
        "summary": "Tasks",
        "parameters": [
          {
            "name": "tasks",
            "in": "query",
            "description": "This parameter is used to only get specific Tasks. This parameter accepts a comma delimited list of task IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 9109
          },
          {
            "name": "assets",
            "in": "query",
            "description": "This parameter is used to only get Tasks that are linked to an asset. This parameter accepts a comma delimited list of asset IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get Tasks at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 73
          },
          {
            "name": "type",
            "in": "query",
            "description": "This parameter is used to only get Tasks of a specific type. This parameter accepts a comma delimited list of task types.",
            "schema": {
              "type": "integer"
            },
            "example": 6
          },
          {
            "name": "name",
            "in": "query",
            "description": "This is a parameter used to string search for a name or partial name of a task this parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%test%"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Tasks that were last edited after the unix timestamp passed into the start parameter. For example, all Tasks that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1000000000
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Tasks that were last edited before the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 2500000000
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what taskID you want to start receiving results at. e.g. passing 137 here will only get you tasks with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "completedStart",
            "in": "query",
            "description": "This parameter is used to only get Tasks that were completed after the unix timestamp passed into this parameter. For example, all Assets that were completed after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "completedEnd",
            "in": "query",
            "description": "This parameter is used to only get Tasks that were completed before the unix timestamp passed into this parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 2500000000
          },
          {
            "name": "scheduledStart",
            "in": "query",
            "description": "This parameter is used as the start of a scheduled-date window. Tasks are returned when their scheduled date range overlaps this timestamp.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "scheduledEnd",
            "in": "query",
            "description": "This parameter is used as the end of a scheduled-date window. Tasks are returned when their scheduled date range overlaps this timestamp.",
            "schema": {
              "type": "integer"
            },
            "example": 2500000000
          },
          {
            "name": "orderBy",
            "in": "query",
            "description": "This parameter sorts based on the value you pass. Negative parameters are used to reverse sort order. This supports sorting by due, createdDate, dateCompleted, scheduledStart, scheduledEnd, and lastEdited.",
            "schema": {
              "type": "string"
            },
            "example": "-createdDate"
          },
          {
            "name": "geoLocation",
            "in": "query",
            "description": "This parameter is used to filter results that contain a geoLocation property. By default it is false and will return all tasks with and without geoLocation property. If true, it will only return tasks with a geoLocation property.",
            "schema": {
              "type": "boolean"
            },
            "example": true
          },
          {
            "name": "users",
            "in": "query",
            "description": "This parameter filters tasks by assignee user IDs. It returns tasks directly assigned to those users and tasks assigned through team/profile membership (including multi-user assignments). This parameter accepts a comma delimited list of user IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 11
          },
          {
            "name": "teams",
            "in": "query",
            "description": "This parameter is used to only get Tasks assigned to specific teams/profiles. This parameter accepts a comma delimited list of team IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 500
          },
          {
            "name": "lastEditedByUsers",
            "in": "query",
            "description": "This parameter is used to filter tasks by users who last edited the task.",
            "schema": {
              "type": "string"
            },
            "example": "0,340,341"
          },
          {
            "name": "status",
            "in": "query",
            "description": "This parameter is used to filter tasks by completed status. 1 - Complete  0 - Incomplete",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "meta1",
            "in": "query",
            "description": "This parameter is used to filter tasks by task meta data. This does not show in the web application, but can be used to track items between integrated systems.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "meta2",
            "in": "query",
            "description": "This parameter is used to filter tasks by task meta data. This does not show in the web application, but can be used to track items between integrated systems.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "meta3",
            "in": "query",
            "description": "This parameter is used to filter tasks by task meta data. This does not show in the web application, but can be used to track items between integrated systems.",
            "schema": {
              "type": "integer"
            },
            "example": 3
          },
          {
            "name": "statusIDs",
            "in": "query",
            "description": "This parameter is used to filter tasks by their associated statusID.",
            "schema": {
              "type": "string"
            },
            "example": "0,1,2"
          },
          {
            "name": "tag",
            "in": "query",
            "description": "This parameter is used to filter results that contain a certain custom tag. The tag must match exactly, i.e. \"Tag\" would not match \"My Custom Tag\". Searching for \"@My Custom Tag;\" is equivalent to searching for \"My Custom Tag\" but because custom tags are stored with an at sign (\"@\") at the beginning and a semicolon (\";\") at the end it is recommended that the param follows the same format.",
            "schema": {
              "type": "string"
            },
            "example": "@My Custom Tag;"
          }
        ],
        "responses": {
          "200": {
            "description": "Pagination using Page & Limit",
            "headers": {
              "Last-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/tasks/?limit=2&orderBy=createdDate&completedStart=0&status=1&page=152"
              },
              "Next-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/tasks/?limit=2&orderBy=createdDate&completedStart=0&status=1&page=3"
              },
              "Previous-Page": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/tasks/?limit=2&orderBy=createdDate&completedStart=0&status=1&page=1"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Task"
                  }
                },
                "example": [
                  {
                    "meta": {
                      "invoices": "/v2/tasks/invoices/?tasks=16",
                      "labor": "/v2/tasks/labor/?tasks=16",
                      "partsUsage": "/v2/parts/usage/?tasks=16",
                      "instructions": "/v2/tasks/16/instructions",
                      "status": "/v2/statuses/?statuses=2"
                    },
                    "taskID": 16,
                    "poIDs": [
                      1234
                    ],
                    "name": "Part Qty Threshold Hit",
                    "userID": 0,
                    "teamID": 436,
                    "locationID": 73,
                    "template": false,
                    "createdDate": 1457569392,
                    "scheduledStart": 0,
                    "scheduledEnd": 0,
                    "due": 1457569392,
                    "description": "",
                    "dateCompleted": 1457569392,
                    "lastEdited": 1518826313,
                    "lastEditedByUser": 0,
                    "completedByUser": 341,
                    "assetID": 0,
                    "completedUserWage": 15,
                    "priority": 0,
                    "priorityID": 8,
                    "downtime": 0,
                    "completionNotes": null,
                    "requestorName": null,
                    "requestorEmail": null,
                    "requestorPhone": null,
                    "requestTitle": null,
                    "requestField1": null,
                    "requestField2": null,
                    "requestField3": null,
                    "requestDropdown1": null,
                    "requestDropdown2": null,
                    "requestDropdown3": null,
                    "requestorDescription": null,
                    "meta1": null,
                    "meta2": null,
                    "meta3": null,
                    "statusID": 2,
                    "type": 7,
                    "status": 1
                  },
                  {
                    "meta": {
                      "invoices": "/v2/tasks/invoices/?tasks=36",
                      "labor": "/v2/tasks/labor/?tasks=36",
                      "partsUsage": "/v2/parts/usage/?tasks=36",
                      "instructions": "/v2/tasks/36/instructions",
                      "status": "/v2/statuses/?statuses=2"
                    },
                    "taskID": 36,
                    "name": "Part Qty Threshold Hit",
                    "userID": 0,
                    "teamID": 436,
                    "locationID": 73,
                    "template": false,
                    "createdDate": 1458062821,
                    "scheduledStart": 0,
                    "scheduledEnd": 0,
                    "due": 1458062821,
                    "description": "",
                    "dateCompleted": 1458062821,
                    "lastEdited": 1518826313,
                    "lastEditedByUser": 0,
                    "completedByUser": 341,
                    "assetID": 0,
                    "completedUserWage": 15,
                    "priority": 0,
                    "priorityID": 8,
                    "downtime": 0,
                    "completionNotes": null,
                    "requestorName": null,
                    "requestorEmail": null,
                    "requestorPhone": null,
                    "requestTitle": null,
                    "requestField1": null,
                    "requestField2": null,
                    "requestField3": null,
                    "requestDropdown1": null,
                    "requestDropdown2": null,
                    "requestDropdown3": null,
                    "requestorDescription": null,
                    "meta1": null,
                    "meta2": null,
                    "meta3": null,
                    "statusID": 2,
                    "type": 7,
                    "status": 1
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks"
        ],
        "description": "This request gets top level information about Tasks such as completed date, assignment, assetID, etc.\n\n**Note:** this endpoint supports pagination. Please refer to the [Pagination](#pagination) section for more information.\n\nReturn data description\n\nmeta | This property has shortcuts to get other information related to the Task such as the Task's invoices, labor parts usage and instructions.\nname | The Task's name.\nuserID | The id of the user this Task is assigned to. A Task can not be assigned to both a Team and a User at the same time.\nteamID | The id of the team this Task is assigned to. A Task can not be assigned to both a Team and a User at the same time.\nlocationID | The id of the Location in which this Task belongs to.\ntemplate | This field indicates if the task is a 'template' that spawns other tasks based on schedules or not.\ncreatedDate | The date this Task was created. This is a unix timestamp.\nstartDate | By default this value is 0 as the startDate is usually the same as the createdDate. Sometimes a task is created such that it is scheduled to start in the future (i.e. after the createdDate). In such a case this value will be a unix timestamp indicating the actual start date of the Task.\nscheduledStart | The scheduled start date of the Task. This is a unix timestamp. A value of null means no scheduled start date is set.\nscheduledEnd | The scheduled end date of the Task. This is a unix timestamp. A value of null means no scheduled end date is set.\ndue | The date this Task is due. This is a unix timestamp.\ndateCompleted | The date this Task was completed. This is a unix timestamp. A value of 0 means this Task is not completed.\nlastEdited | The date this Task was last edited. This is a unix timestamp.\ndescription | The decription of a task.\ncompletedByUser | The id of the User that completed this Task.\nlastEditedByUser | The id of the User that last edited the task.\nassetID | The id of the Asset that this Task belongs to.\ncompletedUserWage | The price per hour of the User's Wage at the point in time when the task was completed.\npriority | The priority of the Task.\ndowntime | The amount of downtime in seconds caused by this Task.\nestimatedTime | The estimated time of the task. This is the time it takes to complete the task in minutes.\ncompletionNotes | Notes inputted by the user at the time of task completion.\nrequestorName | The name of the person that requested this Task.\nrequestorEmail | The email of the person that requested this Task.\nrequestorPhone | The phone number of the person that requested this Task.\nrequestTile | The title of the work request being submitted.\nrequestField1 | Work request portal custom field 1.\nrequestField2 | Work request portal custom field 2.\nrequestField3 | Work request portal custom field 3.\nrequestDropdown1 | Work request portal custom dropdown box 1.\nrequestDropdown2 | Work request portal custom dropdown box 2.\nrequestDropdown3 | Work request portal custom dropdown box 3.\nrequestorDescription | The description of the request submitted via the Work Request portal.\ntype | 1 = Preventative Maintanance (PM);, 2 = Unplanned Work Order (WO);, 4 = Planned Work Order (WO);, 5 = Cycle Count;, 6 = Work Request (WR);, 7 = Min Part Threshold;, 8 = Materials Request;\nstatus | 1 - Complete, 0 - Incomplete, Note: this property indicates a task status with respect to task completion. For the custom task status refer to statusID\nstatusID | The current custom status assigned to this task., Note: this indicates the current status of a task. Use GET Statuses to find the value of each statusID.\npoIDs | An array of Purchase Order IDs linked to this Task. Returns an empty array if no Purchase Orders are linked.\nassociatedTaskID (deprecated) | Please refer to associatedTask meta property on GET Task Instruction for instruction type 14.\nmeta1 | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\nmeta2 | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\nmeta3 | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\ngeoLocation | The location of a task on a Map.\ncustomTags | An array of custom tags associated with the task."
      }
    },
    "/v2/tasks/{taskID}": {
      "patch": {
        "operationId": "patchTasksByTaskID",
        "summary": "Update Task",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks"
        ],
        "description": "This request updates the top level information of a Task.\n\nname | String | Optional | The name of the task.\nlocationID | Int | Optional | The location to which the task is assigned. Must be the location's unique ID number.\ndue | Int | Optional | The time at which the task is due for completion. Must be a unix timestamp.\ntype | Int | Optional | The type of task according to this legend:, 1 = Preventative Maintanance (PM)., 2 = Unplanned Work Order (WO);, 4 = Planned Work Order (WO);, 6 = Work Request (WR)., Only these type of tasks can be changed from one task type to another.\ndescription | string | Optional | A brief description about the task.\nasset | Int | Optional | The asset that the task will be attached to, if any. Must be the unique ID number of the asset. Omitting this parameter or setting it to zero will not attach the task to any asset.\nassignment | Int or null | Optional | The user or team to which the task will be assigned. Must be the unique ID number of the user or team that exists at the specified location. Pass 0 or null to unassign the task. Required when assignmentType is set and status is 1 (close). Not applicable when assignmentType is 'multi'.\nassignmentType | Enum | Optional. Required if 'assignment' is used. | Specifies whether this task will be assigned to a 'user', 'team' or 'multi'. If this parameter is set, the assignment parameter must also be set.\npriority | Int | Optional | Specifies the priority of the task. Must be between 0 and 6 inclusive: 0 = lowest priority, 5 = highest priority, 6 = \"On Hold\".\nestimatedTime | Int | Optional | Updates the estimated time of the task. This is the time it takes to complete the task in minutes.\nscheduledStart | Int | Optional | The scheduled start date of the task. Must be a unix timestamp. Must be 0 or greater.\nscheduledEnd | Int | Optional | The scheduled end date of the task. Must be a unix timestamp. Must be 0 or greater. If both scheduledStart and scheduledEnd are provided, scheduledEnd must be greater than scheduledStart.\nrequestName | string | Optional | Specifies the name of the work requestor.\nrequestEmail | string | Optional | Specifies the email address of the work requestor.\nrequestPhone | string | Optional | Specifies the phone number of the work requestor.\nrequestDescription | string | Optional | Specifies the description set by the work requestor.\nstatus | int | Optional | 1 - Closes a task., 0 - Opens a task., If this parameter is set to 1, the assignment and assignmentType parameters must also be set.\nmeta1 | string | Optional | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\nmeta2 | string | Optional | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\nmeta3 | string | Optional | Task meta data. This does not show in the web application, but can be used to track items between integrated systems.\ngeoLocation | geoJSON | Optional | The geoJSON Feature object that can be used to locate a task on a Map. To remove geoLocation from a Task pass an empty object ({}).\nstatusID | int | Optional | Update the custom status of the task. Cannot update custom status to 1 (Open) or 2 (Complete).\nmultiUsers | array | Optional. Required if assignmentType = multi | Array of user IDs to assign to the task. Must contain at least one user for non-template tasks. Pass an empty array ([]) to remove all users from a PM template (unassign)."
      },
      "parameters": [
        {
          "name": "taskID",
          "in": "path",
          "required": true,
          "description": "taskID of the task you are removing.",
          "schema": {
            "type": "string"
          },
          "example": "{{taskID}}"
        }
      ],
      "delete": {
        "operationId": "deleteTasksByTaskID",
        "summary": "Delete Task",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tasks"
        ]
      }
    },
    "/v2/users/{userID}/roles": {
      "get": {
        "operationId": "getUsersByUserIDRoles",
        "summary": "Get User Roles",
        "parameters": [
          {
            "name": "roles",
            "in": "query",
            "description": "This parameter expects a comma-separated list of roleIDs to filter teams by",
            "schema": {
              "type": "string"
            },
            "example": "1,2"
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter expects a comma-separated list of locationIDs to filter roles by",
            "schema": {
              "type": "string"
            },
            "example": "163,202"
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific role by name. This parameter expects a string full name of a user or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%Manager%"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what teamID you want to start receiving results at. e.g. passing 137 here will only get you tasks with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Get User Roles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "roleID": {
                        "type": "integer"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "roleID": 320,
                    "locationID": 74,
                    "name": "Manager"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Roles"
        ],
        "description": "This request gets all of the Roles a User has and what Location they have that Role at."
      },
      "parameters": [
        {
          "name": "userID",
          "in": "path",
          "required": true,
          "description": "userID of the role user you are removing the Role from.",
          "schema": {
            "type": "string"
          },
          "example": "{{userID}}"
        }
      ],
      "put": {
        "operationId": "putUsersByUserIDRoles",
        "summary": "Add User To Role",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Roles"
        ],
        "description": "This request adds a User to a Role."
      },
      "delete": {
        "operationId": "deleteUsersByUserIDRoles",
        "summary": "Remove Role From User",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Roles"
        ],
        "description": "This request removes a Role from a User."
      }
    },
    "/v2/users/{userID}/teams": {
      "get": {
        "operationId": "getUsersByUserIDTeams",
        "summary": "Get User Teams",
        "parameters": [
          {
            "name": "teams",
            "in": "query",
            "description": "This parameter expects a comma-separated list of teamIDs to filter teams by",
            "schema": {
              "type": "string"
            },
            "example": "436,437"
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter expects a comma-separated list of locationIDs to filter teams by",
            "schema": {
              "type": "string"
            },
            "example": "163,74"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what teamID you want to start receiving results at. e.g. passing 137 here will only get you tasks with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific team by name. This parameter expects a string full name of a user or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%Manager%"
          }
        ],
        "responses": {
          "200": {
            "description": "Get User Teams",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "teamID": {
                        "type": "integer"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "teamID": 436,
                    "locationID": 74,
                    "name": "Manager"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Teams"
        ],
        "description": "This request gets all of the Teams a User has and what Location they have that Team at."
      },
      "parameters": [
        {
          "name": "userID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "example": "{{userID}}"
        }
      ],
      "put": {
        "operationId": "putUsersByUserIDTeams",
        "summary": "Add User To Team",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Teams"
        ],
        "description": "This request adds a User to a Team."
      },
      "delete": {
        "operationId": "deleteUsersByUserIDTeams",
        "summary": "Remove Team From User",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Teams"
        ],
        "description": "This request removes a Team from a User."
      }
    },
    "/v2/users/capacity/exceptions/{userID}": {
      "get": {
        "operationId": "getUsersCapacityExceptionsByUserID",
        "summary": "Get Capacity Exceptions by User",
        "parameters": [
          {
            "name": "locations",
            "in": "query",
            "description": "Required comma-separated location IDs used to scope the user access context.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "startDate",
            "in": "query",
            "description": "Optional lower date bound (YYYY-MM-DD) for overlap filtering.",
            "schema": {
              "type": "string"
            },
            "example": "2026-01-01"
          },
          {
            "name": "endDate",
            "in": "query",
            "description": "Optional upper date bound (YYYY-MM-DD) for overlap filtering. Must be >= startDate when both are present.",
            "schema": {
              "type": "string"
            },
            "example": "2026-01-31"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Optional ID cursor for keyset pagination.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Optional max rows per page.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Get User Capacity Exceptions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "exceptionID": {
                        "type": "integer"
                      },
                      "userID": {
                        "type": "integer"
                      },
                      "createdByUserID": {
                        "type": "integer"
                      },
                      "exceptionStartDate": {
                        "type": "string",
                        "format": "date"
                      },
                      "exceptionEndDate": {
                        "type": "string",
                        "format": "date"
                      },
                      "capacityMinutes": {
                        "type": "integer"
                      },
                      "hoursPerDay": {
                        "type": "integer"
                      },
                      "minutesPerDay": {
                        "type": "integer"
                      },
                      "exceptionTitle": {
                        "type": "string"
                      },
                      "exceptionNotes": {
                        "type": "string"
                      },
                      "exceptionType": {
                        "description": "Structured planned/unplanned classification. Null when unset.",
                        "enum": [
                          "planned",
                          "unplanned",
                          null
                        ]
                      }
                    }
                  }
                },
                "example": [
                  {
                    "exceptionID": 1201,
                    "userID": 42,
                    "createdByUserID": 1,
                    "exceptionStartDate": "2026-01-10",
                    "exceptionEndDate": "2026-01-20",
                    "capacityMinutes": 300,
                    "hoursPerDay": 5,
                    "minutesPerDay": 0,
                    "exceptionTitle": "Training Week",
                    "exceptionNotes": "Limited availability",
                    "exceptionType": "planned"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Capacity",
          "Exceptions"
        ],
        "description": "Gets capacity exception records for a specific user.\n\n`capacityMinutes` is the user's available capacity **per day** for each date in the exception range.\n\nQuery behavior:\n- `locations` scopes by user location membership.\n- `startDate`/`endDate` filter by date overlap (YYYY-MM-DD).\n- `cursor`/`limit` paginate results.\n\nResponse fields include:\n`exceptionID`, `userID`, `createdByUserID`, `exceptionStartDate`, `exceptionEndDate`, `capacityMinutes`, `hoursPerDay`, `minutesPerDay`, `exceptionTitle`, `exceptionNotes`, `exceptionType`."
      },
      "parameters": [
        {
          "name": "userID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "post": {
        "operationId": "postUsersCapacityExceptionsByUserID",
        "summary": "New Capacity Exception",
        "responses": {
          "201": {
            "description": "New Capacity Exception",
            "headers": {
              "Location": {
                "description": "Location of the created resource",
                "schema": {
                  "type": "string"
                },
                "example": "/v2/users/capacity/exceptions/42/1201"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "exceptionID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "exceptionID": 1201
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Capacity",
          "Exceptions"
        ],
        "description": "Creates a capacity exception for a user.\n\n`capacityMinutes` means the user's available work capacity **per day** for each day in the exception date/range. It is **not** the total duration of the exception range.\n\nExamples:\n\n- `capacityMinutes: 0` => unavailable that day (or each day in the range).\n    \n- `capacityMinutes: 480` => 8 hours available per day.\n    \n\nYou can provide either:\n\n- `capacityMinutes` directly, or\n    \n- `hoursPerDay` + `minutesPerDay` (equivalent input).",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "exceptionStartDate": {
                    "type": "string",
                    "format": "date"
                  },
                  "exceptionEndDate": {
                    "type": "string",
                    "format": "date"
                  },
                  "capacityMinutes": {
                    "type": "integer"
                  },
                  "exceptionTitle": {
                    "type": "string"
                  },
                  "exceptionNotes": {
                    "type": "string"
                  },
                  "exceptionType": {
                    "description": "Optional structured classification. 'planned' or 'unplanned'; null/omitted leaves it unset.",
                    "enum": [
                      "planned",
                      "unplanned",
                      null
                    ]
                  }
                }
              },
              "example": {
                "exceptionStartDate": "2026-01-10",
                "exceptionEndDate": "2026-01-20",
                "capacityMinutes": 300,
                "exceptionTitle": "Training Week",
                "exceptionNotes": "Limited availability",
                "exceptionType": "planned"
              }
            }
          }
        }
      }
    },
    "/v2/users/capacity/exceptions": {
      "get": {
        "operationId": "getUsersCapacityExceptions",
        "summary": "Get Capacity Exceptions by Location",
        "parameters": [
          {
            "name": "locations",
            "in": "query",
            "description": "Required comma-separated location IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,3"
          },
          {
            "name": "users",
            "in": "query",
            "description": "Optional comma-separated user IDs filter.",
            "schema": {
              "type": "string"
            },
            "example": "42,57"
          },
          {
            "name": "startDate",
            "in": "query",
            "description": "Optional lower date bound (YYYY-MM-DD) for overlap filtering.",
            "schema": {
              "type": "string"
            },
            "example": "2026-01-01"
          },
          {
            "name": "endDate",
            "in": "query",
            "description": "Optional upper date bound (YYYY-MM-DD) for overlap filtering. Must be >= startDate when both are present.",
            "schema": {
              "type": "string"
            },
            "example": "2026-01-31"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Optional ID cursor for keyset pagination.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Optional max rows per page.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Get Capacity Exceptions By Location",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "exceptionID": {
                        "type": "integer"
                      },
                      "userID": {
                        "type": "integer"
                      },
                      "createdByUserID": {
                        "type": "integer"
                      },
                      "exceptionStartDate": {
                        "type": "string",
                        "format": "date"
                      },
                      "exceptionEndDate": {
                        "type": "string",
                        "format": "date"
                      },
                      "capacityMinutes": {
                        "type": "integer"
                      },
                      "hoursPerDay": {
                        "type": "integer"
                      },
                      "minutesPerDay": {
                        "type": "integer"
                      },
                      "exceptionTitle": {
                        "type": "string"
                      },
                      "exceptionNotes": {
                        "type": "string"
                      },
                      "exceptionType": {
                        "description": "Structured planned/unplanned classification. Null when unset.",
                        "enum": [
                          "planned",
                          "unplanned",
                          null
                        ]
                      }
                    }
                  }
                },
                "example": [
                  {
                    "exceptionID": 1201,
                    "userID": 42,
                    "createdByUserID": 1,
                    "exceptionStartDate": "2026-01-10",
                    "exceptionEndDate": "2026-01-20",
                    "capacityMinutes": 300,
                    "hoursPerDay": 5,
                    "minutesPerDay": 0,
                    "exceptionTitle": "Training Week",
                    "exceptionNotes": "Limited availability",
                    "exceptionType": "planned"
                  },
                  {
                    "exceptionID": 1202,
                    "userID": 57,
                    "createdByUserID": 1,
                    "exceptionStartDate": "2026-01-15",
                    "exceptionEndDate": "2026-01-15",
                    "capacityMinutes": 120,
                    "hoursPerDay": 2,
                    "minutesPerDay": 0,
                    "exceptionTitle": "Half Day",
                    "exceptionNotes": "On-site meeting",
                    "exceptionType": "unplanned"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Capacity",
          "Exceptions"
        ],
        "description": "Gets capacity exception records across users for the requested locations.\n\n`capacityMinutes` is the user's available capacity **per day** for each date in the exception range.\n\nQuery behavior:\n- `locations` is required.\n- `users` optionally narrows results to specific users.\n- `startDate`/`endDate` filter by date overlap (YYYY-MM-DD).\n- `cursor`/`limit` paginate results.\n\nResponse fields include:\n`exceptionID`, `userID`, `createdByUserID`, `exceptionStartDate`, `exceptionEndDate`, `capacityMinutes`, `hoursPerDay`, `minutesPerDay`, `exceptionTitle`, `exceptionNotes`, `exceptionType`."
      }
    },
    "/v2/users/capacity/exceptions/{userID}/{exceptionID}": {
      "delete": {
        "operationId": "deleteUsersCapacityExceptionsByUserIDByExceptionID",
        "summary": "Delete Capacity Exception",
        "responses": {
          "204": {
            "description": "Delete Capacity Exception",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "example": {}
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Capacity",
          "Exceptions"
        ],
        "description": "Deletes a capacity exception for a user."
      },
      "parameters": [
        {
          "name": "userID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        },
        {
          "name": "exceptionID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          }
        }
      ],
      "patch": {
        "operationId": "patchUsersCapacityExceptionsByUserIDByExceptionID",
        "summary": "Update Capacity Exception",
        "responses": {
          "200": {
            "description": "Update Capacity Exception",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "exceptionID": {
                      "type": "integer"
                    },
                    "userID": {
                      "type": "integer"
                    },
                    "createdByUserID": {
                      "type": "integer"
                    },
                    "exceptionStartDate": {
                      "type": "string",
                      "format": "date"
                    },
                    "exceptionEndDate": {
                      "type": "string",
                      "format": "date"
                    },
                    "capacityMinutes": {
                      "type": "integer"
                    },
                    "hoursPerDay": {
                      "type": "integer"
                    },
                    "minutesPerDay": {
                      "type": "integer"
                    },
                    "exceptionTitle": {
                      "type": "string"
                    },
                    "exceptionNotes": {
                      "type": "string"
                    },
                    "exceptionType": {
                      "description": "Structured planned/unplanned classification. Null when unset.",
                      "enum": [
                        "planned",
                        "unplanned",
                        null
                      ]
                    }
                  }
                },
                "example": {
                  "exceptionID": 1201,
                  "userID": 42,
                  "createdByUserID": 1,
                  "exceptionStartDate": "2026-01-10",
                  "exceptionEndDate": "2026-01-20",
                  "capacityMinutes": 240,
                  "hoursPerDay": 4,
                  "minutesPerDay": 0,
                  "exceptionTitle": "Updated availability",
                  "exceptionNotes": "Shortened due to meetings",
                  "exceptionType": "unplanned"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Capacity",
          "Exceptions"
        ],
        "description": "This request updates an existing capacity exception and returns the updated resource.\n\n`capacityMinutes` means the user's available capacity **per day** for each day in the exception date/range. It is **not** the total duration of the exception range.\n\nExamples:\n- `capacityMinutes: 0` => unavailable that day (or each day in the range).\n- `capacityMinutes: 480` => 8 hours available per day.\n\nReturn data description\n\nProperty\tDescription\nexceptionID\tUnique ID for the capacity exception record.\nuserID\tThe user the exception applies to.\ncreatedByUserID\tThe user who created the exception.\nexceptionStartDate\tThe first date the exception applies (YYYY-MM-DD).\nexceptionEndDate\tThe last date the exception applies (YYYY-MM-DD). Null when the exception is only for one day.\ncapacityMinutes\tAllowed capacity in minutes **per day** for the exception date/range.\nhoursPerDay\tDerived whole-hour portion of capacityMinutes.\nminutesPerDay\tDerived minute remainder after hoursPerDay.\nexceptionTitle\tOptional short title for the exception.\nexceptionNotes\tOptional notes/details for the exception.\nexceptionType\tStructured planned/unplanned classification ('planned', 'unplanned', or null when unset).",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "exceptionStartDate": {
                    "type": "string",
                    "format": "date"
                  },
                  "exceptionEndDate": {
                    "type": "string",
                    "format": "date"
                  },
                  "capacityMinutes": {
                    "type": "integer"
                  },
                  "exceptionTitle": {
                    "type": "string"
                  },
                  "exceptionNotes": {
                    "type": "string"
                  },
                  "exceptionType": {
                    "description": "Optional structured classification. 'planned' or 'unplanned'; null clears it. Omitting the field preserves the current value.",
                    "enum": [
                      "planned",
                      "unplanned",
                      null
                    ]
                  }
                }
              },
              "example": {
                "exceptionStartDate": "2026-01-10",
                "exceptionEndDate": "2026-01-20",
                "capacityMinutes": 240,
                "exceptionTitle": "Updated availability",
                "exceptionNotes": "Shortened due to meetings",
                "exceptionType": "unplanned"
              }
            }
          }
        }
      }
    },
    "/v2/users/capacity/schedules": {
      "get": {
        "operationId": "getUsersCapacitySchedules",
        "summary": "Get Capacity Schedules",
        "parameters": [
          {
            "name": "locations",
            "in": "query",
            "description": "Required comma-separated location IDs to scope users.",
            "schema": {
              "type": "string"
            },
            "example": "1,3"
          },
          {
            "name": "users",
            "in": "query",
            "description": "Optional comma-separated user IDs filter.",
            "schema": {
              "type": "string"
            },
            "example": "42,57"
          },
          {
            "name": "startDate",
            "in": "query",
            "description": "Required start date (YYYY-MM-DD).",
            "schema": {
              "type": "string"
            },
            "example": "2026-01-05"
          },
          {
            "name": "endDate",
            "in": "query",
            "description": "Required end date (YYYY-MM-DD), must be >= startDate and within 31 days.",
            "schema": {
              "type": "string"
            },
            "example": "2026-01-07"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Optional zero-based user offset for pagination.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "Optional page size. Supports up to 1000 results.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Get Capacity Schedules",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "range": {
                      "type": "object",
                      "properties": {
                        "startDate": {
                          "type": "string",
                          "format": "date"
                        },
                        "endDate": {
                          "type": "string",
                          "format": "date"
                        }
                      }
                    },
                    "locations": {
                      "type": "array",
                      "items": {
                        "type": "integer"
                      }
                    },
                    "users": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "userID": {
                            "type": "integer"
                          },
                          "locations": {
                            "type": "array",
                            "items": {
                              "type": "integer"
                            }
                          },
                          "days": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "date": {
                                  "type": "string",
                                  "format": "date"
                                },
                                "capacityMinutes": {
                                  "type": "integer"
                                },
                                "hoursPerDay": {
                                  "type": "integer"
                                },
                                "minutesPerDay": {
                                  "type": "integer"
                                },
                                "isAvailable": {
                                  "type": "boolean"
                                },
                                "appliedRule": {
                                  "type": "string"
                                },
                                "reason": {
                                  "type": "string"
                                },
                                "reasonDetails": {
                                  "type": "object",
                                  "properties": {
                                    "scheduleID": {
                                      "type": "integer"
                                    },
                                    "profileID": {
                                      "type": "null"
                                    }
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "cursor": {
                          "type": "integer"
                        },
                        "limit": {
                          "type": "integer"
                        },
                        "totalUsers": {
                          "type": "integer"
                        },
                        "nextCursor": {
                          "type": "null"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "range": {
                    "startDate": "2026-01-05",
                    "endDate": "2026-01-07"
                  },
                  "locations": [
                    1,
                    3
                  ],
                  "users": [
                    {
                      "userID": 42,
                      "locations": [
                        1
                      ],
                      "days": [
                        {
                          "date": "2026-01-05",
                          "capacityMinutes": 300,
                          "hoursPerDay": 5,
                          "minutesPerDay": 0,
                          "isAvailable": true,
                          "appliedRule": "userSchedule",
                          "reason": "Capacity from user schedule",
                          "reasonDetails": {
                            "scheduleID": 1201,
                            "profileID": null
                          }
                        }
                      ]
                    }
                  ],
                  "pagination": {
                    "cursor": 0,
                    "limit": 100,
                    "totalUsers": 1,
                    "nextCursor": null
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/ValidationLimitExceeded"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Capacity",
          "Schedules"
        ],
        "description": "Returns per-user daily capacity rows for a date range, including applied precedence details.\n\nPrecedence order:\n`exception > holiday > userSchedule > profileSchedule > default`.\n\nPagination:\n- `cursor` is a zero-based offset.\n- `limit` max is 100.\n\nDate limits:\n- `startDate` and `endDate` are required (YYYY-MM-DD).\n- Date range cannot exceed 31 days.\n\nResponse notes:\n- `range` now contains only `startDate` and `endDate`.\n- `pagination` contains `cursor`, `limit`, `totalUsers`, and `nextCursor`."
      },
      "post": {
        "operationId": "postUsersCapacitySchedules",
        "summary": "Create Capacity Schedule",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "scheduleName",
                  "startDate",
                  "locationID"
                ],
                "properties": {
                  "scheduleName": {
                    "type": "string",
                    "maxLength": 255,
                    "description": "Name of the schedule."
                  },
                  "startDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                    "description": "Start date (YYYY-MM-DD)."
                  },
                  "endDate": {
                    "type": "string",
                    "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
                    "description": "Optional end date (YYYY-MM-DD). Must be >= startDate."
                  },
                  "locationID": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Location ID for the schedule."
                  },
                  "userID": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "User ID to assign. Mutually exclusive with profileID."
                  },
                  "profileID": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Team profile ID to assign. Mutually exclusive with userID."
                  },
                  "mondayCapacity": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1440
                  },
                  "tuesdayCapacity": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1440
                  },
                  "wednesdayCapacity": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1440
                  },
                  "thursdayCapacity": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1440
                  },
                  "fridayCapacity": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1440
                  },
                  "saturdayCapacity": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1440
                  },
                  "sundayCapacity": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1440
                  },
                  "mondayStartTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "mondayEndTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "tuesdayStartTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "tuesdayEndTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "wednesdayStartTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "wednesdayEndTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "thursdayStartTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "thursdayEndTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "fridayStartTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "fridayEndTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "saturdayStartTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "saturdayEndTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "sundayStartTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "sundayEndTime": {
                    "type": "string",
                    "pattern": "^\\d{2}:\\d{2}(:\\d{2})?$"
                  },
                  "rotationPatternEnabled": {
                    "type": "boolean",
                    "description": "Enable rotation pattern. When true, rotationWeeksOn and rotationWeeksOff are required."
                  },
                  "rotationWeeksOn": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 52
                  },
                  "rotationWeeksOff": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 52
                  },
                  "scheduleNotes": {
                    "type": "string",
                    "maxLength": 2000
                  },
                  "priority": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 1000
                  },
                  "isActive": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "scheduleName": "Morning Shift",
                "startDate": "2026-02-01",
                "endDate": "2026-06-30",
                "locationID": 1,
                "userID": 42,
                "mondayCapacity": 480,
                "tuesdayCapacity": 480,
                "wednesdayCapacity": 480,
                "thursdayCapacity": 480,
                "fridayCapacity": 480,
                "saturdayCapacity": 0,
                "sundayCapacity": 0
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/users/capacity/schedules/1201"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "scheduleID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "scheduleID": 1201
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Capacity",
          "Schedules"
        ],
        "description": "Creates a new capacity schedule for a user or team profile at a specific location.\n\nExactly one of `userID` or `profileID` must be provided (mutually exclusive).\n\nWhen `rotationPatternEnabled` is true, both `rotationWeeksOn` and `rotationWeeksOff` are required.\n\nCapacity values are in minutes per day (0-1440). Time values use HH:MM or HH:MM:SS format."
      }
    },
    "/v2/users/capacity/schedules/{scheduleID}": {
      "delete": {
        "operationId": "deleteUsersCapacitySchedulesByScheduleID",
        "summary": "Delete Capacity Schedule",
        "responses": {
          "204": {
            "description": "Schedule deleted successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users",
          "Capacity",
          "Schedules"
        ],
        "description": "Deletes a capacity schedule by its ID."
      },
      "parameters": [
        {
          "name": "scheduleID",
          "in": "path",
          "required": true,
          "description": "The ID of the capacity schedule to delete.",
          "schema": {
            "type": "integer"
          },
          "example": 1201
        }
      ]
    },
    "/v2/users": {
      "get": {
        "operationId": "getUsers",
        "summary": "Users",
        "parameters": [
          {
            "name": "users",
            "in": "query",
            "description": "This parameter expects a comma-separated list of users to get by id",
            "schema": {
              "type": "integer"
            },
            "example": 342
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific user by name. This parameter expects a string full name of a user or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%jeff%"
          },
          {
            "name": "roles",
            "in": "query",
            "description": "This parameter expects a comma-separated list of users to get by roleID",
            "schema": {
              "type": "integer"
            },
            "example": 320
          },
          {
            "name": "teams",
            "in": "query",
            "description": "This parameter expects a comma-separated list of users to get by teamID",
            "schema": {
              "type": "string"
            },
            "example": "436,437"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what userID you want to start receiving results at. e.g. passing 137 here will only get you tasks with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Users",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/User"
                  }
                },
                "example": [
                  {
                    "userID": 341,
                    "username": "jeff",
                    "email": "jbezos@limblecmms.com",
                    "phone": "8015555555",
                    "firstName": "jeff",
                    "lastName": "bezos",
                    "wage": 16,
                    "active": "true",
                    "emailNotificationActive": "false",
                    "pushNotificationActive": "false",
                    "workdayHours": 8,
                    "dateAdded": 0,
                    "teams": [
                      {
                        "teamID": 436,
                        "locationID": 74,
                        "name": "Manager"
                      },
                      {
                        "teamID": 436,
                        "locationID": 163,
                        "name": "Manager"
                      },
                      {
                        "teamID": 436,
                        "locationID": 584,
                        "name": "Manager"
                      },
                      {
                        "teamID": 437,
                        "locationID": 585,
                        "name": "Technician"
                      },
                      {
                        "teamID": 436,
                        "locationID": 587,
                        "name": "Manager"
                      }
                    ],
                    "roles": [
                      {
                        "roleID": 320,
                        "locationID": 74,
                        "name": "Super User"
                      },
                      {
                        "roleID": 321,
                        "locationID": 74,
                        "name": "Manager"
                      },
                      {
                        "roleID": 321,
                        "locationID": 163,
                        "name": "Manager"
                      },
                      {
                        "roleID": 321,
                        "locationID": 584,
                        "name": "Manager"
                      },
                      {
                        "roleID": 321,
                        "locationID": 587,
                        "name": "Manager"
                      },
                      {
                        "roleID": 322,
                        "locationID": 585,
                        "name": "Technician"
                      }
                    ]
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users"
        ],
        "description": "This request gets information about Users such as User Login, User Email etc.\n\nReturn data description\n\nProperty: username, Description: What a User uses to login.\nProperty: wage, Description: The hourly rate of an employee.\nProperty: active, Description: Determines if a user can log into Limble or not.\nProperty: emailNotificationActive, Description: Determines if a User gets Email Notifications From Limble.\nProperty: pushNotificationActive, Description: Determines if a User gets Push Notifications From Limble.\nProperty: workdayHours, Description: The number of hours a day this employee works.\nProperty: dateAdded, Description: The date a user was added to Limble. This is a unix timestamp.\nProperty: teams, Description: What Teams a User has at specific Locations."
      },
      "post": {
        "operationId": "postUsers",
        "summary": "New User",
        "responses": {
          "201": {
            "description": "New User",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "userID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "userID": 1337
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users"
        ],
        "description": "This request creates a new User and emails them a welcome email with details on how to access Limble.\n\nParameter: firstName, Type: String, Required?: Optional, Description: The User's first name.\nParameter: lastName, Type: String, Required?: Optional, Description: The User's last name.\nParameter: email, Type: string, Required?: Required, Description: The User's email address.\nParameter: password, Type: string, Required?: Optional, Description: The User's password.\nParameter: locationID, Type: Int, Required?: Required, Description: The locationID of the Location the Role will be at.\nParameter: roleID, Type: Int, Required?: Required, Description: The initial Role this user will be granted. This can be changed later with the \"Add Role To User\" request.\nParameter: phone, Type: string, Required?: Optional, Description: The User's phone number.\nParameter: wage, Type: number, Required?: Optional, Description: The User's wage per hour.\nParameter: workDayHours, Type: number, Required?: Optional, Description: The User's hours per day they work.\nParameter: active, Type: Boolean, Required?: Optional, Description: The User's activation status.\nParameter: emailNotificationActive, Type: Boolean, Required?: Optional, Description: The User's email notification activation status. Should they receive email notifications?\nParameter: pushNotificationActive, Type: Boolean, Required?: Optional, Description: The User's push notification activation status. Should they receive push notifications?"
      }
    },
    "/v2/users/{userID}": {
      "patch": {
        "operationId": "patchUsersByUserID",
        "summary": "Update User",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users"
        ],
        "description": "This request updates a User details such as first name, last name, phone number, active status and more.\n\nParameter: firstName, Type: String, Required?: Optional, Description: The User's first name.\nParameter: lastName, Type: String, Required?: Optional, Description: The User's last name.\nParameter: email, Type: string, Required?: Optional, Description: The User's email address.\nParameter: username, Type: string, Required?: Optional, Description: The User's login name.\nParameter: password, Type: string, Required?: Optional, Description: A new password for the User.\nParameter: phone, Type: string, Required?: Optional, Description: The User's phone number.\nParameter: wage, Type: number, Required?: Optional, Description: The User's wage per hour.\nParameter: workDayHours, Type: number, Required?: Optional, Description: The User's hours per day they work.\nParameter: active, Type: Boolean, Required?: Optional, Description: The User's activation status.\nParameter: emailNotificationActive, Type: Boolean, Required?: Optional, Description: The User's email notification activation status.\nParameter: pushNotificationActive, Type: Boolean, Required?: Optional, Description: The User's push notification activation status."
      },
      "parameters": [
        {
          "name": "userID",
          "in": "path",
          "required": true,
          "description": "userID of the user you are removing.",
          "schema": {
            "type": "string"
          },
          "example": "{{userID}}"
        }
      ],
      "delete": {
        "operationId": "deleteUsersByUserID",
        "summary": "Delete User",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Users"
        ]
      }
    },
    "/v2/vendors/fields": {
      "get": {
        "operationId": "getVendorsFields",
        "summary": "Vendor Fields",
        "parameters": [
          {
            "name": "fields",
            "in": "query",
            "description": "This parameter is used to only get specific fields by ID. This parameter expects a comma delimited list of fieldIDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2"
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific field by name. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%pic%"
          },
          {
            "name": "vendors",
            "in": "query",
            "description": "This parameter is used to only get specific Vendors. This parameter expects a comma delimited list of Vendor IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get vendor fields for vendors that were last edited after the unix timestamp passed into the start parameter. For example, all Vendors that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1555105636
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get vendor fields for vendors that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1555105636
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what valueID you want to start receiving results at. e.g. passing 137 here will only get you vendor field values with a valueID greater than 137. Results are ordered by valueID ascending.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "value",
            "in": "query",
            "description": "This parameter is used to only get specific field by value. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "integer"
            },
            "example": 355
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "values",
            "in": "query",
            "description": "This parameter is used to get vendor fields by their valueID. This parameter expects a comma delimited list of Value IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2"
          }
        ],
        "responses": {
          "200": {
            "description": "Vendor Fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "fieldID": {
                        "type": "integer"
                      },
                      "vendorID": {
                        "type": "integer"
                      },
                      "fieldName": {
                        "type": "string"
                      },
                      "value": {
                        "type": "null"
                      },
                      "valueID": {
                        "type": "integer"
                      },
                      "fieldType": {
                        "type": "string"
                      },
                      "lastEdited": {
                        "type": "integer"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "files": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "fileName": {
                              "type": "string"
                            },
                            "link": {
                              "type": "string",
                              "format": "uri"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "fieldID": 1,
                    "vendorID": 1,
                    "fieldName": "pic",
                    "value": null,
                    "valueID": 1,
                    "fieldType": "Pictures",
                    "lastEdited": 1567139818,
                    "locationID": 330,
                    "files": [
                      {
                        "fileName": "41527325_10157931415518298_4759790604056002560_n.jpg",
                        "link": "https://content.limblecmms.com/upload-36/vendors/330/1/1/41527325_10157931415518298_4759790604056002560_n.jpg?Expires=1572459681&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jb250ZW50LmxpbWJsZWNtbXMuY29tL3VwbG9hZC0zNi92ZW5kb3JzLzMzMC8xLzEvNDE1MjczMjVfMTAxNTc5MzE0MTU1MTgyOThfNDc1OTc5MDYwNDA1NjAwMjU2MF9uLmpwZyIsIkNvbmRpdGlvbiI6eyJEYXRlTGVzc1RoYW4iOnsiQVdTOkVwb2NoVGltZSI6MTU3MjQ1OTY4MX19fV19&Signature=Iyd-KhXQvTp4sovnX~HMe4Iim~MhDdJlNb8B6nxgeiq1wmW-iOuS3lR2ZyFUHUu~02q3JQSvXvJZSeTUEkEdzt9V8oFnIPBb1n5tMgzK2SafvkOKZcOnGNQdYd3NW~EiKugA9xsMKVlfExyYbaGT6tKDiASUEj0NKwy5xjjN1DlniFzM0jW1M2X6F6--w0H2XbiKKfUJQzmgWHVM8nlk4vVik153NAGSjetwOSc5uAw1FJQ~PlaU92MbalE2d9F7cQonT9RHJmnf03lF9ww8vlMUHEfJ-PBHTJJeiAXgymggdQk60OKFQ3vf2CJJoDbr2Bi7an911UrNXs8KB1pfiw__&Key-Pair-Id=APKAIH5A42E3EPKJRHFQ"
                      }
                    ]
                  },
                  {
                    "fieldID": 2,
                    "vendorID": 1,
                    "fieldName": "testText",
                    "value": null,
                    "valueID": 2,
                    "fieldType": "Text",
                    "locationID": 330,
                    "files": [],
                    "lastEdited": 1555105636
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "This request gets detailed information about Vendor Fields such as contact information, contracts and any other custom set field.\n\nThis request will return an array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link.\n\n**Note:** this endpoint supports pagination. Please refer to the [**Pagination**](#pagination) section for more information."
      },
      "post": {
        "operationId": "postVendorsFields",
        "summary": "New Vendor Suggested Field",
        "responses": {
          "201": {
            "description": "New Vendor Suggested Field",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/vendors/fields/?fields=5"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "fieldID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "fieldID": "5"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "This request adds a new Field to the list of Suggested Fields that can later be attached to Vendors.\n\nParameter: locationID, Type: Int, Required?: Required, Description: The location ID of the Location to add the new Field to.\nParameter: name, Type: String, Required?: Required, Description: The name of the new Field. Some custom field names such as \"Vendor Name\" are not allowed and reserved for internal use. This will result in a 409 error.\nParameter: fieldType, Type: Int, Required?: Required, Description: The type of the new Field. You can choose from Text (1), Date (2), Pictures (3), Documents (4), Number (5), Currency (6), Dropdown (7).\n\nParameter: options, Type: Array of objects with a \"name\" property, Required?: Optional (only valid when fieldType is 7), Description: Initial list of options for a Dropdown field. Each option must have a \"name\" string."
      }
    },
    "/v2/vendors/fields/suggested": {
      "get": {
        "operationId": "getVendorsFieldsSuggested",
        "summary": "Vendor Suggested Fields",
        "parameters": [
          {
            "name": "fields",
            "in": "query",
            "description": "This parameter can be used to get a single Vendor Fields or a list of Vendor Fields in a comma-separated list.",
            "schema": {
              "type": "string"
            },
            "example": "1,2"
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific field by name. This parameter expects a string full name of a field or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%pic%"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what fieldID you want to start receiving results at. e.g. passing 137 here will only get you vendor fields with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Vendor Suggested Fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "fieldID": {
                        "type": "integer"
                      },
                      "fieldType": {
                        "type": "string"
                      },
                      "fieldName": {
                        "type": "string"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "options": {
                        "type": "array",
                        "description": "Present only when fieldType is \"Dropdown\". Contains the list of available options for the dropdown field.",
                        "items": {
                          "$ref": "#/components/schemas/DropdownOption"
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "fieldID": 1,
                    "fieldType": "Pictures",
                    "fieldName": "pic",
                    "locationID": 330
                  },
                  {
                    "fieldID": 2,
                    "fieldType": "Text",
                    "fieldName": "testText",
                    "locationID": 330
                  },
                  {
                    "fieldID": 3,
                    "fieldType": "Dropdown",
                    "fieldName": "Vendor Tier",
                    "locationID": 330,
                    "options": [
                      {
                        "name": "Preferred"
                      },
                      {
                        "name": "Standard"
                      }
                    ]
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "This request gets all possible fields a Vendor can pick from when deciding which fields it should have."
      }
    },
    "/v2/vendors/fields/{valueID}": {
      "patch": {
        "operationId": "patchVendorsFieldsByValueID",
        "summary": "Update Vendor Field Value",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "This request updates a Vendor's field value.\n\nParameter: value, Type: Depends on fieldType, Required?: Required, Description: The value that will be written to the field. \"value\" must correspond to the fieldType of the field. For example, if the field is a \"number\" fieldType, then \"value\" must be a number."
      },
      "parameters": [
        {
          "name": "valueID",
          "in": "path",
          "required": true,
          "description": "valueID of the field you are removing.",
          "schema": {
            "type": "integer"
          },
          "example": 182
        }
      ],
      "delete": {
        "operationId": "deleteVendorsFieldsByValueID",
        "summary": "Delete Vendor Field",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "This request deletes a custom field attached to a Vendor."
      }
    },
    "/v2/vendors/fields/{fieldID}/options": {
      "get": {
        "operationId": "getVendorsFieldOptions",
        "summary": "Get Vendor Dropdown Field Options",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "responses": {
          "200": {
            "description": "List of options for the dropdown field.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                },
                "example": {
                  "options": [
                    {
                      "name": "Preferred"
                    },
                    {
                      "name": "Standard"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "Returns the list of available options for a Dropdown custom field on vendors."
      },
      "post": {
        "operationId": "postVendorsFieldOptions",
        "summary": "Append Vendor Dropdown Field Option(s)",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "title": "Single option",
                    "type": "object",
                    "required": [
                      "name"
                    ],
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 255,
                        "description": "The name of the option to append."
                      }
                    }
                  },
                  {
                    "title": "Multiple options",
                    "type": "object",
                    "required": [
                      "options"
                    ],
                    "properties": {
                      "options": {
                        "type": "array",
                        "minItems": 1,
                        "items": {
                          "$ref": "#/components/schemas/DropdownOption"
                        },
                        "description": "List of options to append."
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Option(s) appended successfully. Returns the full updated options list. Existing options are preserved; only the new names are added.\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "Appends one or more options to a Dropdown custom field on vendors. Existing options are preserved. Returns 409 if any incoming name duplicates an existing option or another name in the same request (comparison is case-insensitive and trimmed). To replace the entire list, use PUT instead.\n"
      },
      "put": {
        "operationId": "putVendorsFieldOptions",
        "summary": "Replace Vendor Dropdown Field Options",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "options"
                ],
                "properties": {
                  "options": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/DropdownOption"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Options replaced successfully. The full new options list is returned.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "options": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/DropdownOption"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "Replaces the entire list of options for a Dropdown custom field on vendors. All existing options are discarded and replaced with the provided list. Returns 409 if the provided list contains duplicate names (case-insensitive). To append without replacing, use POST instead.\n"
      }
    },
    "/v2/vendors/fields/{fieldID}/options/{optionName}": {
      "delete": {
        "operationId": "deleteVendorsFieldOption",
        "summary": "Delete Vendor Dropdown Field Option",
        "parameters": [
          {
            "name": "fieldID",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "description": "The ID of the dropdown suggested field."
          },
          {
            "name": "optionName",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "The URL-encoded name of the option to delete."
          }
        ],
        "responses": {
          "204": {
            "description": "Option deleted successfully."
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "Removes a single option from a Dropdown custom field on vendors by name (URL-encoded). Returns 404 if the option does not exist."
      }
    },
    "/v2/vendors/{vendorID}/fields": {
      "put": {
        "operationId": "putVendorsByVendorIDFields",
        "summary": "Attach Field to Vendor",
        "responses": {
          "201": {
            "description": "Attach Field to Vendor",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "valueID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "valueID": "4"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Fields"
        ],
        "description": "This request attaches a Suggested Field to a Vendor."
      },
      "parameters": [
        {
          "name": "vendorID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1
        }
      ]
    },
    "/v2/vendors/{vendorID}/image": {
      "put": {
        "operationId": "putVendorsByVendorIDImage",
        "summary": "Add Vendor Image",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Images"
        ],
        "description": "This request adds the main image to a Vendor."
      },
      "parameters": [
        {
          "name": "vendorID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "example": "{{vendorID}}"
        }
      ],
      "delete": {
        "operationId": "deleteVendorsByVendorIDImage",
        "summary": "Delete Vendor Image",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Images"
        ],
        "description": "This request removes the main image from a Vendor."
      }
    },
    "/v2/vendors/logs/file/{fileID}": {
      "delete": {
        "operationId": "deleteVendorsLogsFileByFileID",
        "summary": "Delete Vendor Log File",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Logs",
          "Files"
        ],
        "description": "This requests deletes a file attached to a log."
      },
      "parameters": [
        {
          "name": "fileID",
          "in": "path",
          "required": true,
          "description": "The ID of the file attached to the log.",
          "schema": {
            "type": "integer"
          },
          "example": 7
        }
      ]
    },
    "/v2/vendors/{vendorID}/logs/{logID}/file": {
      "put": {
        "operationId": "putVendorsByVendorIDLogsByLogIDFile",
        "summary": "Add Vendor Log File",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Logs",
          "Files"
        ],
        "description": "This request adds files to a log.\n\nReturn data description\n\nfileID | The ID of the file attached to the log."
      },
      "parameters": [
        {
          "name": "vendorID",
          "in": "path",
          "required": true,
          "description": "The ID of the vendor the log belongs to.",
          "schema": {
            "type": "integer"
          },
          "example": 9
        },
        {
          "name": "logID",
          "in": "path",
          "required": true,
          "description": "The ID of the log to attach the file to.",
          "schema": {
            "type": "integer"
          },
          "example": 11
        }
      ]
    },
    "/v2/vendors/{vendorID}/logs": {
      "get": {
        "operationId": "getVendorsByVendorIDLogs",
        "summary": "Vendor Logs",
        "parameters": [
          {
            "name": "logs",
            "in": "query",
            "description": "This parameter is used to only get specific logs. This parameter accepts a comma delimited list of logIDs.",
            "schema": {
              "type": "string"
            },
            "example": "2,3"
          },
          {
            "name": "users",
            "in": "query",
            "description": "This parameter is used to only get logs created by specific users. This parameter accepts a comma delimited list of userIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 340
          },
          {
            "name": "logEntry",
            "in": "query",
            "description": "This is a parameter used to string search for manual log entry. This parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%test%"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get logs that were last edited after the unix timestamp passed into the start parameter. ",
            "schema": {
              "type": "integer"
            },
            "example": 1555085800
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get logs that were last edited before the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1555087900
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what ID you want to start receiving results at. ",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Vendor Logs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/LogEntry"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Logs"
        ],
        "description": "This request returns the manual log entries for a vendor.\n\nThis request returns logs created manually by users on vendors. Logs related to tasks with vendors will not be returned.\n\n**Note:** this endpoint supports pagination. Please refer to the [**Pagination**](#pagination) section for more information.\n\nReturn data description\n\nlogID | The unique logID of the log.\ndateCreated | The date the log was created as a UNIX timestamp.\nvendorD | The ID of the vendor the log belongs to.\nlogEntry | The log entry for the vendor.\nuserID | The ID of the user that created the log.\nlogFiles | An array of objects that have a fileID, fileName and a link that can used to download the files attached to the log. All links are only valid for 15 minutes, a new call will generate a new link."
      },
      "parameters": [
        {
          "name": "vendorID",
          "in": "path",
          "required": true,
          "description": "The ID of the vendor for which the log will be created.",
          "schema": {
            "type": "integer"
          },
          "example": 9
        }
      ],
      "post": {
        "operationId": "postVendorsByVendorIDLogs",
        "summary": "New Vendor Log",
        "responses": {
          "201": {
            "description": "New Vendor Log",
            "headers": {
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "1000"
              },
              "X-RateLimit-Minute-Limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "240"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "993"
              },
              "X-RateLimit-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1684346312"
              },
              "X-RateLimit-Minute-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "239"
              },
              "X-RateLimit-Minute-First-Call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1684346781"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "logID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "logID": 4354
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Logs"
        ],
        "description": "This creates a manual log entry for a vendor.\n\nuserID | Int | Required | The ID of the user creating the log.\nlogEntry | String | Required | Details of the log.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userID": {
                    "type": "integer"
                  },
                  "logEntry": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "userID": 342,
                "logEntry": "Creating a log"
              }
            }
          }
        }
      }
    },
    "/v2/vendors/logs/{logID}": {
      "patch": {
        "operationId": "patchVendorsLogsByLogID",
        "summary": "Update Vendor Log",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Logs"
        ],
        "description": "This request updates a manual log entry for a vendor.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "logEntry": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "logEntry": "Changing log"
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "logID",
          "in": "path",
          "required": true,
          "description": "The ID of the log to be deleted.",
          "schema": {
            "type": "integer"
          },
          "example": 10
        }
      ],
      "delete": {
        "operationId": "deleteVendorsLogsByLogID",
        "summary": "Delete Vendor Log",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors",
          "Logs"
        ],
        "description": "This request deleted a manual log entry for a vendor."
      }
    },
    "/v2/vendors": {
      "get": {
        "operationId": "getVendors",
        "summary": "Vendors",
        "parameters": [
          {
            "name": "vendors",
            "in": "query",
            "description": "This parameter is used to only get specific Vendors. This parameter expects a comma delimited list of Vendor IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 9
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get Vendors at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 163
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific vendor by name. This parameter expects a string full name of a vendor or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%test%"
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Vendors that were last edited after the unix timestamp passed into the start parameter. For example, all Vendors that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1560233040
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Vendors that were last edited *before* the unix timestamp passed into the end parameter.",
            "schema": {
              "type": "integer"
            },
            "example": 1613665140
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what vendorID you want to start receiving results at. e.g. passing 137 here will only get you vendors with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "Vendors",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Vendor"
                  }
                },
                "example": [
                  {
                    "meta": {
                      "fields": "/v2/vendors/fields/?vendors=1"
                    },
                    "vendorID": 1,
                    "name": "bryan's IT shop",
                    "email": "bob@limblecmms.com",
                    "phone": "801-123-1234",
                    "contact": "Bryan Christiansen",
                    "address": "123 Test Rd",
                    "locationID": 330,
                    "startedOn": 1555085498,
                    "lastEdited": 1566925530,
                    "image": [
                      {
                        "fileName": "41372537_10157931415578298_3719969727385174016_n.jpg",
                        "link": "https://content.limblecmms.com/upload-36/vendors/330/1/41372537_10157931415578298_3719969727385174016_n.jpg?Expires=1572386698&Policy=eyJTdGF0ZW1lbnQiOlt7IlJlc291cmNlIjoiaHR0cHM6Ly9jb250ZW50LmxpbWJsZWNtbXMuY29tL3VwbG9hZC0zNi92ZW5kb3JzLzMzMC8xLzQxMzcyNTM3XzEwMTU3OTMxNDE1NTc4Mjk4XzM3MTk5Njk3MjczODUxNzQwMTZfbi5qcGciLCJDb25kaXRpb24iOnsiRGF0ZUxlc3NUaGFuIjp7IkFXUzpFcG9jaFRpbWUiOjE1NzIzODY2OTh9fX1dfQ__&Signature=Os2lzvCLIJOteYIgc-NgodzrLdjNAYdncy0e~kKtv0qwvZJJr1feiDdJGMt~CIgdCHpLwqlajpK2-GpZIv6SDkVJ5Cl2MoOld64Uy6M1K~wLe1U75aCLqyRRVi~PzpWUpJxF2cf0OwMdYXJfeYhGl74PsvJB1AjeNsxV8aM4hDzILKeJpQVwlsRoXydfyCKe1Ese43kHtEy~Mpb4xZNBeOUaC2d6yR8MigtGFSgwPA1A9mKy8WknmjD7YkLaIl9MaMV4tj2QTDDWilbfps0WSYCzxqqtORoGfLV65kGmYXvOAEmVW3XX~Bkc9xsma~p2V8N0ngqg~ngLF8WEp8ooPw__&Key-Pair-Id=APKAIH5A42E3EPKJRHFQ"
                      }
                    ]
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors"
        ],
        "description": "This request gets information such as VendorIDs, Vendor Names, etc.\n\nThis call returns a \"meta\" object containing URLs that can be used to get data related to a vendor.\n\nThis call will also return an image array of objects that have a file name and a link you can use to download that image. All links are only valid for 15 minutes, a new call will generate a new link.\n\n**Note:** this endpoint supports pagination. Please refer to the [**Pagination**](#pagination) section for more information."
      },
      "post": {
        "operationId": "postVendors",
        "summary": "New Vendor",
        "responses": {
          "201": {
            "description": "New Vendor",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/vendors/?vendors=10"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "vendorID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "vendorID": "10"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors"
        ],
        "description": "This request creates a new Vendor.\n\nname | String | Required | The name of the Vendor.\nlocationID | string | Required | The locationID of the Location the Vendor will be at.\nemail | string | Optional | The Vendor's email address.\ncontact | string | Optional | The Vendor's primary contact.\nphone | string | Optional | The Vendor's phone number.\naddress | string | Optional | The Vendor's address."
      }
    },
    "/v2/vendors/{vendorID}": {
      "patch": {
        "operationId": "patchVendorsByVendorID",
        "summary": "Update Vendor",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors"
        ],
        "description": "This Request updates a Vendor's name, phone, email, contact, address, etc.\n\nname | String | Optional | The name of the Vendor.\nlocationID | string | Required | The locationID of the Location the Vendor will be at.\nemail | string | Optional | The Vendor's email address.\ncontact | string | Optional | The Vendor's primary contact.\naddress | string | Optional | The Vendor's address.\nphone | string | Optional | The Vendor's phone number."
      },
      "parameters": [
        {
          "name": "vendorID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "string"
          },
          "example": "{{vendorID}}"
        }
      ],
      "delete": {
        "operationId": "deleteVendorsByVendorID",
        "summary": "Delete Vendor",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Vendors"
        ],
        "description": "This request deletes a Vendor."
      }
    },
    "/v2/roles": {
      "get": {
        "operationId": "getRoles",
        "summary": "Get Roles",
        "parameters": [
          {
            "name": "roles",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1032
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "%view%"
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Get Roles",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "roleID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "roleID": 321,
                    "name": "Manager"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Roles"
        ],
        "description": "This request returns a list of Roles."
      },
      "post": {
        "operationId": "postRoles",
        "summary": "Create Role",
        "responses": {
          "201": {
            "description": "Create Role",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/roles/?roles=1436"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "roleID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "roleID": 1436
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Roles"
        ],
        "description": "This request creates a new Role. Roles are used for access management in Limble. Once a Role is created you can assign permissions to that Role via the web application and then assign Users to that Role to control what that User can do in Limble.\n\nParameter: name, Type: String, Required?: Required, Description: The name of the role."
      }
    },
    "/v2/roles/{roleID}": {
      "patch": {
        "operationId": "patchRolesByRoleID",
        "summary": "Update Role",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Roles"
        ],
        "description": "This request updates a Role's name.\n\nParameter: name, Type: String, Required?: Required, Description: The name of the role."
      },
      "parameters": [
        {
          "name": "roleID",
          "in": "path",
          "required": true,
          "description": "The roleID of the role you are deleting",
          "schema": {
            "type": "string"
          },
          "example": "{{roleID}}"
        }
      ],
      "delete": {
        "operationId": "deleteRolesByRoleID",
        "summary": "Delete Role",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Roles"
        ],
        "description": "This Request deletes a Role.  This will also remove the Role from any User it is assigned to."
      }
    },
    "/v2/teams": {
      "get": {
        "operationId": "getTeams",
        "summary": "Get Teams",
        "parameters": [
          {
            "name": "teams",
            "in": "query",
            "description": "This parameter expects a comma-separated list of teamIDs to filter teams by.",
            "schema": {
              "type": "string"
            },
            "example": "1778, 1771"
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific teams by name. This parameter expects a string full name of a team or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%Lawn%"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what teamID you want to start receiving results at. e.g. passing 137 here will only get you tasks with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "automaticallyCreated",
            "in": "query",
            "description": "This parameter is used to only get specific teams by if they were automatically created by Limble or not. This parameter expects a bool true or false. Teams can get dynamically created if multiple users are assigned to the same task, for example.",
            "schema": {
              "type": "boolean"
            },
            "example": false
          },
          {
            "name": "includeRoles",
            "in": "query",
            "description": "This parameter is used to determine whether role-based teams (Manager, Technician, etc) are included in the response.",
            "schema": {
              "type": "boolean"
            },
            "example": false
          }
        ],
        "responses": {
          "200": {
            "description": "Get Teams",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "teamID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "automaticallyCreated": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "teamID": 438,
                    "name": "Senior Maintenance",
                    "locationID": 73,
                    "automaticallyCreated": 0
                  },
                  {
                    "teamID": 1146,
                    "name": "Junior Maintenance",
                    "locationID": 361,
                    "automaticallyCreated": 0
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Teams"
        ],
        "description": "This request returns a list of Teams."
      },
      "post": {
        "operationId": "postTeams",
        "summary": "Create Team",
        "responses": {
          "201": {
            "description": "Create Team",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/teams/?teams=2038"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "teamID": {
                      "type": "string",
                      "format": "utc-millisec"
                    }
                  }
                },
                "example": {
                  "teamID": "2038"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Teams"
        ],
        "description": "This request creates a new Team.\n\nParameter: name, Type: String, Required?: Required, Description: The name of the Team.\nParameter: locationID, Type: string, Required?: Required, Description: The locationID of the Location the Team will be available at."
      }
    },
    "/v2/teams/{teamID}": {
      "patch": {
        "operationId": "patchTeamsByTeamID",
        "summary": "Update Team",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Teams"
        ],
        "description": "Update a team name.\n\nParameter: name, Type: String, Required?: Required, Description: The name of the team."
      },
      "parameters": [
        {
          "name": "teamID",
          "in": "path",
          "required": true,
          "description": "The teamID of the team you are deleting.",
          "schema": {
            "type": "string"
          },
          "example": "{{teamID}}"
        }
      ],
      "delete": {
        "operationId": "deleteTeamsByTeamID",
        "summary": "Delete Team",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Teams"
        ],
        "description": "This request deletes a Team. This will also remove the Team from any User it is assigned to."
      }
    },
    "/v2/po/items": {
      "get": {
        "operationId": "getPoItems",
        "summary": "Get Purchase Order Items",
        "parameters": [
          {
            "name": "pos",
            "in": "query",
            "description": "This parameter is used to only get specific POs. This parameter expects a comma delimited list of PO IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3"
          },
          {
            "name": "items",
            "in": "query",
            "description": "This parameter is used to only get specific PO Items by ID. This parameter expects a comma delimited list of poItem IDs.",
            "schema": {
              "type": "string"
            },
            "example": "45,8998,3434"
          },
          {
            "name": "numbers",
            "in": "query",
            "description": "This parameter is used to only get specific POs by Number. This parameter expects a comma delimited list of PO Numbers.",
            "schema": {
              "type": "string"
            },
            "example": "1,2"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what vendorID you want to start receiving results at. e.g. passing 137 here will only get you vendors with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 112
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "lastEditedStart",
            "in": "query",
            "description": "This parameter is used to only get PO items that were last edited after the unix timestamp passed into the start parameter. For example, all PO items that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1518559856
          },
          {
            "name": "lastEditedEnd",
            "in": "query",
            "description": "This parameter is used to only get POs items that were last edited *before* the unix timestamp passed in.",
            "schema": {
              "type": "integer"
            },
            "example": 1518559856
          }
        ],
        "responses": {
          "200": {
            "description": "Get Purchase Order Items",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/POItem"
                  }
                },
                "example": [
                  {
                    "poID": 43,
                    "poItemID": 39,
                    "itemType": 1,
                    "name": null,
                    "description": null,
                    "glID": 0,
                    "partID": 3118,
                    "taskID": 0,
                    "poNumber": 29,
                    "qty": 1,
                    "rate": 15500,
                    "tax": 39000,
                    "discount": 11682,
                    "shipping": 9000,
                    "qtyReceived": 0,
                    "orderUnitAbbreviation": null,
                    "lastEdited": 1613497787,
                    "meta": {
                      "po": "/v2/po?pos=43"
                    }
                  },
                  {
                    "poID": 44,
                    "poItemID": 40,
                    "itemType": 1,
                    "name": null,
                    "description": null,
                    "glID": 0,
                    "partID": 3119,
                    "taskID": 0,
                    "poNumber": 30,
                    "qty": 10,
                    "rate": 72000,
                    "tax": 65500,
                    "discount": 52371,
                    "shipping": 38500,
                    "qtyReceived": 0,
                    "orderUnitAbbreviation": null,
                    "lastEdited": 1613497787,
                    "meta": {
                      "po": "/v2/po?pos=44"
                    }
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Items"
        ],
        "description": "This request gets information associated with PO items. Every line item on a PO is an item returned by this call.\n\nReturn data description\n\npoID | The unique ID of the purchase order associated to this item.\npoItemID | The unqiue ID of this Purchase Order Item\nitemType | Which type (Part, Service, or Other) this item is.\nname | The name of the item.\ndescription | A more detailed description of the item.\nglID | The unique ID of the GL associated to this item.\npartID | The unique ID of the part associated to this item.\ntaskID | The unique ID of the task associated to this item.\npoNumber | The user-set Purchase Order number.\nqty | The quantity purchased.\nrate | The billing rate for the item on the Purchase Order.\ntax | The tax percent rate for the item on the Purchase Order.\ndiscount | The discount percent rate for the item on the Purchase Order.\nshipping | The shipping rate for the item on the Purchase Order.\nqtyReceived | A number representing the total quantity that has been marked as \"received\" for this item.\nlastEdited | Last time this PO item was edited, this field outputs a UNIX timestamp.\norderUnitAbbreviation | The abbreviation for the unit of measure in which the PO item was ordered. (NULL for items not assigned to a unit of measure)"
      }
    },
    "/v2/po/{poID}/items": {
      "post": {
        "operationId": "postPoByPoIDItems",
        "summary": "New Purchase Order Item",
        "responses": {
          "201": {
            "description": "New Purchase Order Item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "itemID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "itemID": 1
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Items"
        ],
        "description": "This request creates a new Purchase Order Item.\n\nitemType | Int | Required | A number describing what type of PO Item this is. Valid values are: 1 (Part), 2 (Service), 4 (Other). If itemType is 1, name and taskID cannot be present and partID is required. If itemType is 2 or 4, name is required and partID cannot be present. If itemType is 2, a checklistID is required.\nname | String | Optional | A short line-item title for this PO Item.\ndescription | String | Optional | A more detailed description for this PO Item.\nglID | Int | Optional | The ID of the General Ledger that this PO Item will belong to.\ntaskID | Int | Optional | The ID of the Task that this PO Item will belong to.\nassetID | Int | Optional | The ID of the Asset that this PO Item will belong to.\npartID | Int | Optional | The ID of the Part that this PO Item will belong to.\nquantity | Int | Optional | A number for how many items are represented in this line. If not provided, the minimum and default values are 1.\nrate | Float | Optional | A decimal (precision 4) representing the cost of one of the item(s). Default is 0.0000\ntax | Float | Optional | A decimal (precision 4) representing the amount of tax on the item(s) as a percent. Default is 0.0000\ndiscount | Float | Optional | A decimal (precision 4) representing the discounted cost on the item(s) as a percent. Default is 0.0000\nshipping | Float | Optional | A decimal (precision 4) representing the cost of shipping for the item(s). Default is 0.0000",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "itemType": {
                    "type": "integer"
                  },
                  "glID": {
                    "type": "integer"
                  },
                  "assetID": {
                    "type": "integer"
                  },
                  "partID": {
                    "type": "integer"
                  },
                  "quantity": {
                    "type": "integer"
                  },
                  "rate": {
                    "type": "number"
                  },
                  "tax": {
                    "type": "integer"
                  },
                  "discount": {
                    "type": "integer"
                  },
                  "shipping": {
                    "type": "number"
                  }
                }
              },
              "example": {
                "itemType": 1,
                "glID": 2,
                "assetID": 3,
                "partID": 4,
                "quantity": 1,
                "rate": 12.99,
                "tax": 10,
                "discount": 3,
                "shipping": 1.2345
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "poID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1
        }
      ]
    },
    "/v2/po/{poID}/items/{poItemID}": {
      "patch": {
        "operationId": "patchPoByPoIDItemsByPoItemID",
        "summary": "Update Purchase Order Item",
        "responses": {
          "200": {
            "description": "Update Purchase Order Item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Items"
        ],
        "description": "This request updates a Purchase Order Item. Considering the validation for this route is non-trivial -- keep in mind that before this update takes place, we validate the resulting PO Item, so the itemType must be valid with any existing or updated properties. For example, if you have a PO Item of itemType 1 (Part) and attempt to send a PATCH that only provides a checklistID, you will get an error back saying that this is an invalid combination.\n\nTo remove an associated ID, pass in the value 0.\n\nitemType | Int | Optional | A number describing what type of PO Item this is. Valid values are: 1 (Part), 2 (Service), 4 (Other). If itemType is 1, name and taskID cannot be present and partID is required. If itemType is 2 or 4, name is required and partID cannot be present. If itemType is 2, a checklistID is required.\nname | String | Optional | A short line-item title for this PO Item.\ndescription | String | Optional | A more detailed description for this PO Item.\nglID | Int | Optional | The ID of the General Ledger that this PO Item will belong to.\ntaskID | Int | Optional | The ID of the Task that this PO Item will belong to.\nassetID | Int | Optional | The ID of the Asset that this PO Item will belong to.\npartID | Int | Optional | The ID of the Part that this PO Item will belong to.\nquantity | Int | Optional | A number for how many items are represented in this line. If not provided, the minimum and default values are 1.\nrate | Float | Optional | A decimal (precision 4) representing the cost of one of the item(s). Default is 0.0000\ntax | Float | Optional | A decimal (precision 4) representing the amount of tax on the item(s) as a percent. Default is 0.0000\ndiscount | Float | Optional | A decimal (precision 4) representing the discounted cost on the item(s) as a percent. Default is 0.0000\nshipping | Float | Optional | A decimal (precision 4) representing the cost of shipping for the item(s). Default is 0.0000",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "itemType": {
                    "type": "integer"
                  },
                  "glID": {
                    "type": "integer"
                  },
                  "assetID": {
                    "type": "integer"
                  },
                  "partID": {
                    "type": "integer"
                  },
                  "quantity": {
                    "type": "integer"
                  },
                  "rate": {
                    "type": "number"
                  },
                  "tax": {
                    "type": "number"
                  },
                  "discount": {
                    "type": "integer"
                  },
                  "shipping": {
                    "type": "number"
                  }
                }
              },
              "example": {
                "itemType": 1,
                "glID": 0,
                "assetID": 0,
                "partID": 4,
                "quantity": 5,
                "rate": 3.5,
                "tax": 7.25,
                "discount": 0,
                "shipping": 24.99
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "poID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1
        },
        {
          "name": "poItemID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1
        }
      ],
      "delete": {
        "operationId": "deletePoByPoIDItemsByPoItemID",
        "summary": "Delete PO Item",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Items"
        ],
        "description": "This request deletes a PO Item, which will also remove any relationships between the PO Item, Parts, and Tasks, and will clean up any history of transactions on this PO Item."
      },
      "put": {
        "operationId": "putPoByPoIDItemsByPoItemID",
        "summary": "Receive PO Item",
        "responses": {
          "200": {
            "description": "Receive PO Item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transactionID": {
                      "type": "integer"
                    },
                    "prID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "transactionID": 1,
                  "prID": 1
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Items"
        ],
        "description": "This request marks a quantity of a PO item as having been received and generates a bill for the receipt of the item.\n\nParameter: quantity, Type: Int, Required?: Required, Description: A positive number representing the received number of items. The sum of all receipts cannot be greater than the total quantity on the PO item., For example: if a PO item has a quantity of 5, then we use this request to receive 3, that will mark 3 of the PO item as received and generate a bill for that receipt of 3 PO items. If we run the same request again to receive another 3, the total would be 6 and the request would be rejected with an error.\n\nReturn data description\n\nProperty: transactionID, Description: The unique ID of the transaction created by this request.\nProperty: prID, Description: The unique ID of the PR (Bill) created by this request.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "quantity": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "quantity": 100
              }
            }
          }
        }
      }
    },
    "/v2/po/{poID}/comments": {
      "get": {
        "operationId": "getPoByPoIDComments",
        "summary": "PO Comments",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what commentID you want to start receiving results at. e.g. passing 137 here will only get you comments with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "PO Comments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "commentID": {
                        "type": "integer"
                      },
                      "comment": {
                        "type": "string"
                      },
                      "timestamp": {
                        "type": "integer"
                      },
                      "userID": {
                        "type": "integer"
                      },
                      "commentFiles": {
                        "type": "array"
                      },
                      "commentEmailAddress": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "commentID": 2,
                    "comment": "PO Started - Automatically generated",
                    "timestamp": 1565902642,
                    "userID": 341,
                    "commentFiles": [],
                    "commentEmailAddress": ""
                  },
                  {
                    "commentID": 23,
                    "comment": "1 QR New Part were received",
                    "timestamp": 1607467636,
                    "userID": 341,
                    "commentFiles": [],
                    "commentEmailAddress": ""
                  },
                  {
                    "commentID": 24,
                    "comment": "2 QR New Part were received",
                    "timestamp": 1608749750,
                    "userID": 341,
                    "commentFiles": [],
                    "commentEmailAddress": ""
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Comments"
        ],
        "description": "This request gets all PO Comments associated with a PO.\n\nReturn data description\n\ncommentID | This is the commentID of comment.\ncomment | The text comment that was entered by the user.\ntimestamp | The date this comment was created. This is a unix timestamp.\nuserID | The ID of the user that made the comment.\ncommentEmailAddress | The email address of the external user that made this comment. This is only populated if the comment was made by an external user via the comment reply system.\ncommentFiles | Array containing fileName and link properties."
      },
      "parameters": [
        {
          "name": "poID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1234
        }
      ],
      "post": {
        "operationId": "postPoByPoIDComments",
        "summary": "Create PO Comment",
        "responses": {
          "201": {
            "description": "201 Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "commentID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "commentID": 56997
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Comments"
        ],
        "description": "Adds a comment to the specified PO.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| poID | path | integer | yes |  | Purchase Order identifier |\n| comment | body | string | yes |  | Comment text |\n| showExternalUsers | body | boolean | no | true | Visible to external users |\n\nResponses:\n- 201 Created: Returns commentID."
      }
    },
    "/v2/po/{poID}/comments/{commentID}/file": {
      "put": {
        "operationId": "putPoByPoIDCommentsByCommentIDFile",
        "summary": "Upload PO Comment File",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Comments"
        ],
        "description": "Uploads a file to a PO comment.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| poID | path | integer | yes |  | Purchase Order identifier |\n| commentID | path | integer | yes |  | Comment identifier |\n| file | form-data | file | yes |  | File to upload (max 50MB). Types: PDF, PNG, JPEG, GIF, TIFF, SVG, DOC, DOCX, XLS, XLSX, ZIP, RAR, RFC822, octet-stream |"
      },
      "parameters": [
        {
          "name": "poID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1234
        },
        {
          "name": "commentID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 5678
        }
      ],
      "delete": {
        "operationId": "deletePoByPoIDCommentsByCommentIDFile",
        "summary": "Delete PO Comment File",
        "parameters": [
          {
            "name": "filename",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "invoice.pdf"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Comments"
        ],
        "description": "Deletes a file from a PO comment.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| poID | path | integer | yes |  | Purchase Order identifier |\n| commentID | path | integer | yes |  | Comment identifier |\n| filename | query | string | yes |  | Exact filename to remove |\n\nResponses:\n- 200 OK: Deleted.\n- 404 Not Found: File not found."
      }
    },
    "/v2/po/{poID}/comments/{commentID}": {
      "delete": {
        "operationId": "deletePoByPoIDCommentsByCommentID",
        "summary": "Delete PO Comment",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "Comments"
        ],
        "description": "Deletes a PO comment.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| poID | path | integer | yes |  | Purchase Order identifier |\n| commentID | path | integer | yes |  | Comment identifier |\n\nResponses:\n- 200 OK: Deleted.\n- 404 Not Found: Comment not found."
      },
      "parameters": [
        {
          "name": "poID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1
        },
        {
          "name": "commentID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 5678
        }
      ]
    },
    "/v2/po/{poID}/state": {
      "patch": {
        "operationId": "patchPoByPoIDState",
        "summary": "Change PO State",
        "responses": {
          "200": {
            "description": "200 OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    },
                    "message": {
                      "type": "string"
                    },
                    "currentState": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "success": true,
                  "message": "State changed",
                  "currentState": "ready_to_receive"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/InvalidStateTransition"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "State"
        ],
        "description": "Updates the state of the specified PO. \n\nImportant Note: Currently POs can only move forward one state per state change request.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- | --- |\n| poID | path | integer | yes | | Purchase Order identifier |\n| newState | body | string | yes | | All PO states: 0 (setup), 1–96 (custom), 97 (ready_to_receive), 98 (partially_received), 99 (fully_received), 100 (closed), 101 (disapproved). API accepts numbers, standard names, or custom_step_N |\n| reason | body | string | no | | Optional note (max 500 chars) |\n\nResponses:\n\n- 200 OK: State changed.\n\n- 400 Bad Request: Invalid transition or failed validation.\n\n- 404 Not Found: PO not found.\n\nResponse data:\n\nsuccess | Boolean, if this operation was successful\nstate | JSON object describing current state.\npreviousState | JSON object describing previous state.\nvalidNextStates | JSON object with a list of possible next states."
      },
      "parameters": [
        {
          "name": "poID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 31939
        }
      ]
    },
    "/v2/po/{poID}/state/transitions": {
      "get": {
        "operationId": "getPoByPoIDStateTransitions",
        "summary": "Get PO State Transitions",
        "responses": {
          "200": {
            "description": "200 OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "currentState": {
                      "type": "object",
                      "properties": {
                        "number": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        },
                        "label": {
                          "type": "string"
                        }
                      }
                    },
                    "validNextStates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "number": {
                            "type": "integer"
                          },
                          "name": {
                            "type": "string"
                          },
                          "label": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "requirements": {
                      "type": "object",
                      "properties": {
                        "ready_to_receive": {
                          "type": "object",
                          "properties": {
                            "vendorRequired": {
                              "type": "boolean"
                            }
                          }
                        },
                        "disapproved": {
                          "type": "object"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "currentState": {
                    "number": 0,
                    "name": "setup",
                    "label": "Setup"
                  },
                  "validNextStates": [
                    {
                      "number": 97,
                      "name": "ready_to_receive",
                      "label": "Ready to Receive"
                    },
                    {
                      "number": 101,
                      "name": "disapproved",
                      "label": "Disapproved"
                    }
                  ],
                  "requirements": {
                    "ready_to_receive": {
                      "vendorRequired": true
                    },
                    "disapproved": {}
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders",
          "State"
        ],
        "description": "Returns the list of valid next states for the specified PO.\n\nParameters:\n\n| Parameter | Type | Required | Default | Description |\n| --- | --- | --- | --- | --- |\n| poID | integer | yes |  | Purchase Order identifier |\n\nReturn data:  \n  \nArray of JSON objects listing possible next state transitions for the selected PO."
      },
      "parameters": [
        {
          "name": "poID",
          "in": "path",
          "required": true,
          "description": "Purchase Order identifier",
          "schema": {
            "type": "integer"
          },
          "example": 31939
        }
      ]
    },
    "/v2/po": {
      "get": {
        "operationId": "getPo",
        "summary": "Get Purchase Orders",
        "parameters": [
          {
            "name": "pos",
            "in": "query",
            "description": "This parameter is used to only get specific POs. This parameter expects a comma delimited list of PO IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "vendors",
            "in": "query",
            "description": "This parameter is used to only get specific Vendors. This parameter expects a comma delimited list of Vendor IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 9
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get POs at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 73
          },
          {
            "name": "numbers",
            "in": "query",
            "description": "This parameter is used to only get specific POs by Number. This parameter expects a comma delimited list of PO Numbers.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what poID you want to start receiving results at. e.g. passing 137 here will only get you PO with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "lastEditedStart",
            "in": "query",
            "description": "This parameter is used to only get POs that were last edited after the unix timestamp passed into the start parameter. For example, all POs that were last edited after April 18th, 2018.",
            "schema": {
              "type": "integer"
            },
            "example": 1629737835
          },
          {
            "name": "lastEditedEnd",
            "in": "query",
            "description": "This parameter is used to only get POs that were last edited *before* the unix timestamp passed in.",
            "schema": {
              "type": "integer"
            },
            "example": 1630121871
          },
          {
            "name": "status",
            "in": "query",
            "description": "This parameter is used to only get POs for a specific group of status.",
            "schema": {
              "type": "string"
            },
            "example": "97,99"
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 3
          }
        ],
        "responses": {
          "200": {
            "description": "Get Purchase Orders",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/PurchaseOrder"
                  }
                },
                "example": [
                  {
                    "poID": 1,
                    "taskID": 16,
                    "budgetID": 1,
                    "poNumber": 1,
                    "vendorID": 9,
                    "locationID": 163,
                    "userIDStarted": 340,
                    "userID": 341,
                    "teamID": 0,
                    "requestedByUserID": 0,
                    "date": 1565902331,
                    "expectedDate": null,
                    "notesToVendor": "",
                    "billTo": null,
                    "shipTo": null,
                    "status": 99,
                    "customField1": null,
                    "customField2": null,
                    "customField3": null,
                    "customField4": null,
                    "customField5": null,
                    "customField6": null,
                    "lastEdited": 1629737835,
                    "poPrefix": null,
                    "meta": {
                      "items": "/v2/po/items?pos=1",
                      "state": "/v2/po/1/state",
                      "stateTransitions": "/v2/po/1/state/transitions",
                      "budget": "/v2/po/budgets?budgets=1",
                      "budgetSteps": "/v2/budgets/steps?budgets=1"
                    },
                    "stateDetails": {
                      "current": {
                        "number": 99,
                        "name": "fully_received",
                        "label": "Fully Received",
                        "canModify": false
                      },
                      "transitions": {
                        "available": [
                          {
                            "state": 100,
                            "name": "closed",
                            "label": "Closed"
                          }
                        ]
                      }
                    },
                    "state": 99
                  },
                  {
                    "poID": 4,
                    "budgetID": 1,
                    "poNumber": 4,
                    "vendorID": 9,
                    "locationID": 163,
                    "userIDStarted": 340,
                    "userID": 656,
                    "teamID": 0,
                    "requestedByUserID": 0,
                    "date": 1565903115,
                    "expectedDate": null,
                    "notesToVendor": "",
                    "billTo": null,
                    "shipTo": null,
                    "status": 99,
                    "customField1": null,
                    "customField2": null,
                    "customField3": null,
                    "customField4": null,
                    "customField5": null,
                    "customField6": null,
                    "lastEdited": 1743190786,
                    "poPrefix": null,
                    "meta": {
                      "items": "/v2/po/items?pos=4",
                      "state": "/v2/po/4/state",
                      "stateTransitions": "/v2/po/4/state/transitions",
                      "budget": "/v2/po/budgets?budgets=1",
                      "budgetSteps": "/v2/budgets/steps?budgets=1"
                    },
                    "stateDetails": {
                      "current": {
                        "number": 99,
                        "name": "fully_received",
                        "label": "Fully Received",
                        "canModify": false
                      },
                      "transitions": {
                        "available": [
                          {
                            "state": 100,
                            "name": "closed",
                            "label": "Closed"
                          }
                        ]
                      }
                    },
                    "state": 99
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders"
        ],
        "description": "meta | useful links relating to this Purchase order\npoID | The unique ID of the Purchase Order.\npoNumber | The user-set Purchase Order number.\nbudgetID | The unique ID of the budget associated with this Purchase Order.\nvendorID | The unique ID of the vendor associated with this Purchase Order.\nlocationID | The unique ID of the location associated with this Purchase Order.\nuserIDStarted | The unique ID of the user that started this Purchase Order.\nuserID | The unique ID of the user this Purchase Order is currently assigned to.\nteamID | The unique ID of the team the user of this Purchase Order is currently assigned to.\nrequestedByUserID | The userID of the user that request this Purchase Order. A value of 0 means this PO wasn't requested, but was manually started by the userIDStarted.\ndate | The date this PO was started as a UNIX timestamp, or the date the user inputted for the Purchase Order.\nexpectedDate | The date this PO is expected as a UNIX timestamp to receive items.\nbillTo | The address that should receive the bill for the PO.\nshipTo | The address the PO's items should be delivered to.\nnotesToVendor | Any notes sent to the vendor, possibly containing handling, packaging, or delivery instructions.\ncustomField1 | PO custom field, the customer chooses which custom fields are available on all POs.\ncustomField2 | PO custom field, the customer chooses which custom fields are available on all POs.\ncustomField3 | PO custom field, the customer chooses which custom fields are available on all POs.\ncustomField4 | PO custom field, the customer chooses which custom fields are available on all POs.\ncustomField5 | PO custom field, the customer chooses which custom fields are available on all POs.\ncustomField6 | PO custom field, the customer chooses which custom fields are available on all POs.\npoPrefix | If a PO prefix is configured, it will show up here.\nlastEdited | Last time this PO was edited as a UNIX timestamp.\nstatus | This is the current status of a PO. Status of PO can be as follows:, 0: the PO has only been setup. (Status: Setup), 1-97: these are custom statuses based on the budget steps. Refer to \"budgetSteps\" in meta. (Status : {Name of the budgetStep it is on} ), 97: the PO is in the ready to receive step. This means items can be received for this PO. (Status: Ready to Receive), 98 all budget steps have been completed, but not all items on the PO have been received. This means only some items or partial qty of items have been received. (Status: Partially Received), 99: the PO is completed. This means all the items and their full qty on the PO have been received but not been paid for ( i.e. all the bills generated for this PO have not been marked as paid yet.) (Status: Fully Received - Pending Payment), 100: the PO is closed. This means all the items on the PO have been received and have been paid for. (i.e. all the bills for this PO have been marked as paid.) (Status: Closed)\nstateDetails | JSON object containing details about the PO's current state, and available state transitions.\npoNumberDisplay | Formatted display string with leading zeros and prefix. This is the PO Number the UI will display."
      },
      "post": {
        "operationId": "postPo",
        "summary": "New Purchase Order",
        "responses": {
          "201": {
            "description": "New Purchase Order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "poID": {
                      "type": "integer"
                    },
                    "meta": {
                      "type": "object",
                      "properties": {
                        "items": {
                          "type": "string"
                        },
                        "state": {
                          "type": "string"
                        },
                        "stateTransitions": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "example": {
                  "poID": 1234,
                  "meta": {
                    "items": "/v2/po/items?pos=31939",
                    "state": "/v2/po/31939/state",
                    "stateTransitions": "/v2/po/31939/state/transitions"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders"
        ],
        "description": "This request creates a new Purchase Order.\n\nParameter: locationID, Type: Int, Required?: Required, Description: The ID of the location this PO will be created for.\nParameter: vendorID, Type: Int, Required?: Required, Description: The ID of the vendor that this PO will be associated with.\nParameter: userID, Type: Int, Required?: Required, Description: The ID of the user that this PO will be assigned to.\nParameter: taskID, Type: Int, Required?: Optional, Description: The ID of the task that this PO will be associated with.\nParameter: budgetID, Type: Int, Required?: Optional, Description: The ID of the budget that this PO will be associated with. If not provided, this will be the location's default budget.\nParameter: date, Type: Int, Required?: Optional, Description: The start time of the PO -- this can be in the past or the future and will still show up in the UI. Must be a unix timestamp. If not provided, this will default to the current time.\nParameter: expectedDate, Type: Int, Required?: Optional, Description: The expected delivery date of this PO. Must be a unix timestamp.\nParameter: requestDescription, Type: String, Required?: Optional, Description: A description of the \"request\" for this PO.\nParameter: customField1, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField2, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField3, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField4, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField5, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField6, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "locationID": {
                    "type": "integer"
                  },
                  "vendorID": {
                    "type": "integer"
                  },
                  "userID": {
                    "type": "integer"
                  },
                  "requestDescription": {
                    "type": "string"
                  },
                  "date": {
                    "type": "integer"
                  },
                  "expectedDate": {
                    "type": "integer"
                  },
                  "budgetID": {
                    "type": "integer"
                  },
                  "customField1": {
                    "type": "string"
                  },
                  "customField2": {
                    "type": "string"
                  },
                  "customField3": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "locationID": 38469,
                "vendorID": 182015,
                "userID": 230530,
                "requestDescription": "testing API created PO",
                "date": 1721631600,
                "expectedDate": 1721631600,
                "budgetID": 6913,
                "customField1": "Test customField1",
                "customField2": "Test customField2",
                "customField3": "Test customField3"
              }
            }
          }
        }
      }
    },
    "/v2/po/{poID}": {
      "patch": {
        "operationId": "patchPoByPoID",
        "summary": "Update Purchase Order",
        "responses": {
          "200": {
            "description": "Update Purchase Order",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders"
        ],
        "description": "This request updates a Purchase Order. Currently, changing the locationID that a PO belongs to is unsupported.\n\nParameter: vendorID, Type: Int, Required?: Optional, Description: The ID of the vendor that this PO will be associated with.\nParameter: userID, Type: Int, Required?: Optional, Description: The ID of the user that this PO will be assigned to.\nParameter: taskID, Type: Int, Required?: Optional, Description: The ID of the task that this PO will be associated with.\nParameter: budgetID, Type: Int, Required?: Optional, Description: The ID of the budget that this PO will be associated with. Changing budgetID when the PO is past the setup phase (state 0) is not supported.\nParameter: date, Type: Int, Required?: Optional, Description: The start time of the PO -- this can be in the past or the future and will still show up in the UI. Must be a unix timestamp.\nParameter: expectedDate, Type: Int, Required?: Optional, Description: The expected delivery date of this PO. Must be a unix timestamp.\nParameter: requestDescription, Type: String, Required?: Optional, Description: A description of the \"request\" for this PO.\nParameter: customField1, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField2, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField3, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField4, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField5, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.\nParameter: customField6, Type: String, Required?: Optional, Description: PO custom field, the customer chooses which custom fields are available on all POs.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "budgetID": {
                    "type": "integer"
                  },
                  "vendorID": {
                    "type": "integer"
                  },
                  "userID": {
                    "type": "integer"
                  },
                  "requestDescription": {
                    "type": "string"
                  },
                  "customField1": {
                    "type": "string"
                  },
                  "customField2": {
                    "type": "string"
                  },
                  "customField3": {
                    "type": "string"
                  },
                  "customField4": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "budgetID": 1,
                "vendorID": 2,
                "userID": 1,
                "requestDescription": "We're gonna need a bigger boat.",
                "customField1": "Test 2",
                "customField2": "Test 5",
                "customField3": "Test 1",
                "customField4": "Test 56"
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "poID",
          "in": "path",
          "required": true,
          "description": "poID of the PO that you are deleting.",
          "schema": {
            "type": "string"
          },
          "example": "{{poID}}"
        }
      ],
      "delete": {
        "operationId": "deletePoByPoID",
        "summary": "Delete PO",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Purchase Orders"
        ],
        "description": "This request deletes a PO. This will also delete any PO Items that belong to this PO, which will also remove any relationships between PO Items, Parts, and Tasks, and will clean up any history of transactions on these PO Items."
      }
    },
    "/v2/gl": {
      "get": {
        "operationId": "getGl",
        "summary": "Get General Ledgers",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what glID you want to start receiving results at. e.g. passing 137 here will only get you GLs with an ID greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          },
          {
            "name": "name",
            "in": "query",
            "description": "This is a parameter used to string search for a name or partial name of a GL. This parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%office%"
          },
          {
            "name": "abbr",
            "in": "query",
            "description": "This is a parameter used to string search for an abbreviation or partial abbreviation of a GL. This parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%off%"
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get GLs that are linked to a location. This parameter accepts a comma delimited list of location IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,163,2"
          },
          {
            "name": "gls",
            "in": "query",
            "description": "This parameter is used to only get specific GLs. This parameter accepts a comma delimited list of GL IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3"
          },
          {
            "name": "assets",
            "in": "query",
            "description": "This parameter is used to only get GLs that are linked to an asset. This parameter accepts a comma delimited list of asset IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3"
          }
        ],
        "responses": {
          "200": {
            "description": "Get General Ledgers",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "glID": {
                        "type": "integer"
                      },
                      "abbr": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "locationID": {
                        "type": "integer"
                      },
                      "description": {
                        "type": "string"
                      },
                      "assetID": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "glID": 1,
                    "abbr": "OFF",
                    "name": "Office",
                    "locationID": 234,
                    "description": "Test",
                    "assetID": 123
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "General Ledgers"
        ],
        "description": "This request returns your GLs in Limble. \n\nReturn data description\n\nProperty: glID, Description: The GL's unique identifier.\nProperty: abbr, Description: An abbreviation for the GL.\nProperty: name, Description: The full name of the GL.\nProperty: locationID, Description: Which Location this GL belongs to.\nProperty: description, Description: An optional bit of descriptive text for the GL.\nProperty: assetID, Description: Which Asset this GL belongs to."
      },
      "post": {
        "operationId": "postGl",
        "summary": "New General Ledger",
        "responses": {
          "201": {
            "description": "New General Ledger",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "glID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "glID": 6
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "General Ledgers"
        ],
        "description": "This request creates a new General Ledger.\n\nParameter: locationID, Type: Int, Required?: Required, Description: The ID of the location this GL will be created for.\nParameter: assetID, Type: Int, Required?: Required, Description: The ID of the asset that this GL will be associated with.\nParameter: abbr, Type: String, Required?: Required, Description: An short version of this GLs name.\nParameter: name, Type: String, Required?: Required, Description: A full title for this GL.\nParameter: description, Type: String, Required?: Optional, Description: Any further needed description for this GL.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "locationID": {
                    "type": "integer"
                  },
                  "assetID": {
                    "type": "integer"
                  },
                  "abbr": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "locationID": 63,
                "assetID": 8895,
                "abbr": "OFF1",
                "name": "Office 1",
                "description": "Any general supplies for Office 1"
              }
            }
          }
        }
      }
    },
    "/v2/gl/{glID}": {
      "patch": {
        "operationId": "patchGlByGlID",
        "summary": "Update General Ledger",
        "responses": {
          "200": {
            "description": "Update General Ledger",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "General Ledgers"
        ],
        "description": "This request updates a General Ledger.\n\nParameter: assetID, Type: Int, Required?: Optional, Description: The ID of the asset that this GL will be associated with. Must be a valid assetID that belongs to the current GL's location.\nParameter: abbr, Type: String, Required?: Optional, Description: An new short version of this GLs name.\nParameter: name, Type: String, Required?: Optional, Description: A new title for this GL.\nParameter: description, Type: String, Required?: Optional, Description: Any further needed description for this GL.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "abbr": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "assetID": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "name": "Sanitation",
                "abbr": "SAN",
                "description": "Any supplies for the Sanitation Department",
                "assetID": 123
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "glID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 46
        }
      ],
      "delete": {
        "operationId": "deleteGlByGlID",
        "summary": "Delete General Ledger",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "General Ledgers"
        ],
        "description": "This request deletes a GL. If any PO Items are associated to this GL, their glID will be set to 0."
      }
    },
    "/v2/budgets/{budgetID}/steps": {
      "post": {
        "operationId": "postBudgetsByBudgetIDSteps",
        "summary": "New Step",
        "responses": {
          "201": {
            "description": "New Step",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "stepID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "stepID": 97
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Budgets",
          "Steps"
        ],
        "description": "This request creates a new Budget Step (sometimes called a PO Workflow Step).\n\nParameter: name, Type: String, Required?: Required, Description: The title of this budget.\nParameter: assignmentType, Type: Enum, Required?: Required, Description: What type ('user' or 'team') should we interpret the assignment value as?\nParameter: assignment, Type: Int or Array of Ints, Required?: Required, Description: When POs belonging to this step's budget enter this step, who will they be assigned to? If awaitingAssignmentType is 'team' then this cannot be an array, and may only be one number.\nParameter: emailSend, Type: Boolean, Required?: Required, Description: When POs of this step's budget enter this step, should we send email notification(s)?\nParameter: allowPOEdit, Type: Boolean, Required?: Optional, Description: When POs belonging to this step's budget are in this step, can the PO be edited?\nParameter: allowPR, Type: Boolean, Required?: Required, Description: When POs belonging to this step's budget are in this step, can items be received?",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "assignmentType": {
                    "type": "string"
                  },
                  "assignment": {
                    "type": "integer"
                  },
                  "emailSend": {
                    "type": "boolean"
                  },
                  "allowPR": {
                    "type": "boolean"
                  },
                  "allowPOEdit": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "name": "Very important step",
                "assignmentType": "user",
                "assignment": 341,
                "emailSend": false,
                "allowPR": true,
                "allowPOEdit": true
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "budgetID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1
        }
      ]
    },
    "/v2/budgets/{budgetID}/steps/{stepID}": {
      "delete": {
        "operationId": "deleteBudgetsByBudgetIDStepsByStepID",
        "summary": "Delete Step",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Budgets",
          "Steps"
        ],
        "description": "This request deletes a step from a budget."
      },
      "parameters": [
        {
          "name": "budgetID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 9
        },
        {
          "name": "stepID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 10
        }
      ],
      "patch": {
        "operationId": "patchBudgetsByBudgetIDStepsByStepID",
        "summary": "Update Step",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Budgets",
          "Steps"
        ],
        "description": "This request updates a Budget Step (sometimes called a PO Workflow Step).\n\nParameter: name, Type: String, Required?: Optional, Description: The title of this budget.\nParameter: assignmentType, Type: Enum, Required?: Optional, Description: What type ('user' or 'team') should we interpret the assignment value as? This is required when the assignment property is present.\nParameter: assignment, Type: Int or Array of Ints, Required?: Optional, Description: When POs belonging to this step's budget enter this step, who will they be assigned to? If awaitingAssignmentType is 'team' then this cannot be an array, and may only be one number. This is required when the assignmentType property is present.\nParameter: emailSend, Type: Boolean, Required?: Optional, Description: When POs of this step's budget enter this step, should we send email notification(s)?\nParameter: allowPOEdit, Type: Boolean, Required?: Optional, Description: When POs belonging to this step's budget are in this step, can the PO be edited?\nParameter: allowPR, Type: Boolean, Required?: Optional, Description: When POs belonging to this step's budget are in this step, can items be received?\nParameter: order, Type: Int, Required?: Optional, Description: For the order of steps in this step's budget, which position should this step be in?",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "assignmentType": {
                    "type": "string"
                  },
                  "assignment": {
                    "type": "integer"
                  },
                  "emailSend": {
                    "type": "boolean"
                  },
                  "allowPOEdit": {
                    "type": "boolean"
                  },
                  "allowPR": {
                    "type": "boolean"
                  },
                  "order": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "name": "Get Approval",
                "assignmentType": "user",
                "assignment": 1,
                "emailSend": true,
                "allowPOEdit": true,
                "allowPR": false,
                "order": 1
              }
            }
          }
        }
      }
    },
    "/v2/budgets/steps": {
      "get": {
        "operationId": "getBudgetsSteps",
        "summary": "Get Steps",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "description": "This is a parameter used to string search for a name or partial name of a budget. This parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%test%"
          },
          {
            "name": "steps",
            "in": "query",
            "description": "This parameter is used to only get specific steps. This parameter accepts a comma delimited list of step IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3"
          },
          {
            "name": "budgets",
            "in": "query",
            "description": "This parameter is used to only get steps that are linked to a budget. This parameter accepts a comma delimited list of budget IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 158
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get steps that are linked to a budget at a specific location. This parameter accepts a comma delimited list of location IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what stepID you want to start receiving results at. e.g. passing 137 here will only get you steps with an ID greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Budget Steps",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/BudgetStep"
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Budgets",
          "Steps"
        ]
      }
    },
    "/v2/budgets": {
      "get": {
        "operationId": "getBudgets",
        "summary": "Get Budgets",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what budgetID you want to start receiving results at. e.g. passing 137 here will only get you budgets with an ID greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "name",
            "in": "query",
            "description": "This is a parameter used to string search for a name or partial name of a budget. This parameter expects a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%General%"
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get budgets that are linked to a location. This parameter accepts a comma delimited list of location IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3"
          },
          {
            "name": "budgets",
            "in": "query",
            "description": "This parameter is used to only get specific budgets. This parameter accepts a comma delimited list of budget IDs.",
            "schema": {
              "type": "string"
            },
            "example": "1,2,3"
          }
        ],
        "responses": {
          "200": {
            "description": "Get Budgets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Budget"
                  }
                },
                "example": [
                  {
                    "budgetID": 1,
                    "name": "General",
                    "locationID": 1,
                    "awaitingAllowPOEdit": false,
                    "awaitingUserID": 0,
                    "awaitingProfileID": 437,
                    "awaitingEmailSend": true,
                    "prUserID": 0,
                    "prProfileID": 1,
                    "prEmailSend": true,
                    "defaultBudget": {
                      "global": true,
                      "purchaseRequests": false,
                      "minPartQtyPOs": true
                    },
                    "meta": {
                      "steps": "/v2/budgets/steps?budgets=1",
                      "location": "/v2/locations?locations=1"
                    }
                  },
                  {
                    "budgetID": 2,
                    "name": "Purchase Request Budget",
                    "locationID": 1,
                    "awaitingAllowPOEdit": true,
                    "awaitingUserID": 1,
                    "awaitingProfileID": 0,
                    "awaitingEmailSend": true,
                    "prUserID": 0,
                    "prProfileID": 0,
                    "prEmailSend": true,
                    "defaultBudget": {
                      "global": false,
                      "purchaseRequests": true,
                      "minPartQtyPOs": false
                    },
                    "meta": {
                      "steps": "/v2/budgets/steps?budgets=2",
                      "location": "/v2/locations?locations=1"
                    }
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Budgets"
        ],
        "description": "This request returns your Budgets in Limble. \n\nReturn data description\n\nProperty: budgetID, Description: The Budget's unique identifier.\nProperty: name, Description: The full name of the Budget.\nProperty: locationID, Description: Which Location this Budget belongs to."
      },
      "post": {
        "operationId": "postBudgets",
        "summary": "New Budget",
        "responses": {
          "201": {
            "description": "New Budget",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "budgetID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "budgetID": 98
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Budgets"
        ],
        "description": "This request creates a new Budget.\n\nParameter: locationID, Type: Int, Required?: Required, Description: The ID of the location this budget will belong to.\nParameter: name, Type: String, Required?: Required, Description: The title of this budget.\nParameter: awaitingAllowPOEdit, Type: Boolean, Required?: Required, Description: When POs belonging to this budget are in the \"ready to receive\" state, will they be editable?\nParameter: awaitingEmailSend, Type: Boolean, Required?: Required, Description: When POs belonging to this budget enter the \"ready to receive\" state, should the assignee(s) be emailed?\nParameter: awaitingAssignmentType, Type: Enum, Required?: Required, Description: What type ('user' or 'team') should we interpret the awaitingAssignment value as?\nParameter: awaitingAssignment, Type: Int or Array of Ints, Required?: Required, Description: When POs belonging to this budget enter the \"ready to receive\" state, who will they be assigned to? If awaitingAssignmentType is 'team' then this cannot be an array, and may only be one number.\nParameter: prEmailSend, Type: Boolean, Required?: Required, Description: When PO items are received on POs that belong to this budget in the \"ready to receive\" or \"partially received\" states, should we send email notification(s)?\nParameter: prAssignmentType, Type: Enum, Required?: Required, Description: What type ('user' or 'team') should we interpret the prAssignment value as?\nParameter: prAssignment, Type: Int or Array of Ints, Required?: Required, Description: When bills are generated for PO items on POs that belong to this budget, who should the bills be assigned to? If prAssignmentType is 'team' then this cannot be an array, and may only be one number.\nParameter: defaultBudget, Type: Object, Required?: Required, Description: An object containing Boolean flags for global, purchaseRequests, and minPartQtyPOs. Setting any of these flags to true will set the same value for any other budgets at this location to false (we cannot have two default budgets). All properties of this object are required. global: Should this be the default budget for this location? purchaseRequests: When purchase requests are created from tasks, should this be the default budget? minPartQtyPOs: When a PO is automatically created due to part quantity threshold, should this be the default budget?",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "locationID": {
                    "type": "integer"
                  },
                  "name": {
                    "type": "string"
                  },
                  "awaitingAllowPOEdit": {
                    "type": "boolean"
                  },
                  "awaitingEmailSend": {
                    "type": "boolean"
                  },
                  "awaitingAssignmentType": {
                    "type": "string"
                  },
                  "awaitingAssignment": {
                    "type": "integer"
                  },
                  "prEmailSend": {
                    "type": "boolean"
                  },
                  "prAssignmentType": {
                    "type": "string"
                  },
                  "prAssignment": {
                    "type": "integer"
                  },
                  "defaultBudget": {
                    "type": "object",
                    "properties": {
                      "global": {
                        "type": "boolean"
                      },
                      "purchaseRequests": {
                        "type": "boolean"
                      },
                      "minPartQtyPOs": {
                        "type": "boolean"
                      }
                    }
                  }
                }
              },
              "example": {
                "locationID": 163,
                "name": "Awesome Test Budget",
                "awaitingAllowPOEdit": true,
                "awaitingEmailSend": true,
                "awaitingAssignmentType": "team",
                "awaitingAssignment": 437,
                "prEmailSend": true,
                "prAssignmentType": "team",
                "prAssignment": 437,
                "defaultBudget": {
                  "global": true,
                  "purchaseRequests": true,
                  "minPartQtyPOs": true
                }
              }
            }
          }
        }
      }
    },
    "/v2/budgets/{budgetID}": {
      "delete": {
        "operationId": "deleteBudgetsByBudgetID",
        "summary": "Delete Budget",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Budgets"
        ],
        "description": "This request deletes a budget."
      },
      "parameters": [
        {
          "name": "budgetID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 1
        }
      ],
      "patch": {
        "operationId": "patchBudgetsByBudgetID",
        "summary": "Update Budget",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Budgets"
        ],
        "description": "This request updates an existing Budget.\n\nParameter: name, Type: String, Required?: Optional, Description: The title of this budget.\nParameter: awaitingAllowPOEdit, Type: Boolean, Required?: Optional, Description: When POs belonging to this budget are in the \"ready to receive\" state, will they be editable?\nParameter: awaitingEmailSend, Type: Boolean, Required?: Optional, Description: When POs belonging to this budget enter the \"ready to receive\" state, should the assignee(s) be emailed?\nParameter: awaitingAssignmentType, Type: Enum, Required?: Optional, Description: What type ('user' or 'team') should we interpret the awaitingAssignment value as? Required when awaitingAssignment is provided.\nParameter: awaitingAssignment, Type: Int or Array of Ints, Required?: Optional, Description: When POs belonging to this budget enter the \"ready to receive\" state, who will they be assigned to? If awaitingAssignmentType is 'team' then this cannot be an array, and may only be one number. Required when awaitingAssignmentType is provided.\nParameter: prEmailSend, Type: Boolean, Required?: Optional, Description: When PO items are received on POs that belong to this budget in the \"ready to receive\" or \"partially received\" states, should we send email notification(s)?\nParameter: prAssignmentType, Type: Enum, Required?: Optional, Description: What type ('user' or 'team') should we interpret the prAssignment value as? Required when prAssignment is provided.\nParameter: prAssignment, Type: Int or Array of Ints, Required?: Optional, Description: When bills are generated for PO items on POs that belong to this budget, who should the bills be assigned to? If prAssignmentType is 'team' then this cannot be an array, and may only be one number. Required when prAssignmentType is provided.\nParameter: defaultBudget, Type: Object, Required?: Optional, Description: An object containing Boolean flags for global, purchaseRequests, and minPartQtyPOs. Setting any of these flags to true will set the same value for any other budgets at this location to false (we cannot have two default budgets). All properties of this object are required when the object is provided. global: Should this be the default budget for this location? purchaseRequests: When purchase requests are created from tasks, should this be the default budget? minPartQtyPOs: When a PO is automatically created due to part quantity threshold, should this be the default budget?",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "awaitingAllowPOEdit": {
                    "type": "boolean"
                  },
                  "awaitingEmailSend": {
                    "type": "boolean"
                  },
                  "awaitingAssignmentType": {
                    "type": "string"
                  },
                  "awaitingAssignment": {
                    "type": "integer"
                  },
                  "prEmailSend": {
                    "type": "boolean"
                  },
                  "prAssignmentType": {
                    "type": "string"
                  },
                  "prAssignment": {
                    "type": "array",
                    "items": {
                      "type": "integer"
                    }
                  },
                  "defaultBudget": {
                    "type": "object",
                    "properties": {
                      "global": {
                        "type": "boolean"
                      },
                      "purchaseRequests": {
                        "type": "boolean"
                      },
                      "minPartQtyPOs": {
                        "type": "boolean"
                      }
                    }
                  }
                }
              },
              "example": {
                "name": "Extremely Cool Budget",
                "awaitingAllowPOEdit": false,
                "awaitingEmailSend": false,
                "awaitingAssignmentType": "team",
                "awaitingAssignment": 1,
                "prEmailSend": false,
                "prAssignmentType": "user",
                "prAssignment": [
                  1,
                  2,
                  3
                ],
                "defaultBudget": {
                  "global": true,
                  "purchaseRequests": false,
                  "minPartQtyPOs": true
                }
              }
            }
          }
        }
      }
    },
    "/v2/priorities": {
      "get": {
        "operationId": "getPriorities",
        "summary": "Get Priorities",
        "parameters": [
          {
            "name": "priorities",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 118
          }
        ],
        "responses": {
          "200": {
            "description": "Get Priorities",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "priorityID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      },
                      "priorityLevel": {
                        "type": "integer"
                      },
                      "color": {
                        "type": "string",
                        "format": "color"
                      },
                      "isDefault": {
                        "type": "boolean"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "priorityID": 8,
                    "name": "Ultra Low",
                    "priorityLevel": 4,
                    "color": "#000000",
                    "isDefault": false
                  },
                  {
                    "priorityID": 9,
                    "name": "Low Priority",
                    "priorityLevel": 1,
                    "color": "#429b1f",
                    "isDefault": false
                  },
                  {
                    "priorityID": 10,
                    "name": "Medium Priority",
                    "priorityLevel": 2,
                    "color": "#ef6a00",
                    "isDefault": false
                  },
                  {
                    "priorityID": 11,
                    "name": "Medium Priority",
                    "priorityLevel": 3,
                    "color": "#ef6a00",
                    "isDefault": false
                  },
                  {
                    "priorityID": 12,
                    "name": "High Priority",
                    "priorityLevel": 5,
                    "color": "#c22528",
                    "isDefault": false
                  },
                  {
                    "priorityID": 13,
                    "name": "High Priority",
                    "priorityLevel": 6,
                    "color": "#c22528",
                    "isDefault": false
                  },
                  {
                    "priorityID": 14,
                    "name": "On Hold",
                    "priorityLevel": 7,
                    "color": "#f1c40f",
                    "isDefault": false
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Priorities"
        ],
        "description": "This request returns your priorities in Limble. \n\nReturn data description\n\nProperty: priorityID, Description: The priority's unique identifier.\nProperty: name, Description: The full name of the priority.\nProperty: priorityLevel, Description: A number representing ordering or indicator of severity.\nProperty: color, Description: A hex-color string that will be used to color tasks associated to this priority.\nProperty: isDefault, Description: A boolean representing whether or not this is the priority that will be associated to tasks by default."
      },
      "post": {
        "operationId": "postPriorities",
        "summary": "New Priority",
        "responses": {
          "201": {
            "description": "New Priority",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "priorityID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "priorityID": 113
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Priorities"
        ],
        "description": "This request creates a new Priority.\n\nWhen providing priorityLevel or isDefault, calls to this endpoint may reorder or otherwise adjust other priorities.\n\nParameter: name, Type: String, Required?: Required, Description: The title of this priority.\nParameter: priorityLevel, Type: Int, Required?: Required, Description: What level is this priority? If we're inserting a priority in the middle of the levels, priorities with a priorityLevel equal-to or greater-than the specified priorityLevel will have their priorityLevel incremented by one. This can only be between the numbers 1 and the current highest priorityLevel + 1.\nParameter: color, Type: String, Required?: Optional, Description: This is the color that will be shown on all tasks with this priority. Default is #429b1f\nParameter: isDefault, Type: Boolean, Required?: Optional, Description: Should this be the default priority that tasks are assigned to when a priority is not specified? Default is false. If isDefault is true, then any other priorities will have their isDefault set to false.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "priorityLevel": {
                    "type": "integer"
                  },
                  "color": {
                    "type": "string",
                    "format": "color"
                  },
                  "isDefault": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "name": "Super Extreme",
                "priorityLevel": 5,
                "color": "#000000",
                "isDefault": true
              }
            }
          }
        }
      }
    },
    "/v2/priorities/{priorityID}": {
      "patch": {
        "operationId": "patchPrioritiesByPriorityID",
        "summary": "Update Priority",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Priorities"
        ],
        "description": "This request updates a Priority.\n\n**When providing priorityLevel or isDefault, calls to this endpoint may reorder or otherwise adjust** _**other**_ **priorities.**\n\nname | String | Optional | The title of this priority.\npriorityLevel | Int | Optional | What level is this priority? When moving a priority to a different priorityLevel, be mindful that this will shift other priorities' priorityLevels in order to accommodate this change. If provided, this can only be between the numbers 1 and the current highest priorityLevel.\ncolor | String | Optional | This is the color that will be shown on all tasks with this priority.\nisDefault | Boolean | Optional | Should this be the default priority that tasks are assigned to when a priority is not specified? When setting this to true, any other priorities whose isDefault is true will have it set to false.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "isDefault": {
                    "type": "boolean"
                  }
                }
              },
              "example": {
                "name": "On Hold",
                "isDefault": true
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "priorityID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 8
        }
      ],
      "delete": {
        "operationId": "deletePrioritiesByPriorityID",
        "summary": "Delete Priority",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Priorities"
        ],
        "description": "This call simply removes a priority from Limble.\n\nThings to keep in mind when using this endpoint:\n\n- \nCalls to this endpoint will potentially adjust other priorities' priorityLevels.\n\n- If you delete a priority that isDefault, you will not have a default priority anymore, and that may cause issues.\n\n- If you delete a priority that has tasks associated to it, those tasks will have their priority removed.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/v2/tags": {
      "get": {
        "operationId": "getTags",
        "summary": "Get Tags",
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "safety"
          }
        ],
        "responses": {
          "200": {
            "description": "Get Tags",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "example": [
                  "@Safety"
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tags"
        ],
        "description": "This request returns your tags in Limble.\n\nReturn data description\n\nProperty: name, Description: A search-string for tags."
      },
      "post": {
        "operationId": "postTags",
        "summary": "Create Account Tag",
        "responses": {
          "200": {
            "description": "200 OK - Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "created": {
                      "type": "boolean"
                    },
                    "name": {
                      "type": "string"
                    },
                    "tags": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tags"
        ],
        "description": "Creates a new account-level custom tag. The tag is normalized and validated before creation.\n\n**Request Body:**\n- `name` (string, required) - Tag name with or without leading '@', must not contain ';'\n\n**Response (200 OK):**\n- `created` (boolean) - Always true on success\n- `name` (string) - Canonical tag name without trailing ';' (e.g., `@Food Safety`)\n- `sanitizations` (array, optional) - List of normalization actions applied\n- `tags` (array) - All account tags in canonical format with trailing ';'\n\n**Normalization Rules:**\n- Semicolons ';' are rejected (not allowed in input)\n- Internal '@' characters removed, single leading '@' added\n- Backslashes removed\n- Commas converted to spaces\n- Whitespace collapsed\n- CR/LF and NBSP normalized to spaces\n- ASCII control characters removed\n\n**Error Responses:**\n- 400 Bad Request - Invalid input (contains ';' or normalizes to empty)\n- 409 Conflict - Tag already exists (case-insensitive comparison)",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "name": "@Food Safety"
              }
            }
          }
        }
      }
    },
    "/v2/tags/{oldName}": {
      "patch": {
        "operationId": "patchTagsByOldName",
        "summary": "Rename Account Tag",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "description": "The tag to rename does not exist at the account level."
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tags"
        ],
        "description": "Renames an account-level custom tag.  \n  \n**IMPORTANT NOTE:** The change propagates to all data entities using this tag (Tasks, dashboards, notifications, etc).\n\n**Path Parameters:**\n\n- `oldName` (string, required) - Existing tag name (with or without '@', without trailing ';')\n    - URL encode special characters (e.g., `@Food%20Safety` for `@Food Safety`)\n\n**Request Body:**\n\n- `newName` (string, required) - New tag name (with or without '@', without trailing ';')\n\n**Response (200 OK):**\n\n- `renamed` (boolean) - Always true on success\n    \n- `from` (string) - Old canonical tag name without trailing ';'\n    \n- `to` (string) - New canonical tag name without trailing ';'\n    \n- `tags` (array) - All account tags in canonical format with trailing ';'\n\n**Validation:**\n\n- Old tag must exist (case-insensitive)\n    \n- New tag must not exist (case-insensitive)\n    \n- Semicolons not allowed in input\n    \n- Both names subject to normalization rules\n\n**Error Responses:**\n\n- 400 Bad Request - Invalid input (contains ';' or normalizes to empty)\n    \n- 404 Not Found - Old tag does not exist\n    \n- 409 Conflict - New tag name already exists",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "newName": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "newName": "@Food & Safety"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteTagsByTagName",
        "summary": "Delete Account Tag",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "description": "The tag to delete does not exist at the account level."
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Tags"
        ],
        "description": "Deletes an account-level custom tag.\n\n**IMPORTANT NOTE:** The change propagates to all data entities using this tag (Tasks, dashboards, notifications, etc).\n\n**Path Parameters:**\n\n- `oldName` (string, required) - Tag name to delete (with or without '@', without trailing ';')\n    - URL encode special characters (e.g., `@Food%20Safety` for `@Food Safety`)\n\n**Response (200 OK):**\n\n- `deleted` (boolean) - Always true on success\n    \n- `name` (string) - Canonical tag name that was deleted (without trailing ';')\n    \n- `tags` (array) - Remaining account tags in canonical format with trailing ';'\n\n**Validation:**\n\n- Tag must exist (case-insensitive)\n    \n- Tag name subject to normalization for matching\n\n**Error Responses:**\n\n- 404 Not Found - Tag does not exist"
      },
      "parameters": [
        {
          "name": "oldName",
          "in": "path",
          "required": true,
          "description": "Tag name (URL encode spaces and special characters)",
          "schema": {
            "type": "string"
          },
          "example": "@Food Safety"
        }
      ]
    },
    "/v2/statuses": {
      "get": {
        "operationId": "getStatuses",
        "summary": "Statuses",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 3
          },
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "%ogr%"
          },
          {
            "name": "statuses",
            "in": "query",
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "200": {
            "description": "Statuses",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "statusID": {
                        "type": "integer"
                      },
                      "name": {
                        "type": "string"
                      },
                      "description": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "statusID": 1,
                    "name": "In Progress",
                    "description": ""
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Statuses"
        ],
        "description": "This request returns your custom task statuses in Limble.\n\nReturn data description\n\nProperty: statusID, Description: A unique identifier for this status.\nProperty: name, Description: A custom string that labels this status.\nProperty: description, Description: An optional description that elaborates on what this status means."
      },
      "post": {
        "operationId": "postStatuses",
        "summary": "Create Status",
        "responses": {
          "201": {
            "description": "201 Created - Success",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/statuses?statuses=10"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "statusID": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "description": "Invalid input — name is missing, exceeds 100 characters, or description exceeds 65535 characters."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "description": "A status with this name already exists (case-insensitive), or the name conflicts with a default status."
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Statuses"
        ],
        "description": "Creates a new custom status for the customer account.\n\n**Request Body:**\n\n- `name` (string, required) - Status name, 1-100 characters, must be unique (case-insensitive)\n    \n- `description` (string, optional) - Status description, max 65535 characters\n    \n- `sortOrder` (integer, optional) - Display order, 0-99, auto-assigned if omitted\n    \n\n**Response (201 Created):**\n\n- `statusID` (number) - ID of the newly created status\n    \n- Location header: `/v2/statuses?statuses={statusID}`\n    \n\n**Validation:**\n\n- Name must not conflict with existing statuses or defaults (\"Open\", \"In Progress\", \"Complete\")\n    \n- Name is compared case-insensitively",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "sortOrder": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "name": "Blocked",
                "description": "Task is blocked by external dependencies",
                "sortOrder": 3
              }
            }
          }
        }
      }
    },
    "/v2/statuses/{statusID}": {
      "patch": {
        "operationId": "patchStatusesByStatusID",
        "summary": "Update Status",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "description": "Cannot modify a default status (IDs 0, 1, 2)."
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "description": "Status not found."
          },
          "409": {
            "$ref": "#/components/responses/Conflict",
            "description": "A status with this name already exists (case-insensitive), or the name conflicts with a default status."
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Statuses"
        ],
        "description": "Updates an existing custom status. Default statuses (0, 1, 2) cannot be modified.\n\n**IMPORTANT NOTE:** Changes to statuses automatically propogate to all tasks currently assigned that status.\n\n**Path Parameters:**\n\n- `statusID` (number, required) - ID of the status to update\n    \n\n**Request Body (at least one field required):**\n\n- `name` (string, optional) - New status name, 1-100 characters, must be unique\n    \n- `description` (string, optional) - New description, max 65535 characters\n    \n- `sortOrder` (integer, optional) - New display order, 0-99\n    \n\n**Validation:**\n\n- Cannot modify default statuses (IDs 0, 1, 2)\n    \n- If changing name, must not conflict with existing statuses\n    \n- Status must exist and belong to the customer",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "description": {
                    "type": "string"
                  },
                  "sortOrder": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "name": "On Hold",
                "description": "Task temporarily paused",
                "sortOrder": 5
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "statusID",
          "in": "path",
          "required": true,
          "description": "The ID of the status to delete",
          "schema": {
            "type": "integer"
          },
          "example": 10
        }
      ],
      "delete": {
        "operationId": "deleteStatusesByStatusID",
        "summary": "Delete Status",
        "parameters": [
          {
            "name": "replacementStatusID",
            "in": "query",
            "description": "ID of the status to reassign tasks to (required)",
            "schema": {
              "type": "integer"
            },
            "example": 1
          }
        ],
        "responses": {
          "204": {
            "description": "204 No Content - Success"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest",
            "description": "The replacementStatusID query parameter is missing, invalid, or references the status being deleted."
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden",
            "description": "Cannot delete a default status (IDs 0, 1, 2)."
          },
          "404": {
            "$ref": "#/components/responses/NotFound",
            "description": "Status not found."
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Statuses"
        ],
        "description": "Deletes a custom status and reassigns all tasks using it. Default statuses (0, 1, 2) cannot be deleted.\n\n**IMPORTANT NOTE:** Deleting task statuses that are currently in use will result in all tasks assigned that status being reset to status 0 (open).\n\n**Path Parameters:**\n\n- `statusID` (number, required) - ID of the status to delete\n    \n\n**Query Parameters:**\n\n- `replacementStatusID` (number, required) - ID of the status to assign to tasks currently using the deleted status. Can be a default status (0, 1, 2) or another custom status.\n    \n\n**Validation:**\n\n- Cannot delete default statuses (IDs 0, 1, 2)\n    \n- Both statusID and replacementStatusID must exist\n    \n- replacementStatusID must differ from statusID\n    \n- replacementStatusID must be valid for the customer"
      }
    },
    "/v2/bills/{billID}/transactions": {
      "post": {
        "operationId": "postBillsByBillIDTransactions",
        "summary": "Add Bill Item",
        "responses": {
          "201": {
            "description": "Add Bill Item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "transactionID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "transactionID": 399
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Transactions"
        ],
        "description": "This request creates a Bill transaction by adding a Bill Item to an unclosed Bill.\n\nParameter: poItemID, Type: Int, Required?: Required, Description: The ID of the item that has to be added to the Bill.\nParameter: qtyReceived, Type: Int, Required?: Required, Description: The item quantity received on this Bill.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "poItemID": {
                    "type": "integer"
                  },
                  "qtyReceived": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "poItemID": 358,
                "qtyReceived": 2
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "billID",
          "in": "path",
          "required": true,
          "description": "The ID of the bill for which an item needs to be added.",
          "schema": {
            "type": "integer"
          },
          "example": 425
        }
      ]
    },
    "/v2/bills/transactions": {
      "get": {
        "operationId": "getBillsTransactions",
        "summary": "Bill Transactions",
        "parameters": [
          {
            "name": "bills",
            "in": "query",
            "description": "This parameter is used to only get specific Bill Transactions by billID. This parameter expects a comma delimited list of billIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 423
          },
          {
            "name": "items",
            "in": "query",
            "description": "This parameter is used to only get specific Bill Transactions by items in a Bill. This parameter expects a comma delimited list of poItem IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 358
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Bill Transactions that were created after or on the unix timestamp passed into it. ",
            "schema": {
              "type": "integer"
            },
            "example": 1630611650
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Bill transactions that were created before or on the unix timestamp passed into it. ",
            "schema": {
              "type": "integer"
            },
            "example": 1630611660
          },
          {
            "name": "transactions",
            "in": "query",
            "description": "This parameter is used to only get specific Bill Transactions. This parameter expects a comma delimited list of transactionIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 397
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 10
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get Bill Transactions at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 163
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "Cursor for pagination. Pass the transactionID of the last record from the previous page to fetch the next page. Defaults to 0 (start from the beginning).",
            "schema": {
              "type": "integer"
            },
            "example": 0
          }
        ],
        "responses": {
          "200": {
            "description": "Bill Transaction",
            "headers": {
              "X-Has-More": {
                "schema": {
                  "type": "string",
                  "enum": [
                    "true",
                    "false"
                  ]
                },
                "description": "Indicates whether additional records exist beyond the current page.",
                "example": "false"
              },
              "Next-Page": {
                "schema": {
                  "type": "string"
                },
                "description": "Ready-to-use URL for the next page (only present when X-Has-More is true).",
                "example": "/v2/bills/transactions?limit=100&cursor=397"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "transactionID": {
                        "type": "integer"
                      },
                      "billID": {
                        "type": "integer"
                      },
                      "poItemID": {
                        "type": "integer"
                      },
                      "qtyReceived": {
                        "type": "integer"
                      },
                      "dateReceived": {
                        "type": "integer"
                      },
                      "meta": {
                        "type": "object",
                        "properties": {
                          "bills": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                },
                "example": [
                  {
                    "transactionID": 397,
                    "billID": 423,
                    "poItemID": 358,
                    "qtyReceived": 1,
                    "dateReceived": 1630611659,
                    "meta": {
                      "bills": "/v2/bills?bills=423"
                    }
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Transactions"
        ],
        "description": "This request gets information about the transactions made for a Bill.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "/v2/bills/{billID}/transactions/{transactionID}": {
      "patch": {
        "operationId": "patchBillsByBillIDTransactionsByTransactionID",
        "summary": "Update Bill Transaction",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Transactions"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "poItemID": {
                    "type": "integer"
                  },
                  "qtyReceived": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "poItemID": 358,
                "qtyReceived": 100
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "billID",
          "in": "path",
          "required": true,
          "description": "The ID of the Bill for which the transaction needs to be updated.",
          "schema": {
            "type": "integer"
          },
          "example": 425
        },
        {
          "name": "transactionID",
          "in": "path",
          "required": true,
          "description": "The ID of the transaction which needs ot be updated.",
          "schema": {
            "type": "integer"
          },
          "example": 399
        }
      ]
    },
    "/v2/bills/transactions/{transactionID}": {
      "delete": {
        "operationId": "deleteBillsTransactionsByTransactionID",
        "summary": "Bill Transaction",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Transactions"
        ]
      },
      "parameters": [
        {
          "name": "transactionID",
          "in": "path",
          "required": true,
          "description": "The ID of the Bill Transaction to be deleted.",
          "schema": {
            "type": "integer"
          },
          "example": 399
        }
      ]
    },
    "/v2/bills/{billID}/comments": {
      "get": {
        "operationId": "getBillsByBillIDComments",
        "summary": "Bill Comments",
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what commentID you want to start receiving results at. e.g. passing 100 here will only get you comments with an id greater than 100",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Bill Comments",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "commentID": {
                        "type": "integer"
                      },
                      "comment": {
                        "type": "string"
                      },
                      "timestamp": {
                        "type": "integer"
                      },
                      "userID": {
                        "type": "integer"
                      },
                      "commentFiles": {
                        "type": "array"
                      },
                      "commentEmailAddress": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "commentID": 47,
                    "comment": "Bill marked as paid",
                    "timestamp": 1688165716,
                    "userID": 340,
                    "commentFiles": [],
                    "commentEmailAddress": ""
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Comments"
        ],
        "description": "This request gets all Bill Comments associated with a Bill.\n\nReturn data description\n\ncommentID | This is the commentID of comment.\ncomment | The text comment that was entered by the user.\ntimestamp | The date this comment was created. This is a unix timestamp.\nuserID | The ID of the user that made the comment.\ncommentEmailAddress | The email address of the external user that made this comment. This is only populated if the comment was made by an external user via the comment reply system.\ncommentFiles | Array containing fileName and link properties."
      },
      "parameters": [
        {
          "name": "billID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 2001
        }
      ],
      "post": {
        "operationId": "postBillsByBillIDComments",
        "summary": "Create Bill Comment",
        "responses": {
          "201": {
            "description": "201 Created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Comments"
        ],
        "description": "Adds a comment to a Bill.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| billID | path | integer | yes |  | Bill identifier |\n| comment | body | string | yes |  | Comment text |\n| showExternalUsers | body | boolean | no | true | Visible to external users |\n\nResponses:\n- 201 Created: Returns commentID."
      }
    },
    "/v2/bills/{billID}/comments/{commentID}/file": {
      "put": {
        "operationId": "putBillsByBillIDCommentsByCommentIDFile",
        "summary": "Upload Bill Comment File",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Comments"
        ],
        "description": "Uploads a file to a Bill comment.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| billID | path | integer | yes |  | Bill identifier |\n| commentID | path | integer | yes |  | Comment identifier |\n| file | form-data | file | yes |  | File to upload (max 50MB). Same types as PO comment files |"
      },
      "parameters": [
        {
          "name": "billID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 2001
        },
        {
          "name": "commentID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 12
        }
      ],
      "delete": {
        "operationId": "deleteBillsByBillIDCommentsByCommentIDFile",
        "summary": "Delete Bill Comment File",
        "parameters": [
          {
            "name": "filename",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "receipt.png"
          }
        ],
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Comments"
        ],
        "description": "Deletes a file from a Bill comment.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| billID | path | integer | yes |  | Bill identifier |\n| commentID | path | integer | yes |  | Comment identifier |\n| filename | query | string | yes |  | Exact filename to remove |\n\nResponses:\n- 200 OK: Deleted.\n- 404 Not Found: File not found."
      }
    },
    "/v2/bills/{billID}/comments/{commentID}": {
      "delete": {
        "operationId": "deleteBillsByBillIDCommentsByCommentID",
        "summary": "Delete Bill Comment",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills",
          "Comments"
        ],
        "description": "Deletes a Bill comment.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| billID | path | integer | yes |  | Bill identifier |\n| commentID | path | integer | yes |  | Comment identifier |\n\nResponses:\n- 200 OK: Deleted.\n- 404 Not Found: Comment not found."
      },
      "parameters": [
        {
          "name": "billID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 2001
        },
        {
          "name": "commentID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 12
        }
      ]
    },
    "/v2/bills": {
      "get": {
        "operationId": "getBills",
        "summary": "Get Bills",
        "parameters": [
          {
            "name": "bills",
            "in": "query",
            "description": "This parameter is used to only get specific Bills. This parameter expects a comma delimited list of billIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "numbers",
            "in": "query",
            "description": "This parameter is used to only get specific Bills by Number. This parameter expects a comma delimited list of billNumbers.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "status",
            "in": "query",
            "description": "This parameter is used to only get specific Bills by their status. The bill status could be 0,1 or 2\n",
            "schema": {
              "type": "string"
            },
            "example": "0,1"
          },
          {
            "name": "end",
            "in": "query",
            "description": "This parameter is used to only get Bills that were created before or on the unix timestamp passed into it. ",
            "schema": {
              "type": "integer"
            },
            "example": 1697443800
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "pos",
            "in": "query",
            "description": "This parameter is used to only get specific Bills by POs. This parameter expects a comma delimited list of PO IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 5
          },
          {
            "name": "start",
            "in": "query",
            "description": "This parameter is used to only get Bills that were created after or on the unix timestamp passed into it. ",
            "schema": {
              "type": "integer"
            },
            "example": 1597443703
          },
          {
            "name": "locations",
            "in": "query",
            "description": "This parameter is used to only get Bills at a specific group of Locations. This parameter accepts a comma delimited list of Location IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 163
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what billID you want to start receiving results at. e.g. passing 130 here will only get you bills with an id greater than 130.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information.",
            "schema": {
              "type": "integer"
            },
            "example": 2
          }
        ],
        "responses": {
          "200": {
            "description": "Get Bills",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Bill"
                  }
                },
                "example": [
                  {
                    "billID": 1,
                    "poID": 5,
                    "status": 1,
                    "userID": 340,
                    "userIDStarted": 340,
                    "userIDMarkPaid": 0,
                    "billNumber": 1,
                    "locationID": 163,
                    "date": 1597443703,
                    "meta": {
                      "items": "/v2/po/items?pos=5",
                      "po": "/v2/po?pos=5",
                      "transactions": "/v2/bills/transactions?bills=1"
                    }
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills"
        ],
        "description": "This request gets information such as Bill IDs, Bill Numbers, etc.\n\nThis call returns a \"meta\" object containing URLs that can be used to get data related to the Bill.\n\nNote: this endpoint supports pagination. Please refer to the [**Pagination**](#pagination) section for more information.\n\nReturn data description\n\nProperty: meta, Description: useful links relating to this Bill\nProperty: billID, Description: The unique ID of the Bill.\nProperty: billNumber, Description: The bill number assigned to the Bill.\nProperty: poID, Description: The poID of which the Bill was made.\nProperty: locationID, Description: The unique ID of the location associated with this Bill.\nProperty: date, Description: The date this Bill was created as a UNIX timestamp.\nProperty: status, Description: The status of this Bill. The status can be as follows: 0: The bill is setup. 1: The bill is submitted. 2: The bill is closed i.e. Marked as Paid\nProperty: userID, Description: The Id of the user this Bill was assigned to.\nProperty: userIDStarted, Description: The ID of the user this Bill was created by.\nProperty: userIDMarkPaid, Description: The ID of the user this Bill was marked paid by."
      },
      "post": {
        "operationId": "postBills",
        "summary": "New Bill",
        "responses": {
          "201": {
            "description": "New Bill",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "billID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "billID": 423
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills"
        ],
        "description": "This request creates a new Bill for a Purchase Order.\n\nParameter: poID, Type: Int, Required?: Required, Description: The poID for which the Bill is made.\nParameter: userID, Type: Int, Required?: Optional, Description: The ID of the user that this Bill will be assigned to.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "poID": {
                    "type": "integer"
                  },
                  "userID": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "poID": 381,
                "userID": 340
              }
            }
          }
        }
      }
    },
    "/v2/bills/{billID}": {
      "patch": {
        "operationId": "patchBillsByBillID",
        "summary": "Update Bill",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills"
        ],
        "description": "This request updates a Bill. \n\nParameter: userID, Type: Int, Required?: Optional, Description: The ID of the user that this Bill will be assigned to.\nParameter: status, Type: Int, Required?: Optional, Description: The status of this Bill. Refer to GET Bill to understand what values status can be. A bill status cannot be reduced once it is changed.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userID": {
                    "type": "integer"
                  },
                  "status": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "userID": 340,
                "status": 2
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "billID",
          "in": "path",
          "required": true,
          "description": "The ID of the Bill to be deleted.",
          "schema": {
            "type": "integer"
          },
          "example": 226
        }
      ],
      "delete": {
        "operationId": "deleteBillsByBillID",
        "summary": "Delete Bill",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Bills"
        ],
        "description": "This request deletes a Bill. This will also delete any Bill transactions for PO Items that were received on this Bill. The qty and price of the PO Items on the Bill will be recalculated."
      }
    },
    "/v2/regions": {
      "post": {
        "operationId": "postRegions",
        "summary": "Create Region",
        "responses": {
          "201": {
            "description": "201 Created",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "/v2/regions?regions=123"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "regionID": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Regions"
        ],
        "description": "Creates a region.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| name | body | string | yes |  | Region name |\n| parentRegionID | body | integer | no | 0 | Parent region (≥ 0) |\n\nResponses:\n- 201 Created: { regionID } with Location header."
      },
      "get": {
        "operationId": "getRegions",
        "summary": "Regions",
        "parameters": [
          {
            "name": "regions",
            "in": "query",
            "description": "This parameter is used to only get regions in the list provided. This parameter accepts a comma delimited list of Region IDs.",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "name",
            "in": "query",
            "description": "This parameter is used to only get specific regions by name. This parameter expects a string- the full name of a region\n or partial name with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%One%"
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what regionID you want to start receiving results at. e.g. passing 137 here will only get you regions\n with an id greater than 137.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 \nresults at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Regions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "regionID": {
                        "type": "integer"
                      },
                      "regionName": {
                        "type": "string"
                      },
                      "parentRegionID": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "regionID": 1,
                    "regionName": "One region",
                    "parentRegionID": 0
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Regions"
        ],
        "description": "This request returns your Regions in Limble. \n\nReturn data description\n\nProperty: regionID, Description: The ID of the Region\nProperty: regionName, Description: The name of the Region\nProperty: parentRegionID, Description: The regionID of the parent of a region."
      }
    },
    "/v2/regions/{regionID}": {
      "patch": {
        "operationId": "patchRegionsByRegionID",
        "summary": "Update Region",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Regions"
        ],
        "description": "Updates a region.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| regionID | path | integer | yes |  | Region identifier |\n| name | body | string | no |  | New name |\n| parentRegionID | body | integer | no |  | New parent (≥ 1) |"
      },
      "parameters": [
        {
          "name": "regionID",
          "in": "path",
          "required": true,
          "schema": {
            "type": "integer"
          },
          "example": 123
        }
      ],
      "delete": {
        "operationId": "deleteRegionsByRegionID",
        "summary": "Delete Region",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Regions"
        ],
        "description": "Deletes a region.\n\nParameters:\n\n| Parameter | In | Type | Required | Default | Description |\n|---|---|---|---|---|---|\n| regionID | path | integer | yes |  | Region identifier |\n\nResponses:\n- 200 OK: Deleted.\n- 404 Not Found: Region does not exist."
      }
    },
    "/v2/webhooks": {
      "get": {
        "operationId": "getWebhooks",
        "summary": "Get Webhooks",
        "parameters": [
          {
            "name": "webhooks",
            "in": "query",
            "description": "This parameter is used to only get specific Webhooks. This parameter expects a comma delimited list of webhookIDs.",
            "schema": {
              "type": "integer"
            },
            "example": 24
          },
          {
            "name": "endpoint",
            "in": "query",
            "description": "This parameter is used for a string search by the webhook endpoint. This parameter expects a URL or partial URL of a webhook using a string with the wildcard %.",
            "schema": {
              "type": "string"
            },
            "example": "%hello.com"
          },
          {
            "name": "type",
            "in": "query",
            "description": "This parameter is used to only get Webhooks of a specific type. This parameter accepts a comma delimited list of webhook types.",
            "schema": {
              "type": "string"
            },
            "example": "task"
          },
          {
            "name": "enabled",
            "in": "query",
            "description": "This parameter is used to get Webooks which are enabled. This paramter expects 1: Enabled or 0: Disabled",
            "schema": {
              "type": "integer"
            },
            "example": 1
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "This parameter is a cursor that selects what webhookID you want to start receiving results at. e.g. passing 10 here will only get you webhooks with an id greater than 10.",
            "schema": {
              "type": "integer"
            },
            "example": 0
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is set to return no more than 100 results at one time.",
            "schema": {
              "type": "integer"
            },
            "example": 100
          }
        ],
        "responses": {
          "200": {
            "description": "Get Webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "webhookID": {
                        "type": "integer"
                      },
                      "endpoint": {
                        "type": "string",
                        "format": "uri"
                      },
                      "type": {
                        "type": "string"
                      },
                      "enabled": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "webhookID": 24,
                    "endpoint": "https://hello.com",
                    "type": "task",
                    "enabled": 1
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Webhooks"
        ],
        "description": "This request returns your Webhooks configured for Limble. \n\nReturn data description\n\nProperty: webhhokID, Description: The ID of the Webhook\nProperty: endpoint, Description: The webhook URL.\nProperty: type, Description: The type of webhook. Webhooks can be of type task, po, poItem.\nProperty: enabled, Description: Determines if the webhook is enabled. 0 = Disabled 1=Enabled"
      },
      "post": {
        "operationId": "postWebhooks",
        "summary": "New Webhook",
        "responses": {
          "201": {
            "description": "New Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "webhookID": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "webhookID": 42
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Webhooks"
        ],
        "description": "This requests creates a new Webhook.\n\nParameter\nType\nRequired?\nDescription\n\nendpoint\nURL\nRequired\nThe webhook URL.\n\ntype\nString\nRequired\nThe type of webhook. Refer to GET webhooks for type values\n\nenabled\nInt\nOptional\nShould the webhook be enabled or disabled. It is enabled(1) by default.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "endpoint": {
                    "type": "string",
                    "format": "uri"
                  },
                  "type": {
                    "type": "string"
                  },
                  "enabled": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "endpoint": "https://hello.com",
                "type": "assetField",
                "enabled": 0
              }
            }
          }
        }
      }
    },
    "/v2/webhooks/{webhookID}": {
      "delete": {
        "operationId": "deleteWebhooksByWebhookID",
        "summary": "Delete Webhook",
        "responses": {
          "200": {
            "$ref": "#/components/responses/EmptySuccess"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Webhooks"
        ],
        "description": "This request deletes a Webhook.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "webhookID",
          "in": "path",
          "required": true,
          "description": "This parameter expects a webhookID.",
          "schema": {
            "type": "integer"
          },
          "example": 42
        }
      ],
      "patch": {
        "operationId": "patchWebhooksByWebhookID",
        "summary": "Update Webhook",
        "responses": {
          "200": {
            "description": "Update Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "success": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Webhooks"
        ],
        "description": "This requests updates a Webhook.\n\nParameter\nType\nRequired?\nDescription\n\nendpoint\nURL\nOptional\nThe webhook URL.\n\ntype\nString\nOptional\nThe type of webhook. Refer to GET webhooks for type values\n\nenabled\nInt\nOptional\nEnable (1) or disable a webhook(0)",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "endpoint": {
                    "type": "string",
                    "format": "uri"
                  },
                  "type": {
                    "type": "string"
                  },
                  "enabled": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "endpoint": "https://hello123wf",
                "type": "task",
                "enabled": 0
              }
            }
          }
        }
      }
    },
    "/v2/uom": {
      "get": {
        "operationId": "getUom",
        "summary": "Get Units",
        "parameters": [
          {
            "name": "unitCodes",
            "in": "query",
            "description": "This parameter is used to only get specific units. This parameter accepts a comma delimited list of unit codes.",
            "schema": {
              "type": "string"
            },
            "example": "fluid_ounce_us, W0gzuwOpmOo_dXKtrc2RL"
          },
          {
            "name": "limit",
            "in": "query",
            "description": "This parameter is a result limiter. The default is 20 units. Supports up to 1000 results.",
            "schema": {
              "type": "integer"
            },
            "example": 10
          },
          {
            "name": "page",
            "in": "query",
            "description": "This parameter is used to paginate results based on the limit. Refer to Pagination section for more information. ",
            "schema": {
              "type": "integer"
            },
            "example": 2
          },
          {
            "name": "nameStartsWith",
            "in": "query",
            "description": "Filter by units that have a name which starts with this string.",
            "schema": {
              "type": "string"
            },
            "example": "p"
          },
          {
            "name": "abbreviationStartsWith",
            "in": "query",
            "description": "Filter by units that have an abbreviation which starts with this string.",
            "schema": {
              "type": "string"
            },
            "example": "l"
          }
        ],
        "responses": {
          "200": {
            "description": "Get Units of Measure",
            "headers": {
              "x-ratelimit-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "4000"
              },
              "x-ratelimit-minute-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "360"
              },
              "x-ratelimit-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "3993"
              },
              "x-ratelimit-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1734557517"
              },
              "x-ratelimit-minute-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "358"
              },
              "x-ratelimit-minute-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1734558279"
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "example": "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "unitCode": {
                        "type": "string"
                      },
                      "defaultAbbreviation": {
                        "type": "string"
                      },
                      "abbreviation": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "isCustom": {
                        "type": "boolean"
                      },
                      "category": {
                        "type": "string"
                      }
                    }
                  }
                },
                "example": [
                  {
                    "unitCode": "gallon_us",
                    "defaultAbbreviation": "gal",
                    "abbreviation": "gal",
                    "name": "Gallon",
                    "isCustom": false,
                    "category": "volume"
                  },
                  {
                    "unitCode": "milliliter",
                    "defaultAbbreviation": "mL",
                    "abbreviation": "mL",
                    "name": "Milliliter",
                    "isCustom": false,
                    "category": "volume"
                  },
                  {
                    "unitCode": "meter",
                    "defaultAbbreviation": "m",
                    "abbreviation": "m",
                    "name": "Meter",
                    "isCustom": false,
                    "category": "length"
                  },
                  {
                    "unitCode": "inch",
                    "defaultAbbreviation": "in",
                    "abbreviation": "in",
                    "name": "Inch",
                    "isCustom": false,
                    "category": "length"
                  },
                  {
                    "unitCode": "foot",
                    "defaultAbbreviation": "ft",
                    "abbreviation": "ft",
                    "name": "Foot",
                    "isCustom": false,
                    "category": "length"
                  },
                  {
                    "unitCode": "centimeter",
                    "defaultAbbreviation": "cm",
                    "abbreviation": "cm",
                    "name": "Centimeter",
                    "isCustom": false,
                    "category": "length"
                  },
                  {
                    "unitCode": "box",
                    "defaultAbbreviation": "box",
                    "abbreviation": "BoX",
                    "name": "Box",
                    "isCustom": false,
                    "category": "count"
                  },
                  {
                    "unitCode": "case",
                    "defaultAbbreviation": "case",
                    "abbreviation": "case",
                    "name": "Case",
                    "isCustom": false,
                    "category": "count"
                  },
                  {
                    "unitCode": "drum",
                    "defaultAbbreviation": "drum",
                    "abbreviation": "drum",
                    "name": "Drum",
                    "isCustom": false,
                    "category": "count"
                  },
                  {
                    "unitCode": "milligram",
                    "defaultAbbreviation": "mg",
                    "abbreviation": "mg",
                    "name": "Milligram",
                    "isCustom": false,
                    "category": "weight"
                  }
                ]
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Units of Measure"
        ],
        "description": "This endpoint makes an HTTP GET request to retrieve the unit of measurement (UOM) data. The response of this request is documented as a JSON schema.\n\nReturn data description\n\n| **Property** | **Description** |\n| --- | --- |\n| unitCode | The identifier of this unit of measure. It is some random text for custom units (e.g. `j5VEKvW-TD8femkRe02KV`) and it is something semantic for provided units (e.g. `fluid_ounce`) |\n| name | The full name of a unit to make it clear what it is. |\n| abbreviation | The abbreviated name of a unit that is used for compact formatting such as `fl oz`. Can override the default abbreviation of a provided unit. E.g. if the default abbreviation of fluid ounce is `fl oz`, you can make it `oz.` |\n| defaultAbbreviation | This is always the same as abbreviation for custom units. For provided units, this never changes. If you choose to alias the abbreviation, this will show the original, and the abbreivation property will be your alias. |\n| category | Also known as the \"physical quantity\" of a unit, which tells you what exactly this is measuring. The possibilities are `volume`, `weight`, `length`, `count`. All custom units will have the category of `count`, as there is no way to setup custom conversion rates. |\n| isCustom | Boolean which tells you if this is a custom unit or provided unit. |"
      },
      "post": {
        "operationId": "postUom",
        "summary": "Create Unit",
        "responses": {
          "201": {
            "description": "Create Custom Unit",
            "headers": {
              "x-ratelimit-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "1000"
              },
              "x-ratelimit-minute-limit": {
                "schema": {
                  "type": "integer"
                },
                "example": "240"
              },
              "x-ratelimit-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "999"
              },
              "x-ratelimit-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1734559351"
              },
              "x-ratelimit-minute-remaining": {
                "schema": {
                  "type": "integer"
                },
                "example": "239"
              },
              "x-ratelimit-minute-first-call": {
                "schema": {
                  "type": "integer"
                },
                "example": "1734559351"
              },
              "Cache-Control": {
                "schema": {
                  "type": "string"
                },
                "example": "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "unitCode": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "abbreviation": {
                      "type": "string"
                    },
                    "defaultAbbreviation": {
                      "type": "string"
                    },
                    "category": {
                      "type": "string"
                    },
                    "isCustom": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "unitCode": "JXGOdSI45mJ4oRXElEWgu",
                  "name": "Crate",
                  "abbreviation": "crt",
                  "defaultAbbreviation": "crt",
                  "category": "count",
                  "isCustom": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Units of Measure"
        ],
        "description": "The `POST /v2/uom` endpoint is used to create a new custom unit. The request should include a JSON payload with the `name` and `abbreviation` fields.\n\n### Request Body\n\n- `name` (string): The full name of the unit.\n    \n- `abbreviation` (string): A compact name of the unit.\n    \n\n### Response\n\nThe full unit object of your newly created unit.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "abbreviation": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "name": "Crate",
                "abbreviation": "crt"
              }
            }
          }
        }
      }
    },
    "/v2/uom/{unitCode}": {
      "patch": {
        "operationId": "patchUomByUnitCode",
        "summary": "Update Unit",
        "responses": {
          "200": {
            "description": "Update Custom Unit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "unitCode": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "abbreviation": {
                      "type": "string"
                    },
                    "defaultAbbreviation": {
                      "type": "string"
                    },
                    "category": {
                      "type": "string"
                    },
                    "isCustom": {
                      "type": "boolean"
                    }
                  }
                },
                "example": {
                  "unitCode": "E979vVp936_8kV0amzLre",
                  "name": "Barrel",
                  "abbreviation": "BRL",
                  "defaultAbbreviation": "BRL",
                  "category": "count",
                  "isCustom": true
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          }
        },
        "tags": [
          "Routes",
          "Units of Measure"
        ],
        "description": "The HTTP PATCH request is used to update a specific unit identified by its unit code. The request should be made to the endpoint `{{protocol}}://{{server}}:{{port}}/v2/uom/:unitCode`, where `:unitCode` is the unique identifier of the unit being updated.\n\n### Request Body\n\nThe body is interpreted slightly differently, depending on whether the `unitCode` in the url is for a custom unit or a provided unit. If it is custom, then either property can be used to update the unit. If it is a provided unit, the `name` property will be ignored and only the `abbreviation` property will be used to override the defaut one. You can also use `null` to remove the override from the provided unit. If either property is `null` for a custom unit, that property will not be updated.\n\nThe request should include a JSON payload with the following parameters:\n\n- `name` (string): The full name of the unit.\n    \n- `abbreviation` (string): A compact name of the unit.\n    \n\n### Response\n\nThe full object of the updated unit.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "abbreviation": {
                    "type": "string"
                  }
                }
              },
              "example": {
                "name": "Barrel",
                "abbreviation": "BRL"
              }
            }
          }
        }
      },
      "parameters": [
        {
          "name": "unitCode",
          "in": "path",
          "required": true,
          "description": "The unit identifier.",
          "schema": {
            "type": "string"
          },
          "example": "E979vVp936_8kV0amzLre"
        }
      ]
    }
  },
  "components": {
    "schemas": {
      "DropdownOption": {
        "type": "object",
        "description": "A single option in a Dropdown custom field.",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "maxLength": 255,
            "description": "The display name of the dropdown option."
          }
        }
      },
      "ErrorResponse": {
        "description": "Error response body. The API emits two shapes today: the standard `{ message }` shape returned by the central error handler and most controllers, and the legacy `{ error, success, msg }` shape returned by the auth middleware. Some controllers also include extra fields (e.g. `success`, conflict metadata).",
        "oneOf": [
          {
            "type": "object",
            "required": [
              "message"
            ],
            "properties": {
              "message": {
                "type": "string"
              },
              "success": {
                "type": "boolean"
              },
              "raw": {
                "description": "Optional raw error object (validation errors)."
              }
            }
          },
          {
            "type": "object",
            "required": [
              "error",
              "msg"
            ],
            "properties": {
              "error": {
                "type": "integer",
                "description": "Numeric HTTP status echoed in the body."
              },
              "success": {
                "type": "boolean"
              },
              "msg": {
                "type": "string"
              }
            }
          }
        ]
      },
      "Asset": {
        "type": "object",
        "properties": {
          "assetID": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "startedOn": {
            "type": "integer"
          },
          "lastEdited": {
            "type": "integer"
          },
          "parentAssetID": {
            "type": "integer"
          },
          "locationID": {
            "type": "integer"
          },
          "hoursPerWeek": {
            "type": "integer"
          },
          "meta": {
            "type": "object",
            "properties": {
              "fields": {
                "type": "string"
              },
              "tasks": {
                "type": "string"
              }
            }
          },
          "workRequestPortal": {
            "type": "string",
            "format": "uri"
          },
          "image": {
            "type": "array"
          }
        }
      },
      "Bill": {
        "type": "object",
        "properties": {
          "billID": {
            "type": "integer"
          },
          "poID": {
            "type": "integer"
          },
          "status": {
            "type": "integer"
          },
          "userID": {
            "type": "integer"
          },
          "userIDStarted": {
            "type": "integer"
          },
          "userIDMarkPaid": {
            "type": "integer"
          },
          "billNumber": {
            "type": "integer"
          },
          "locationID": {
            "type": "integer"
          },
          "date": {
            "type": "integer"
          },
          "meta": {
            "type": "object",
            "properties": {
              "items": {
                "type": "string"
              },
              "po": {
                "type": "string"
              },
              "transactions": {
                "type": "string"
              }
            }
          }
        }
      },
      "Budget": {
        "type": "object",
        "properties": {
          "budgetID": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "locationID": {
            "type": "integer"
          },
          "awaitingAllowPOEdit": {
            "type": "boolean"
          },
          "awaitingUserID": {
            "type": "integer"
          },
          "awaitingProfileID": {
            "type": "integer"
          },
          "awaitingEmailSend": {
            "type": "boolean"
          },
          "prUserID": {
            "type": "integer"
          },
          "prProfileID": {
            "type": "integer"
          },
          "prEmailSend": {
            "type": "boolean"
          },
          "defaultBudget": {
            "type": "object",
            "properties": {
              "global": {
                "type": "boolean"
              },
              "purchaseRequests": {
                "type": "boolean"
              },
              "minPartQtyPOs": {
                "type": "boolean"
              }
            }
          },
          "meta": {
            "type": "object",
            "properties": {
              "steps": {
                "type": "string"
              },
              "location": {
                "type": "string"
              }
            }
          }
        }
      },
      "Location": {
        "type": "object",
        "properties": {
          "locationID": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "regionID": {
            "type": "integer"
          },
          "timezone": {
            "type": "string"
          },
          "weeklyOperationHours": {
            "type": "integer"
          },
          "address": {
            "type": "null"
          },
          "address2": {
            "type": "null"
          },
          "phone": {
            "type": "null"
          },
          "metaField1": {
            "type": "null"
          },
          "metaField2": {
            "type": "null"
          },
          "metaField3": {
            "type": "null"
          },
          "geoLocation": {
            "type": "null"
          },
          "workRequestPortal": {
            "type": "string",
            "format": "uri"
          },
          "currencyCode": {
            "type": "string"
          }
        }
      },
      "POItem": {
        "type": "object",
        "properties": {
          "poID": {
            "type": "integer"
          },
          "poItemID": {
            "type": "integer"
          },
          "itemType": {
            "type": "integer"
          },
          "name": {
            "type": "null"
          },
          "description": {
            "type": "null"
          },
          "glID": {
            "type": "integer"
          },
          "partID": {
            "type": "integer"
          },
          "taskID": {
            "type": "integer"
          },
          "poNumber": {
            "type": "integer"
          },
          "qty": {
            "type": "integer"
          },
          "rate": {
            "type": "integer"
          },
          "tax": {
            "type": "integer"
          },
          "discount": {
            "type": "integer"
          },
          "shipping": {
            "type": "integer"
          },
          "qtyReceived": {
            "type": "integer"
          },
          "orderUnitAbbreviation": {
            "type": "null"
          },
          "lastEdited": {
            "type": "integer"
          },
          "meta": {
            "type": "object",
            "properties": {
              "po": {
                "type": "string"
              }
            }
          }
        }
      },
      "Part": {
        "type": "object",
        "properties": {
          "partID": {
            "type": "integer"
          },
          "number": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "generalStock": {
            "type": "integer"
          },
          "unitCode": {
            "type": "string"
          },
          "generalPrice": {
            "type": "number"
          },
          "category": {
            "type": "string"
          },
          "categoryID": {
            "type": "integer"
          },
          "locationID": {
            "type": "integer"
          },
          "location": {
            "type": "string"
          },
          "minQtyStatus": {
            "type": "integer"
          },
          "minQtyThreshold": {
            "type": "integer"
          },
          "maxQtyThreshold": {
            "type": "integer"
          },
          "staleThreshold": {
            "type": "integer"
          },
          "staleStatus": {
            "type": "integer"
          },
          "lastEdited": {
            "type": "integer"
          },
          "userID": {
            "type": "integer"
          },
          "teamID": {
            "type": "integer"
          },
          "stockOnHand": {
            "type": "integer"
          },
          "pos": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "quantity": {
                  "type": "integer"
                },
                "quantityUsed": {
                  "type": "integer"
                },
                "price": {
                  "type": "number"
                },
                "poItemID": {
                  "type": "integer"
                }
              }
            }
          },
          "image": {
            "type": "array"
          }
        }
      },
      "PurchaseOrder": {
        "type": "object",
        "properties": {
          "poID": {
            "type": "integer"
          },
          "taskID": {
            "type": "integer"
          },
          "budgetID": {
            "type": "integer"
          },
          "poNumber": {
            "type": "integer"
          },
          "vendorID": {
            "type": "integer"
          },
          "locationID": {
            "type": "integer"
          },
          "userIDStarted": {
            "type": "integer"
          },
          "userID": {
            "type": "integer"
          },
          "teamID": {
            "type": "integer"
          },
          "requestedByUserID": {
            "type": "integer"
          },
          "date": {
            "type": "integer"
          },
          "expectedDate": {
            "type": "null"
          },
          "notesToVendor": {
            "type": "string"
          },
          "billTo": {
            "type": "null"
          },
          "shipTo": {
            "type": "null"
          },
          "status": {
            "type": "integer"
          },
          "customField1": {
            "type": "null"
          },
          "customField2": {
            "type": "null"
          },
          "customField3": {
            "type": "null"
          },
          "customField4": {
            "type": "null"
          },
          "customField5": {
            "type": "null"
          },
          "customField6": {
            "type": "null"
          },
          "lastEdited": {
            "type": "integer"
          },
          "poPrefix": {
            "type": "null"
          },
          "meta": {
            "type": "object",
            "properties": {
              "items": {
                "type": "string"
              },
              "state": {
                "type": "string"
              },
              "stateTransitions": {
                "type": "string"
              },
              "budget": {
                "type": "string"
              },
              "budgetSteps": {
                "type": "string"
              }
            }
          },
          "stateDetails": {
            "type": "object",
            "properties": {
              "current": {
                "type": "object",
                "properties": {
                  "number": {
                    "type": "integer"
                  },
                  "name": {
                    "type": "string"
                  },
                  "label": {
                    "type": "string"
                  },
                  "canModify": {
                    "type": "boolean"
                  }
                }
              },
              "transitions": {
                "type": "object",
                "properties": {
                  "available": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "state": {
                          "type": "integer"
                        },
                        "name": {
                          "type": "string"
                        },
                        "label": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "state": {
            "type": "integer"
          }
        }
      },
      "Task": {
        "type": "object",
        "properties": {
          "meta": {
            "type": "object",
            "properties": {
              "invoices": {
                "type": "string"
              },
              "labor": {
                "type": "string"
              },
              "partsUsage": {
                "type": "string"
              },
              "instructions": {
                "type": "string"
              },
              "status": {
                "type": "string"
              }
            }
          },
          "taskID": {
            "type": "integer"
          },
          "poIDs": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "name": {
            "type": "string"
          },
          "userID": {
            "type": "integer"
          },
          "teamID": {
            "type": "integer"
          },
          "locationID": {
            "type": "integer"
          },
          "template": {
            "type": "boolean"
          },
          "createdDate": {
            "type": "integer"
          },
          "scheduledStart": {
            "type": "integer"
          },
          "scheduledEnd": {
            "type": "integer"
          },
          "due": {
            "type": "integer"
          },
          "description": {
            "type": "string"
          },
          "dateCompleted": {
            "type": "integer"
          },
          "lastEdited": {
            "type": "integer"
          },
          "lastEditedByUser": {
            "type": "integer"
          },
          "completedByUser": {
            "type": "integer"
          },
          "assetID": {
            "type": "integer"
          },
          "completedUserWage": {
            "type": "integer"
          },
          "priority": {
            "type": "integer"
          },
          "priorityID": {
            "type": "integer"
          },
          "downtime": {
            "type": "integer"
          },
          "completionNotes": {
            "type": "null"
          },
          "requestorName": {
            "type": "null"
          },
          "requestorEmail": {
            "type": "null"
          },
          "requestorPhone": {
            "type": "null"
          },
          "requestTitle": {
            "type": "null"
          },
          "requestField1": {
            "type": "null"
          },
          "requestField2": {
            "type": "null"
          },
          "requestField3": {
            "type": "null"
          },
          "requestDropdown1": {
            "type": "null"
          },
          "requestDropdown2": {
            "type": "null"
          },
          "requestDropdown3": {
            "type": "null"
          },
          "requestorDescription": {
            "type": "null"
          },
          "meta1": {
            "type": "null"
          },
          "meta2": {
            "type": "null"
          },
          "meta3": {
            "type": "null"
          },
          "statusID": {
            "type": "integer"
          },
          "type": {
            "type": "integer"
          },
          "status": {
            "type": "integer"
          }
        }
      },
      "User": {
        "type": "object",
        "properties": {
          "userID": {
            "type": "integer"
          },
          "username": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string",
            "format": "utc-millisec"
          },
          "firstName": {
            "type": "string"
          },
          "lastName": {
            "type": "string"
          },
          "wage": {
            "type": "integer"
          },
          "active": {
            "type": "string"
          },
          "emailNotificationActive": {
            "type": "string"
          },
          "pushNotificationActive": {
            "type": "string"
          },
          "workdayHours": {
            "type": "integer"
          },
          "dateAdded": {
            "type": "integer"
          },
          "teams": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "teamID": {
                  "type": "integer"
                },
                "locationID": {
                  "type": "integer"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          },
          "roles": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "roleID": {
                  "type": "integer"
                },
                "locationID": {
                  "type": "integer"
                },
                "name": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "Vendor": {
        "type": "object",
        "properties": {
          "meta": {
            "type": "object",
            "properties": {
              "fields": {
                "type": "string"
              }
            }
          },
          "vendorID": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "email": {
            "type": "string",
            "format": "email"
          },
          "phone": {
            "type": "string"
          },
          "contact": {
            "type": "string"
          },
          "address": {
            "type": "string"
          },
          "locationID": {
            "type": "integer"
          },
          "startedOn": {
            "type": "integer"
          },
          "lastEdited": {
            "type": "integer"
          },
          "image": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "fileName": {
                  "type": "string"
                },
                "link": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        }
      },
      "Me": {
        "type": "object",
        "properties": {
          "customerName": {
            "type": "string"
          },
          "customerPlan": {
            "type": "string",
            "enum": [
              "starter",
              "professional",
              "business",
              "enterprise",
              "legacy"
            ]
          }
        }
      },
      "LogEntry": {
        "type": "object",
        "properties": {
          "logID": {
            "type": "integer"
          },
          "dateCreated": {
            "type": "integer"
          },
          "logEntry": {
            "type": "string"
          },
          "userID": {
            "type": "integer"
          },
          "logFiles": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "fileID": {
                  "type": "integer"
                },
                "fileName": {
                  "type": "string"
                },
                "link": {
                  "type": "string",
                  "format": "uri"
                }
              }
            }
          }
        }
      },
      "PartLogEntry": {
        "type": "object",
        "properties": {
          "logID": {
            "type": "integer"
          },
          "dateCreated": {
            "type": "integer"
          },
          "partID": {
            "type": "integer"
          },
          "sourceID": {
            "type": "integer"
          },
          "logEntry": {
            "type": "string"
          },
          "userID": {
            "type": "integer"
          },
          "associatedID": {
            "type": "integer"
          }
        }
      },
      "AssetPart": {
        "type": "object",
        "properties": {
          "relationID": {
            "type": "integer"
          },
          "partID": {
            "type": "integer"
          },
          "assetID": {
            "type": "integer"
          },
          "qty": {
            "type": "integer"
          },
          "createdAt": {
            "type": "integer"
          },
          "lastEdited": {
            "type": "integer"
          },
          "associationType": {
            "type": "string"
          }
        }
      },
      "BudgetStep": {
        "type": "object",
        "properties": {
          "stepID": {
            "type": "integer"
          },
          "budgetID": {
            "type": "integer"
          },
          "name": {
            "type": "string"
          },
          "sortOrder": {
            "type": "integer"
          }
        }
      },
      "TaskInstruction": {
        "type": "object",
        "properties": {
          "instructionID": {
            "type": "integer"
          },
          "taskID": {
            "type": "integer"
          },
          "parentInstructionID": {
            "type": "integer"
          },
          "instruction": {
            "type": "string"
          },
          "type": {
            "type": "integer"
          },
          "options": {
            "type": "array"
          },
          "response": {
            "type": "boolean"
          },
          "instructionFiles": {
            "type": "array"
          }
        }
      },
      "WorkRequestSubmission": {
        "type": "object",
        "properties": {
          "workRequestSubmissionId": {
            "type": "integer"
          },
          "status": {
            "type": "string",
            "enum": [
              "Pending",
              "Approved",
              "Rejected"
            ]
          },
          "createdByUserId": {
            "type": "integer"
          },
          "createdAt": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          },
          "deletedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "reviewedByUserId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "reviewedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "reviewedReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "additionalNotes": {
            "type": [
              "string",
              "null"
            ]
          },
          "locationId": {
            "type": "integer"
          },
          "assetId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "priorityId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "dueDateUnit": {
            "type": [
              "string",
              "null"
            ]
          },
          "requestInformation": {
            "type": "object"
          },
          "customerID": {
            "type": "integer"
          },
          "requestTitle": {
            "type": "string"
          },
          "assignedToProfileId": {
            "type": [
              "integer",
              "null"
            ]
          },
          "requestDescription": {
            "type": [
              "string",
              "null"
            ]
          },
          "checklistID": {
            "type": [
              "integer",
              "null"
            ]
          },
          "requesterName": {
            "type": "string"
          }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "The request was malformed — either invalid JSON syntax or a validation failure (missing required field, wrong type, etc.).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Unauthorized": {
        "description": "No `Authorization` header was provided on the request.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "The supplied credentials are invalid, the customer account is inactive, or the credentials do not have permission to perform this action.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "The referenced resource does not exist or is not visible to the authenticated customer.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "Conflict": {
        "description": "The request conflicts with the current state of the resource (e.g. a uniqueness constraint or a referenced parent that is in the wrong state).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "The per-minute or per-hour rate limit for this credential and method has been exhausted. Inspect the `X-RateLimit-*` headers to determine when to retry.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "InternalServerError": {
        "description": "An unhandled server-side error. The body message is generic (`System unavailable...`) when the underlying cause is a database fault; otherwise it reflects the raised error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "AssociationNotFound": {
        "description": "The vendor-part association does not exist.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "status": {
                  "type": "integer"
                },
                "error": {
                  "type": "string"
                }
              }
            },
            "example": {
              "status": 404,
              "error": "Vendor-part association not found"
            }
          }
        }
      },
      "ValidationLimitExceeded": {
        "description": "A query parameter exceeds its allowed maximum (e.g. limit greater than 100).",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "error": {
                  "type": "object",
                  "properties": {
                    "status": {
                      "type": "integer"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            },
            "example": {
              "error": {
                "status": 400,
                "message": "\"limit\" must be less than or equal to 100"
              }
            }
          }
        }
      },
      "InvalidStateTransition": {
        "description": "The requested state transition is not allowed from the resource's current state.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": {
                "success": {
                  "type": "boolean"
                },
                "message": {
                  "type": "string"
                }
              }
            },
            "example": {
              "success": false,
              "message": "Transition not allowed from current state"
            }
          }
        }
      },
      "EmptySuccess": {
        "description": "The operation completed successfully. The response body is empty."
      }
    },
    "securitySchemes": {
      "BasicAuth": {
        "type": "http",
        "scheme": "basic"
      }
    }
  }
}