{
  "openapi": "3.1.1",
  "info": {
    "title": "Everhour API",
    "version": "1.0.0",
    "license": {
      "name": "Proprietary",
      "identifier": "LicenseRef-Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://api.everhour.com"
    }
  ],
  "tags": [
    {
      "name": "Clients"
    },
    {
      "name": "Custom Fields"
    },
    {
      "name": "Expenses"
    },
    {
      "name": "Invoices"
    },
    {
      "name": "Projects"
    },
    {
      "name": "Reports"
    },
    {
      "name": "Schedule"
    },
    {
      "name": "Tasks"
    },
    {
      "name": "Time Off"
    },
    {
      "name": "Time Records"
    },
    {
      "name": "Timecards"
    },
    {
      "name": "Timers"
    },
    {
      "name": "Timesheets"
    },
    {
      "name": "Users"
    },
    {
      "name": "Webhooks"
    }
  ],
  "paths": {
    "/clients": {
      "get": {
        "tags": [
          "Clients"
        ],
        "summary": "Get All Clients",
        "description": "Search Clients by Name using the query parameter.",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Search Clients by Name",
            "schema": {
              "type": "string",
              "example": "Vending Inc"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Client"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllClients"
      },
      "post": {
        "tags": [
          "Clients"
        ],
        "summary": "Create Client",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createClient",
        "description": "Create a new client. Names are not deduplicated — posting the same name creates another client."
      }
    },
    "/clients/{client_id}": {
      "get": {
        "tags": [
          "Clients"
        ],
        "summary": "Get Client",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "description": "Client ID",
            "schema": {
              "type": "number",
              "example": 107
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getClient",
        "description": "Retrieve a single client by ID."
      },
      "put": {
        "tags": [
          "Clients"
        ],
        "summary": "Update Client",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "description": "Client ID",
            "schema": {
              "type": "number",
              "example": 107
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateClient",
        "description": "Update an existing client. Only the fields supplied in the body are modified."
      },
      "delete": {
        "tags": [
          "Clients"
        ],
        "summary": "Delete Client",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "description": "Client ID",
            "schema": {
              "type": "number",
              "example": 107
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteClient",
        "description": "Delete a client."
      }
    },
    "/clients/{client_id}/budget": {
      "put": {
        "tags": [
          "Clients"
        ],
        "summary": "Update Client Budget",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "description": "Client ID",
            "schema": {
              "type": "number",
              "example": 107
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ClientBudget"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateClientBudget",
        "description": "Create or replace the budget attached to a client. Send a complete budget object; partial updates are not supported."
      },
      "delete": {
        "tags": [
          "Clients"
        ],
        "summary": "Delete Client Budget",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "description": "Client ID",
            "schema": {
              "type": "number",
              "example": 107
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Client"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteClientBudget",
        "description": "Remove the budget attached to a client. The client itself is kept."
      }
    },
    "/projects/{project_id}/fields": {
      "get": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Get Project Fields Configuration",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Field"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getProjectFieldsConfiguration",
        "description": "List the custom fields configured on a project, in display order."
      },
      "post": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Create Field in Project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Field"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createFieldInProject",
        "description": "Create a new custom field on a project."
      }
    },
    "/fields/{field_id}": {
      "put": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Update Field",
        "parameters": [
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "description": "Field ID",
            "schema": {
              "type": "number",
              "example": 4456411
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Field"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateField",
        "description": "Update a custom field's name, type-specific options, or visibility."
      },
      "delete": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Delete Field",
        "parameters": [
          {
            "name": "field_id",
            "in": "path",
            "required": true,
            "description": "Field ID",
            "schema": {
              "type": "number",
              "example": 4456411
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteField",
        "description": "Delete a custom field. Existing task values for that field are discarded."
      }
    },
    "/projects/{project_id}/fields-order": {
      "put": {
        "tags": [
          "Custom Fields"
        ],
        "summary": "Reorder Fields",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/FieldOrderRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "reorderFields",
        "description": "Reorder a project's custom fields. Send the full list of field IDs in the desired order."
      }
    },
    "/expenses": {
      "get": {
        "tags": [
          "Expenses"
        ],
        "summary": "Get All Expenses",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Expense"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllExpenses",
        "description": "List expenses logged by the authenticated user."
      },
      "post": {
        "tags": [
          "Expenses"
        ],
        "summary": "Create Expense",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Expense"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createExpense",
        "description": "Log a new expense. Amounts are in cents (see [Concepts](/concepts)); attach files first via `POST /attachments` and reference their IDs in the request body."
      }
    },
    "/expenses/{expense_id}": {
      "put": {
        "tags": [
          "Expenses"
        ],
        "summary": "Update Expense",
        "parameters": [
          {
            "name": "expense_id",
            "in": "path",
            "required": true,
            "description": "Expense ID",
            "schema": {
              "type": "number",
              "example": 7810
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Expense"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateExpense",
        "description": "Update an existing expense entry."
      },
      "delete": {
        "tags": [
          "Expenses"
        ],
        "summary": "Delete Expense",
        "parameters": [
          {
            "name": "expense_id",
            "in": "path",
            "required": true,
            "description": "Expense ID",
            "schema": {
              "type": "number",
              "example": 7810
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteExpense",
        "description": "Delete an expense entry. Attached files are also removed."
      }
    },
    "/expenses/categories": {
      "get": {
        "tags": [
          "Expenses"
        ],
        "summary": "Get All Categories",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ExpenseCategory"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllCategories",
        "description": "List expense categories available in the team."
      },
      "post": {
        "tags": [
          "Expenses"
        ],
        "summary": "Create Category",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseCategoryRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseCategory"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createCategory",
        "description": "Create a new expense category."
      }
    },
    "/expenses/categories/{category_id}": {
      "put": {
        "tags": [
          "Expenses"
        ],
        "summary": "Update Category",
        "parameters": [
          {
            "name": "category_id",
            "in": "path",
            "required": true,
            "description": "Expense Category ID",
            "schema": {
              "type": "number",
              "example": 94
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ExpenseCategoryRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ExpenseCategory"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateCategory",
        "description": "Update an expense category."
      },
      "delete": {
        "tags": [
          "Expenses"
        ],
        "summary": "Delete Category",
        "parameters": [
          {
            "name": "category_id",
            "in": "path",
            "required": true,
            "description": "Expense Category ID",
            "schema": {
              "type": "number",
              "example": 94
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteCategory",
        "description": "Delete an expense category. Expenses already assigned to it are kept but become uncategorized.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "targetCategory": {
                    "type": "integer",
                    "description": "Move this category's expenses to the given category ID."
                  },
                  "removeExpenses": {
                    "type": "boolean",
                    "description": "Delete the category's expenses instead of reassigning them.",
                    "example": false
                  }
                }
              }
            }
          }
        }
      }
    },
    "/attachments": {
      "post": {
        "tags": [
          "Expenses"
        ],
        "summary": "Create Attachment",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttachmentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createAttachment",
        "description": "Upload a file and receive a one-time attachment token. The token can then be attached to an expense via `POST /expenses/{expense_id}/attachments` or included in `POST /expenses`."
      }
    },
    "/expenses/{expense_id}/attachments": {
      "post": {
        "tags": [
          "Expenses"
        ],
        "summary": "Add Attachment To Expense",
        "parameters": [
          {
            "name": "expense_id",
            "in": "path",
            "required": true,
            "description": "Expense ID",
            "schema": {
              "type": "number",
              "example": 7810
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AttachmentRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AttachmentDetails"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "addAttachmentToExpense",
        "description": "Attach a previously uploaded file (by its token from `POST /attachments`) to an existing expense."
      }
    },
    "/attachments/{attachment_token}/download": {
      "get": {
        "tags": [
          "Expenses"
        ],
        "summary": "Download Attachment",
        "parameters": [
          {
            "name": "attachment_token",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "example": "aaaabbbbcccddd.eeefff"
            }
          },
          {
            "name": "inline",
            "in": "query",
            "required": false,
            "description": "Set to `1` to serve the file inline (`Content-Disposition: inline`) instead of as an attachment.",
            "schema": {
              "type": "boolean",
              "example": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK. The `Content-Type` header reflects the uploaded file type.",
            "content": {
              "application/octet-stream": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "downloadAttachment",
        "description": "Download the binary contents of an attachment by its token. The response is the raw file, not JSON."
      }
    },
    "/attachments/{attachment_id}": {
      "delete": {
        "tags": [
          "Expenses"
        ],
        "summary": "Delete Attachment",
        "parameters": [
          {
            "name": "attachment_id",
            "in": "path",
            "required": true,
            "description": "Attachment ID",
            "schema": {
              "type": "number",
              "example": 3905
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteAttachment",
        "description": "Delete an attachment and its underlying file."
      }
    },
    "/invoices": {
      "get": {
        "tags": [
          "Invoices"
        ],
        "summary": "Get All Invoices",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Invoice"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllInvoices",
        "description": "List invoices in the team. Supports filtering by date and client."
      }
    },
    "/invoices/{invoice_id}": {
      "get": {
        "tags": [
          "Invoices"
        ],
        "summary": "Get Invoice",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "description": "Invoice ID",
            "schema": {
              "type": "number",
              "example": 11903
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getInvoice",
        "description": "Retrieve a single invoice with its full line-item breakdown."
      },
      "put": {
        "tags": [
          "Invoices"
        ],
        "summary": "Update Invoice",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "description": "Invoice ID",
            "schema": {
              "type": "number",
              "example": 11903
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateInvoice",
        "description": "Update invoice metadata (notes, dates, custom totals). To change the lifecycle state, set `manualStatus` to `draft`, `sent`, or `paid`."
      },
      "delete": {
        "tags": [
          "Invoices"
        ],
        "summary": "Delete Invoice",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "description": "Invoice ID",
            "schema": {
              "type": "number",
              "example": 11903
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteInvoice",
        "description": "Delete an invoice. Time records attached to the invoice are released and become billable again."
      }
    },
    "/clients/{client_id}/invoices": {
      "post": {
        "tags": [
          "Invoices"
        ],
        "summary": "Create Invoice",
        "parameters": [
          {
            "name": "client_id",
            "in": "path",
            "required": true,
            "description": "Client ID",
            "schema": {
              "type": "number",
              "example": 107
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createInvoice",
        "description": "Create an invoice for a client. The invoice is generated from the client's tracked time over the requested date range — see [Dates](/dates-and-timezones)."
      }
    },
    "/invoices/{invoice_id}/reset-time": {
      "post": {
        "tags": [
          "Invoices"
        ],
        "summary": "Refresh Invoice Line Items",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "description": "Invoice ID",
            "schema": {
              "type": "number",
              "example": 11903
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/InvoiceRefreshRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "refreshInvoiceLineItems",
        "description": "Refresh an invoice's line items from current time records.\n\nThe invoice's billable items are rebuilt from the underlying time tracked against the invoice's client over its date range. Useful when time records have been added, edited, or deleted after the invoice was first generated."
      }
    },
    "/invoices/{invoice_id}/export": {
      "post": {
        "tags": [
          "Invoices"
        ],
        "summary": "Export Invoice to Xero/QB/FB",
        "parameters": [
          {
            "name": "invoice_id",
            "in": "path",
            "required": true,
            "description": "Invoice ID",
            "schema": {
              "type": "number",
              "example": 11903
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Invoice"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "exportInvoiceToXeroQbFb",
        "description": "Export an invoice to a connected external accounting system.\n\nSupports Xero, QuickBooks, and FreshBooks integrations — the destination must be linked to the team beforehand. An invoice can only be exported once; subsequent calls return an error."
      }
    },
    "/projects": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get All Projects",
        "parameters": [
          {
            "name": "platform",
            "in": "query",
            "required": false,
            "description": "Filter by Integration",
            "schema": {
              "type": "string",
              "enum": [
                "as",
                "ev",
                "b3",
                "b2",
                "pv",
                "gh",
                "in",
                "tr",
                "jr"
              ],
              "example": "as"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Search Projects by Name",
            "schema": {
              "type": "string",
              "example": "Development"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Max Results",
            "schema": {
              "type": "integer",
              "example": 100
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Results page (1-based)",
            "schema": {
              "type": "integer",
              "example": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Project"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllProjects",
        "description": "List projects the caller has access to. Use the `query` parameter to search by name and `limit`/`page` for pagination — see [Pagination](/pagination)."
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Create Project",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createProject",
        "description": "Create a new project. To copy from an existing template use the `template` or `publicTemplate` body field. To sync a project from a connected integration use `POST /projects/{project_id}/sync` instead."
      }
    },
    "/projects/{project_id}": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get Project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "as:1234567789001"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getProject",
        "description": "Retrieve a single project. See [Concepts](/concepts) for the project model."
      },
      "put": {
        "tags": [
          "Projects"
        ],
        "summary": "Update Project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateProject",
        "description": "Update project settings. To change budget or billable rate, use `PUT /projects/{project_id}/billing` instead."
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "summary": "Delete Project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteProject",
        "description": "Delete a project, its tasks, and all associated time records. This is irreversible."
      }
    },
    "/projects/{project_id}/archive": {
      "patch": {
        "tags": [
          "Projects"
        ],
        "summary": "Archive/Unarchive Project",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectArchiveRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "archiveUnarchiveProject",
        "description": "Archive or unarchive a project. Archived projects are hidden from default listings but their data is preserved."
      }
    },
    "/projects/{project_id}/billing": {
      "put": {
        "tags": [
          "Projects"
        ],
        "summary": "Update Project Billing/Budget",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ProjectBilling"
              },
              "examples": {
                "hourlyProject": {
                  "summary": "Hourly project",
                  "value": {
                    "billing": {
                      "type": "hourly"
                    },
                    "budget": {
                      "type": "money",
                      "budget": 50000,
                      "period": "general"
                    },
                    "rate": {
                      "type": "project_rate",
                      "rate": 10000
                    }
                  }
                },
                "fixedFeeProject": {
                  "summary": "Fixed-fee project",
                  "value": {
                    "billing": {
                      "type": "fixed_fee",
                      "fee": 50000
                    },
                    "budget": {
                      "type": "money",
                      "budget": 50000,
                      "period": "general"
                    },
                    "rate": {
                      "type": "user_rate"
                    }
                  }
                },
                "nonBillableProject": {
                  "summary": "Non-billable project",
                  "value": {
                    "billing": {
                      "type": "non_billable"
                    },
                    "budget": {
                      "type": "time",
                      "budget": 360000,
                      "period": "general"
                    }
                  }
                },
                "hourlyWithUserOverrides": {
                  "summary": "Hourly project with user rates overrides",
                  "value": {
                    "billing": {
                      "type": "hourly"
                    },
                    "rate": {
                      "type": "user_rate",
                      "userRateOverrides": {
                        "45038": 10000
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateProjectBillingBudget",
        "description": "Set or update the project's budget, billable rate, and billing type in a single call. Amounts are in cents (see [Concepts](/concepts))."
      }
    },
    "/projects/{project_id}/sections": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get Project Sections",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Section"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getProjectSections",
        "description": "List sections (groupings of tasks) within a project."
      },
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Create Section",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Section"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createSection",
        "description": "Create a new section in a project."
      }
    },
    "/sections/{section_id}": {
      "get": {
        "tags": [
          "Projects"
        ],
        "summary": "Get Section",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "description": "Section ID",
            "schema": {
              "type": "number",
              "example": 349235
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Section"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getSection",
        "description": "Retrieve a single section by ID."
      },
      "put": {
        "tags": [
          "Projects"
        ],
        "summary": "Update Section",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "description": "Section ID",
            "schema": {
              "type": "number",
              "example": 349235
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SectionRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Section"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateSection",
        "description": "Update a section's name or position."
      },
      "delete": {
        "tags": [
          "Projects"
        ],
        "summary": "Delete Section",
        "parameters": [
          {
            "name": "section_id",
            "in": "path",
            "required": true,
            "description": "Section ID",
            "schema": {
              "type": "number",
              "example": 349235
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteSection",
        "description": "Delete a section. Tasks in the section are kept but become section-less.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "preserveTasks": {
                    "type": "boolean",
                    "description": "Keep the section's tasks instead of deleting them.",
                    "example": false
                  },
                  "section": {
                    "type": "integer",
                    "description": "Section ID to move the preserved tasks into."
                  }
                }
              }
            }
          }
        }
      }
    },
    "/projects/{project_id}/sync": {
      "post": {
        "tags": [
          "Projects"
        ],
        "summary": "Sync Integration Project",
        "description": "Sync new integration projects to Everhour.\n\nTraditionally, project sync relied on background jobs which could delay access to Everhour functionality.\n\nThis endpoint allows instant synchronization of a project from a connected integration (like Trello, Asana, ClickUp, etc.) into Everhour.\nUseful for automation flows where you want to start working with a project immediately after creating it in your external tool.\n\nSafe to call multiple times — if the project already exists in Everhour, it simply returns it without creating duplicates.\n\n**Workflow**\n\n- Create a project in your external tool (Asana, Trello, etc.) and retrieve its ID.\n- Sync it to Everhour using this endpoint in Everhour API.\n- Proceed with other Everhour API actions — assign a budget, link a client, or set task estimates.\n\nSupported platform codes:\nas, b2, b3, bb, cl, gh, gl, in, li, mo, no, td, tw, tr, wr.\n",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "The external project ID in the format {platform code}:{platform ID}.",
            "schema": {
              "type": "string",
              "example": "as:1234567789001"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Project"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "syncIntegrationProject"
      }
    },
    "/dashboards/projects": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Projects Report",
        "parameters": [
          {
            "name": "date.gte",
            "in": "query",
            "required": false,
            "description": "Report start date",
            "schema": {
              "type": "string",
              "example": "2020-01-01"
            }
          },
          {
            "name": "date.lte",
            "in": "query",
            "required": false,
            "description": "Report end date",
            "schema": {
              "type": "string",
              "example": "2021-01-01"
            }
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "description": "Filter by project ID",
            "schema": {
              "type": "string",
              "example": "as:123456789012345"
            }
          },
          {
            "name": "clientId",
            "in": "query",
            "required": false,
            "description": "Filter by client ID",
            "schema": {
              "type": "number",
              "example": 12345
            }
          },
          {
            "name": "memberId",
            "in": "query",
            "required": false,
            "description": "Filter by user ID",
            "schema": {
              "type": "number",
              "example": 7890
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ProjectsDashboardItem"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "projectsReport",
        "description": "Aggregated project report.\n\nReturns time, billing, and budget figures grouped by project. Filter the result with `date.gte`, `date.lte`, `projectId`, `clientId`, and `memberId` query parameters — see [Dates](/dates-and-timezones) for parameter formats. Time columns are in seconds, amounts in cents (see [Concepts](/concepts))."
      }
    },
    "/dashboards/clients": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Clients Report",
        "parameters": [
          {
            "name": "date.gte",
            "in": "query",
            "required": false,
            "description": "Report start date",
            "schema": {
              "type": "string",
              "example": "2020-01-01"
            }
          },
          {
            "name": "date.lte",
            "in": "query",
            "required": false,
            "description": "Report end date",
            "schema": {
              "type": "string",
              "example": "2021-01-01"
            }
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "description": "Filter by project ID",
            "schema": {
              "type": "string",
              "example": "as:123456789012345"
            }
          },
          {
            "name": "clientId",
            "in": "query",
            "required": false,
            "description": "Filter by client ID",
            "schema": {
              "type": "number",
              "example": 12345
            }
          },
          {
            "name": "memberId",
            "in": "query",
            "required": false,
            "description": "Filter by user ID",
            "schema": {
              "type": "number",
              "example": 7890
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/ClientsDashboardItem"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "clientsReport",
        "description": "Aggregated client report. Same filters and units as `GET /dashboards/projects` — see [Concepts](/concepts)."
      }
    },
    "/dashboards/users": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Users Report",
        "parameters": [
          {
            "name": "date.gte",
            "in": "query",
            "required": false,
            "description": "Report start date",
            "schema": {
              "type": "string",
              "example": "2020-01-01"
            }
          },
          {
            "name": "date.lte",
            "in": "query",
            "required": false,
            "description": "Report end date",
            "schema": {
              "type": "string",
              "example": "2021-01-01"
            }
          },
          {
            "name": "projectId",
            "in": "query",
            "required": false,
            "description": "Filter by project ID",
            "schema": {
              "type": "string",
              "example": "as:123456789012345"
            }
          },
          {
            "name": "clientId",
            "in": "query",
            "required": false,
            "description": "Filter by client ID",
            "schema": {
              "type": "number",
              "example": 12345
            }
          },
          {
            "name": "memberId",
            "in": "query",
            "required": false,
            "description": "Filter by user ID",
            "schema": {
              "type": "number",
              "example": 7890
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/UsersDashboardItem"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "usersReport",
        "description": "Aggregated member report. Same filters and units as `GET /dashboards/projects` — see [Concepts](/concepts)."
      }
    },
    "/team/estimate/export": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Estimates Report (deprecated)",
        "parameters": [
          {
            "name": "dueFrom",
            "in": "query",
            "required": false,
            "description": "Task due date from you what to fetch estimates (format YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "example": "2018-01-01"
            }
          },
          {
            "name": "dueTo",
            "in": "query",
            "required": false,
            "description": "Task due date to you what to fetch estimates (format YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "example": "2018-01-31"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "description": "Task status (e.g. open or completed)",
            "schema": {
              "type": "string",
              "example": "open"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/EstimateExportObject"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "estimatesReportDeprecated",
        "description": "Legacy export of team estimates, returned as JSON. Requires admin access. Kept for backward compatibility; new integrations should use the dashboard reports."
      }
    },
    "/team/time/export": {
      "get": {
        "tags": [
          "Reports"
        ],
        "summary": "Time Report (deprecated)",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Date from you what to fetch reported time (format YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "example": "2018-01-01"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Date to you what to fetch reported time (format YYYY-MM-DD)",
            "schema": {
              "type": "string",
              "example": "2018-01-31"
            }
          },
          {
            "name": "fields",
            "in": "query",
            "required": false,
            "description": "Comma-separated columns. Allowed: date, user, task, project, month, projects.",
            "schema": {
              "type": "string",
              "example": "date,user,task"
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by project (encoded ID).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "client",
            "in": "query",
            "required": false,
            "description": "Filter by client ID.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "user",
            "in": "query",
            "required": false,
            "description": "Filter by user ID.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "allowTimeWithoutTask",
            "in": "query",
            "required": false,
            "description": "Include time records that have no task.",
            "schema": {
              "type": "boolean",
              "example": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TimeExportObject"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "timeReportDeprecated",
        "description": "Legacy export of team time records, returned as JSON. Kept for backward compatibility; new integrations should use `GET /team/time` or the dashboard reports."
      }
    },
    "/resource-planner/assignments": {
      "get": {
        "tags": [
          "Schedule"
        ],
        "summary": "Get All Assignments",
        "parameters": [
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Filter by Assignment Type",
            "schema": {
              "type": "string",
              "enum": [
                "time-off",
                "assignment"
              ],
              "example": "time-off"
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Filter by Project ID",
            "schema": {
              "type": "string",
              "example": "ev:3456780034"
            }
          },
          {
            "name": "task",
            "in": "query",
            "required": false,
            "description": "Filter by Task ID",
            "schema": {
              "type": "string",
              "example": "ev:1123000456"
            }
          },
          {
            "name": "client",
            "in": "query",
            "required": false,
            "description": "Filter by Client ID",
            "schema": {
              "type": "number",
              "example": 1408
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Get Assignments Starting From",
            "schema": {
              "type": "string",
              "example": "2020-11-19"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Get Assignments Ending At",
            "schema": {
              "type": "string",
              "example": "2020-11-30"
            }
          },
          {
            "name": "allowRemovedUsers",
            "in": "query",
            "required": false,
            "description": "Include assignments of users removed from the team.",
            "schema": {
              "type": "boolean",
              "example": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Assignment"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllAssignments",
        "description": "List schedule assignments across the team. Supports filtering by date range, project, and member."
      },
      "post": {
        "tags": [
          "Schedule"
        ],
        "summary": "Create Assignment",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignmentRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Assignment"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createAssignment",
        "description": "Create a schedule assignment. To create time-off use `POST /resource-planner/assignments/time-off` instead."
      }
    },
    "/resource-planner/assignments/{assignment_id}": {
      "put": {
        "tags": [
          "Schedule"
        ],
        "summary": "Update Assignment",
        "parameters": [
          {
            "name": "assignment_id",
            "in": "path",
            "required": true,
            "description": "Assignment ID",
            "schema": {
              "type": "number",
              "example": 8495
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/AssignmentRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Assignment"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateAssignment",
        "description": "Update an existing schedule assignment."
      },
      "delete": {
        "tags": [
          "Schedule"
        ],
        "summary": "Delete Assignment",
        "parameters": [
          {
            "name": "assignment_id",
            "in": "path",
            "required": true,
            "description": "Assignment ID",
            "schema": {
              "type": "number",
              "example": 8495
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteAssignment",
        "description": "Delete a schedule assignment. You can include an optional `reason` (max 1000 characters) in the request body."
      }
    },
    "/projects/{project_id}/tasks": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get Project Tasks",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Results page",
            "schema": {
              "type": "integer",
              "example": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Tasks per page, 250 max",
            "schema": {
              "type": "integer",
              "example": 250
            }
          },
          {
            "name": "exclude-closed",
            "in": "query",
            "required": false,
            "description": "Exclude closed/completed tasks",
            "schema": {
              "type": "boolean",
              "example": false
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Search tasks by name",
            "schema": {
              "type": "string",
              "example": "Management"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Task"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getProjectTasks",
        "description": "List tasks in a project. By default all tasks are returned; set `exclude-closed=true` to hide closed/completed tasks. See [Pagination](/pagination) for `limit`/`page` rules."
      },
      "post": {
        "tags": [
          "Tasks"
        ],
        "summary": "Create Task",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createTask",
        "description": "Create a task in a project. For tasks coming from connected integrations, sync them via `POST /projects/{project_id}/sync` instead."
      }
    },
    "/tasks/{task_id}": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Get Task",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Task ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          },
          {
            "name": "opts_include_billing",
            "in": "query",
            "required": false,
            "description": "Set to `1` to include billing data on returned tasks: `rate` (cents per hour) and `amount` (round(time * rate / 3600)). Requires billing permissions; otherwise billing is omitted.",
            "schema": {
              "type": "integer",
              "example": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getTask",
        "description": "Retrieve a single task with its time totals, estimate, and custom fields."
      },
      "put": {
        "tags": [
          "Tasks"
        ],
        "summary": "Update Task",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Task ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateTask",
        "description": "Update task fields (name, status, due date, section, labels)."
      },
      "delete": {
        "tags": [
          "Tasks"
        ],
        "summary": "Delete Task",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Task ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteTask",
        "description": "Delete a task and all of its time records."
      }
    },
    "/tasks/{task_id}/billing": {
      "put": {
        "tags": [
          "Tasks"
        ],
        "summary": "Update Task Billing",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Task ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskBillingRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateTaskBilling",
        "description": "Set a task's billing rate or mark it non-billable. Requires admin access. The same values are returned on task responses when you pass `opts_include_billing=1`."
      }
    },
    "/tasks/{task_id}/estimate": {
      "put": {
        "tags": [
          "Tasks"
        ],
        "summary": "Update Task Estimate",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Task ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskEstimate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskEstimate"
                }
              }
            }
          },
          "204": {
            "description": "No Content (the task has no estimate)"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateTaskEstimate",
        "description": "Set or replace a task's estimate (in seconds). Send a complete estimate object; partial updates are not supported."
      },
      "delete": {
        "tags": [
          "Tasks"
        ],
        "summary": "Delete Task Estimate",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Task ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteTaskEstimate",
        "description": "Remove a task's estimate."
      }
    },
    "/tasks/search": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Search Tasks",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Search query",
            "schema": {
              "type": "string",
              "example": "Managem"
            }
          },
          {
            "name": "project",
            "in": "query",
            "required": false,
            "description": "Limit the search to a single project (encoded ID).",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Max number of search results",
            "schema": {
              "type": "integer",
              "example": 100
            }
          },
          {
            "name": "searchInClosed",
            "in": "query",
            "required": false,
            "description": "Should we search in closed/completed tasks?",
            "schema": {
              "type": "boolean",
              "example": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Task"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "searchTasks",
        "description": "Search tasks across all projects by name. The `limit` parameter must be between 1 and 100."
      }
    },
    "/projects/{project_id}/tasks/search": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "summary": "Search Project Tasks",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "ev:1234567789001"
            }
          },
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Search query",
            "schema": {
              "type": "string",
              "example": "Managem"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Max number of search results",
            "schema": {
              "type": "integer",
              "example": 10
            }
          },
          {
            "name": "searchInClosed",
            "in": "query",
            "required": false,
            "description": "Should we search in closed/completed tasks?",
            "schema": {
              "type": "boolean",
              "example": false
            }
          },
          {
            "name": "searchInUnscheduled",
            "in": "query",
            "required": false,
            "description": "Return unscheduled tasks (not in any section). Works without a `query`.",
            "schema": {
              "type": "boolean",
              "example": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Task"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "searchProjectTasks",
        "description": "Search tasks within a single project. Same query semantics as `GET /tasks/search`; `limit` must be between 1 and 100."
      }
    },
    "/resource-planner/time-off-types": {
      "get": {
        "tags": [
          "Time Off"
        ],
        "summary": "Get Time Off Types",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TimeOffType"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getTimeOffTypes",
        "description": "List the time-off types defined for the team (e.g. Vacation, Sick Leave)."
      },
      "post": {
        "tags": [
          "Time Off"
        ],
        "summary": "Create Time Off Type",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimeOffTypeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeOffType"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createTimeOffType",
        "description": "Create a new time-off type."
      }
    },
    "/resource-planner/time-off-types/{type_id}": {
      "put": {
        "tags": [
          "Time Off"
        ],
        "summary": "Update Time Off Type",
        "parameters": [
          {
            "name": "type_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimeOffTypeRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeOffType"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateTimeOffType",
        "description": "Update a time-off type's name, color, or settings."
      },
      "delete": {
        "tags": [
          "Time Off"
        ],
        "summary": "Delete Time Off Type",
        "parameters": [
          {
            "name": "type_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteTimeOffType",
        "description": "Delete a time-off type. Existing time-off entries that reference it are kept."
      }
    },
    "/allocations": {
      "get": {
        "tags": [
          "Time Off"
        ],
        "summary": "Get All Allocations",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TimeOffAllocation"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllAllocations",
        "description": "List per-user time-off allocations (e.g. annual vacation balances)."
      },
      "post": {
        "tags": [
          "Time Off"
        ],
        "summary": "Create Allocation",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimeOffAllocationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeOffAllocation"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createAllocation",
        "description": "Create a time-off allocation for a user and time-off type."
      }
    },
    "/allocations/{allocation_id}": {
      "put": {
        "tags": [
          "Time Off"
        ],
        "summary": "Update Allocation",
        "parameters": [
          {
            "name": "allocation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimeOffAllocationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeOffAllocation"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateAllocation",
        "description": "Update a time-off allocation's amount or period."
      },
      "delete": {
        "tags": [
          "Time Off"
        ],
        "summary": "Delete Allocation",
        "parameters": [
          {
            "name": "allocation_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "number"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteAllocation",
        "description": "Delete a time-off allocation."
      }
    },
    "/team/time": {
      "get": {
        "tags": [
          "Time Records"
        ],
        "summary": "Get All Time Records",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Date from",
            "schema": {
              "type": "string",
              "example": "2018-01-01"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Date to",
            "schema": {
              "type": "string",
              "example": "2018-01-31"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Max results for pagination, max value 50000",
            "schema": {
              "type": "integer",
              "example": 10000
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page",
            "schema": {
              "type": "integer",
              "example": 1
            }
          },
          {
            "name": "opts_include_billing",
            "in": "query",
            "required": false,
            "description": "Include billing data",
            "schema": {
              "type": "integer",
              "example": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "oneOf": [
                      {
                        "$ref": "#/components/schemas/TimeRecordExtended"
                      },
                      {
                        "$ref": "#/components/schemas/TaskTimeBillable"
                      }
                    ]
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllTimeRecords",
        "description": "List time records across the entire team for a date range. When `from`/`to` are omitted, only the current day is returned. See [Dates](/dates-and-timezones)."
      }
    },
    "/users/{user_id}/time": {
      "get": {
        "tags": [
          "Time Records"
        ],
        "summary": "Get User Time Records",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "User ID",
            "schema": {
              "type": "number",
              "example": 89
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Date from",
            "schema": {
              "type": "string",
              "example": "2018-01-01"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Date to",
            "schema": {
              "type": "string",
              "example": "2018-01-31"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Max results for pagination, max value 50000",
            "schema": {
              "type": "integer",
              "example": 10000
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page",
            "schema": {
              "type": "integer",
              "example": 1
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "Record offset. Takes precedence over `page` when both are sent.",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TimeRecord"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getUserTimeRecords",
        "description": "List time records for a single user. Supports the same filters as `GET /team/time`."
      }
    },
    "/tasks/{task_id}/time": {
      "get": {
        "tags": [
          "Time Records"
        ],
        "summary": "Get Task Time Records",
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Task ID",
            "schema": {
              "type": "string",
              "example": "ev:3000010034"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Date from",
            "schema": {
              "type": "string",
              "example": "2018-01-01"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Date to",
            "schema": {
              "type": "string",
              "example": "2018-01-31"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Max results for pagination, max value 50000",
            "schema": {
              "type": "integer",
              "example": 10000
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page",
            "schema": {
              "type": "integer",
              "example": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TimeRecordExtended"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getTaskTimeRecords",
        "description": "List time records logged against a single task, across all users."
      }
    },
    "/projects/{project_id}/time": {
      "get": {
        "tags": [
          "Time Records"
        ],
        "summary": "Get Project Time Records",
        "parameters": [
          {
            "name": "project_id",
            "in": "path",
            "required": true,
            "description": "Project ID",
            "schema": {
              "type": "string",
              "example": "as:13456788"
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Date from",
            "schema": {
              "type": "string",
              "example": "2018-01-01"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Date to",
            "schema": {
              "type": "string",
              "example": "2018-01-31"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Max results for pagination, max value 50000",
            "schema": {
              "type": "integer",
              "example": 10000
            }
          },
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page",
            "schema": {
              "type": "integer",
              "example": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/TimeRecordExtended"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getProjectTimeRecords",
        "description": "List time records logged against a single project, across all users and tasks."
      }
    },
    "/time": {
      "post": {
        "tags": [
          "Time Records"
        ],
        "summary": "Add Time",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimeRecordRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeRecordExtended"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "addTime",
        "description": "Add a time record (in seconds) for a user on a given task and date.\n\n**Upsert:** at most one time record exists per `(user, date, task)`. Posting again with the same combination updates the existing record's duration instead of creating a duplicate. To update a specific record by ID, use `PUT /time/{time_id}`.\n\nSee [Dates](/dates-and-timezones) for accepted date and duration formats."
      }
    },
    "/time/{time_id}": {
      "put": {
        "tags": [
          "Time Records"
        ],
        "summary": "Update Time Record",
        "parameters": [
          {
            "name": "time_id",
            "in": "path",
            "required": true,
            "description": "ID of Task Time",
            "schema": {
              "type": "number",
              "example": 8006001
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimeRecordRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeRecordExtended"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateTimeRecord",
        "description": "Update a specific time record by ID. To add or upsert time, use `POST /time` instead."
      },
      "delete": {
        "tags": [
          "Time Records"
        ],
        "summary": "Delete Time Record",
        "parameters": [
          {
            "name": "time_id",
            "in": "path",
            "required": true,
            "description": "ID of Task Time",
            "schema": {
              "type": "number",
              "example": 8006001
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimeRecordExtended"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteTimeRecord",
        "description": "Remove a time record by setting its duration to zero.\n\nThe history trail is preserved; the row no longer appears in time listings, which filter for `time > 0`."
      }
    },
    "/users/{user_id}/timecards/{date}": {
      "get": {
        "tags": [
          "Timecards"
        ],
        "summary": "Get Timecard",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "User ID",
            "schema": {
              "type": "number",
              "example": 89
            }
          },
          {
            "name": "date",
            "in": "path",
            "required": true,
            "description": "Date",
            "schema": {
              "type": "string",
              "example": "2020-10-21"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Timecard"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getTimecard",
        "description": "Retrieve a user's timecard for a specific date."
      },
      "put": {
        "tags": [
          "Timecards"
        ],
        "summary": "Update Timecard",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "User ID",
            "schema": {
              "type": "number",
              "example": 89
            }
          },
          {
            "name": "date",
            "in": "path",
            "required": true,
            "description": "Date",
            "schema": {
              "type": "string",
              "example": "2020-10-21"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "clockIn": {
                    "type": "string",
                    "description": "Clock in time in user timezone",
                    "example": "09:00"
                  },
                  "clockOut": {
                    "type": "string",
                    "description": "Clock out time in user timezone",
                    "example": "18:00"
                  },
                  "breakTime": {
                    "type": "number",
                    "description": "Breaks duration in seconds",
                    "example": 3600
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Timecard"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateTimecard",
        "description": "Update (or create, if missing) a user's timecard for a specific date. Suitable for manual edits — clock-in and clock-out have dedicated endpoints."
      },
      "delete": {
        "tags": [
          "Timecards"
        ],
        "summary": "Delete Timecard",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "User ID",
            "schema": {
              "type": "number",
              "example": 89
            }
          },
          {
            "name": "date",
            "in": "path",
            "required": true,
            "description": "Date",
            "schema": {
              "type": "string",
              "example": "2020-10-21"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteTimecard",
        "description": "Delete a user's timecard entry for a specific date."
      }
    },
    "/users/{user_id}/timecards": {
      "get": {
        "tags": [
          "Timecards"
        ],
        "summary": "Get User Timecards",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "User ID",
            "schema": {
              "type": "number",
              "example": 89
            }
          },
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Date from (2 weeks ago by default)",
            "schema": {
              "type": "string",
              "example": "2020-10-01"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Date to",
            "schema": {
              "type": "string",
              "example": "2020-11-01"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Timecard"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getUserTimecards",
        "description": "List timecards for a single user. Defaults to the last two weeks when no date range is provided."
      }
    },
    "/timecards": {
      "get": {
        "tags": [
          "Timecards"
        ],
        "summary": "Get All Timecards",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "required": false,
            "description": "Date from (2 weeks ago by default)",
            "schema": {
              "type": "string",
              "example": "2020-10-01"
            }
          },
          {
            "name": "to",
            "in": "query",
            "required": false,
            "description": "Date to",
            "schema": {
              "type": "string",
              "example": "2020-11-01"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Timecard"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllTimecards",
        "description": "List timecards across the team. Defaults to the last two weeks when no date range is provided — see [Dates](/dates-and-timezones)."
      }
    },
    "/users/{user_id}/timecards/clock-in": {
      "post": {
        "tags": [
          "Timecards"
        ],
        "summary": "Clock In",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "User ID",
            "schema": {
              "type": "number",
              "example": 89
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userDate": {
                    "type": "string",
                    "description": "Current user date, if not specified we will rely on user profile timezone.",
                    "example": "2020-11-27"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Timecard"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "clockIn",
        "description": "Clock a user in. Starts a new timecard segment at the current time."
      }
    },
    "/users/{user_id}/timecards/clock-out": {
      "post": {
        "tags": [
          "Timecards"
        ],
        "summary": "Clock Out",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "User ID",
            "schema": {
              "type": "number",
              "example": 89
            }
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "userDate": {
                    "type": "string",
                    "description": "Current user date, if not specified we will rely on user profile timezone.",
                    "example": "2020-11-27"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Timecard"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "clockOut",
        "description": "Clock a user out. Closes the current timecard segment."
      }
    },
    "/timers": {
      "post": {
        "tags": [
          "Timers"
        ],
        "summary": "Start Timer",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimerRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Timer"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "startTimer",
        "description": "Start a timer for the authenticated user on a given task.\n\nOnly one timer can run per user at a time. If the user already has a timer running on another task, that timer is stopped automatically before the new one starts; the stopped run is committed to a time record on its own date (the date the timer was started, which may not be today for cross-midnight runs).\n\nSee [Concepts](/concepts) for timer semantics."
      }
    },
    "/timers/current": {
      "get": {
        "tags": [
          "Timers"
        ],
        "summary": "Get Running Timer",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Timer"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getRunningTimer",
        "description": "Retrieve the authenticated user's currently running timer, or an empty timer payload if none is running."
      },
      "delete": {
        "tags": [
          "Timers"
        ],
        "summary": "Stop Timer",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "The stopped timer plus the time record it saved.",
                  "properties": {
                    "status": {
                      "type": "string",
                      "example": "stopped"
                    },
                    "taskTime": {
                      "$ref": "#/components/schemas/TimeRecord"
                    },
                    "timecard": {
                      "type": "object",
                      "nullable": true
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "stopTimer",
        "description": "Stop the authenticated user's currently running timer.\n\nThe accumulated duration is committed to a time record on the timer's task for the current date and returned in the response."
      }
    },
    "/team/timers": {
      "get": {
        "tags": [
          "Timers"
        ],
        "summary": "Get All Team Timers",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Timer"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllTeamTimers",
        "description": "List the timers currently running across the team — one entry per active user."
      }
    },
    "/users/{user_id}/timesheets": {
      "get": {
        "tags": [
          "Timesheets"
        ],
        "summary": "Get User Timesheets",
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "description": "User ID",
            "schema": {
              "type": "number"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "max number of weeks",
            "schema": {
              "type": "integer",
              "example": 10
            }
          },
          {
            "name": "weekId",
            "in": "query",
            "required": false,
            "description": "Filter to a single week (YYWW).",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Timesheet"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getUserTimesheets",
        "description": "List timesheet weeks for a single user. The week id is the Monday date of the week (see [Dates](/dates-and-timezones))."
      }
    },
    "/timesheets": {
      "get": {
        "tags": [
          "Timesheets"
        ],
        "summary": "Get Team Timesheets",
        "parameters": [
          {
            "name": "weekId",
            "in": "query",
            "required": false,
            "description": "Week ID",
            "schema": {
              "type": "number",
              "example": 2535
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of timesheets to return.",
            "schema": {
              "type": "integer",
              "example": 10
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Timesheet"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getTeamTimesheets",
        "description": "List timesheet weeks across the team, grouped by user."
      }
    },
    "/timesheets/{timesheet_id}/approval": {
      "post": {
        "tags": [
          "Timesheets"
        ],
        "summary": "Approve Week/Request for Approval",
        "parameters": [
          {
            "name": "timesheet_id",
            "in": "path",
            "required": true,
            "description": "Timesheet ID",
            "schema": {
              "type": "number",
              "example": 148562535
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimesheetApprovalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimesheetApproval"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "approveWeekRequestForApproval",
        "description": "Submit a timesheet week for approval.\n\nThe week's owner uses this endpoint to request review; an approver acts on the request via `PUT /timesheets/{timesheet_id}/approval`.\n\nThe `timesheet_id` is the concatenation of `user_id` and a 4-digit `week_id` in `YYWW` format (no separator). Example: user `14856` for week `2535` (week 35 of 2025) → `timesheet_id = 148562535`. See the Timesheets overview for the full Week ID definition."
      },
      "put": {
        "tags": [
          "Timesheets"
        ],
        "summary": "Approve or Reject Approval Request",
        "parameters": [
          {
            "name": "timesheet_id",
            "in": "path",
            "required": true,
            "description": "Timesheet ID",
            "schema": {
              "type": "number",
              "example": 148562535
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimesheetApprovalReviewRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimesheetApproval"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "approveOrRejectApprovalRequest",
        "description": "Approve or reject an existing timesheet approval request.\n\nUse this endpoint to act on a request previously created with `POST /timesheets/{timesheet_id}/approval`. The response reflects the resulting approval state."
      }
    },
    "/timesheets/{timesheet_id}/discard-approval": {
      "put": {
        "tags": [
          "Timesheets"
        ],
        "summary": "Discard Your Approval Request",
        "parameters": [
          {
            "name": "timesheet_id",
            "in": "path",
            "required": true,
            "description": "Timesheet ID",
            "schema": {
              "type": "number",
              "example": 148562535
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TimesheetApprovalRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TimesheetApproval"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "discardYourApprovalRequest",
        "description": "Retract the caller's previously submitted approval request for a week. The week returns to draft state."
      }
    },
    "/users/me": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Get Current User",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CurrentUser"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getCurrentUser",
        "description": "Retrieve the user that owns the API key, including personal settings (timezone, formats, API key)."
      }
    },
    "/team/users": {
      "get": {
        "tags": [
          "Users"
        ],
        "summary": "Get All Users",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/User"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllUsers",
        "description": "List all members of the team. Supports `query` for name search and `limit` for pagination — see [Pagination](/pagination).",
        "parameters": [
          {
            "name": "query",
            "in": "query",
            "required": false,
            "description": "Filter users by name or email.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Maximum number of users to return.",
            "schema": {
              "type": "integer"
            }
          }
        ]
      }
    },
    "/hooks/{hook_id}": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Get Webhook",
        "parameters": [
          {
            "name": "hook_id",
            "in": "path",
            "required": true,
            "description": "Webhook ID",
            "schema": {
              "type": "number",
              "example": 280382
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getWebhook",
        "description": "Retrieve a single webhook subscription."
      },
      "put": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Update Webhook",
        "parameters": [
          {
            "name": "hook_id",
            "in": "path",
            "required": true,
            "description": "Webhook ID",
            "schema": {
              "type": "number",
              "example": 280382
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookRequestUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "updateWebhook",
        "description": "Update a webhook's events or scope. The `targetUrl` cannot be changed and is ignored if sent; the handshake is repeated against the existing URL to confirm it is still reachable. Send `X-Skip-Handshake: 1` to skip it."
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete Webhook",
        "parameters": [
          {
            "name": "hook_id",
            "in": "path",
            "required": true,
            "description": "Webhook ID",
            "schema": {
              "type": "number",
              "example": 280382
            }
          }
        ],
        "responses": {
          "204": {
            "description": "No Content"
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "deleteWebhook",
        "description": "Delete a webhook subscription. Stops further deliveries; no event is sent for the deletion itself."
      }
    },
    "/hooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Get All Webhooks",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Webhook"
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "getAllWebhooks",
        "description": "List all webhook subscriptions created with your API key."
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Create Webhook",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookRequestCreateRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized"
          }
        },
        "operationId": "createWebhook",
        "description": "Register a new webhook subscription.\n\n**Handshake:** on create, Everhour sends a POST to the supplied `targetUrl` with an `X-Hook-Secret` header (HMAC-SHA512) and an empty body. The receiver must respond with a 2xx status to complete verification. Send `X-Skip-Handshake: 1` to skip verification when the receiver cannot participate.\n\n**Scope:** a webhook can listen across the whole team or be scoped to a single project. See [Webhooks](/webhooks) for event types, payload structure, and delivery semantics."
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "X-Api-Key"
      }
    },
    "schemas": {
      "WebhookRequestCreateRequest": {
        "type": "object",
        "properties": {
          "targetUrl": {
            "type": "string",
            "description": "URL that receives event POSTs.",
            "example": "https://some-secure-endpoint.com/path"
          },
          "events": {
            "type": "array",
            "description": "Events you want to receive.",
            "items": {
              "type": "string"
            },
            "example": [
              "api:time:updated"
            ]
          },
          "project": {
            "type": [
              "string",
              "null"
            ],
            "description": "Restrict the subscription to a single project.",
            "example": "ev:12345657890"
          }
        },
        "required": [
          "targetUrl",
          "events"
        ]
      },
      "WebhookRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "events": {
            "type": "array",
            "description": "Replacement list of events. `targetUrl` and scope cannot be changed after creation.",
            "items": {
              "type": "string"
            },
            "example": [
              "api:time:updated"
            ]
          }
        },
        "required": [
          "events"
        ]
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Webhook ID",
            "example": 12345
          },
          "targetUrl": {
            "type": "string",
            "example": "https://some-secure-endpoint.com/path"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "api:time:updated"
            ]
          },
          "project": {
            "type": [
              "string",
              "null"
            ],
            "description": "You can receive events only for specific project",
            "example": "ev:12345657890"
          },
          "active": {
            "type": "boolean",
            "example": true
          },
          "createdAt": {
            "type": "string",
            "description": "Datetime when webhook was created (format: Y-m-d H:i:s)",
            "example": "2018-03-05 16:17:14"
          },
          "lastUsedAt": {
            "type": "string",
            "description": "Datetime when webhook was last used (format: Y-m-d H:i:s)",
            "example": "2018-03-05 20:01:58"
          }
        },
        "required": [
          "id",
          "targetUrl",
          "events",
          "createdAt",
          "lastUsedAt"
        ]
      },
      "ClientBudget": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Budget Type",
            "enum": [
              "money",
              "time",
              "costs"
            ],
            "example": "money"
          },
          "budget": {
            "type": "number",
            "description": "Budget value in cents (for money) or seconds (for time)",
            "example": 100000
          },
          "period": {
            "type": "string",
            "description": "Budget periodicity (overall, monthly, weekly, daily)",
            "enum": [
              "general",
              "monthly",
              "weekly",
              "daily",
              "quarterly",
              "yearly"
            ],
            "example": "general"
          },
          "appliedFrom": {
            "type": [
              "string",
              "null"
            ],
            "description": "Start budget from (available only for non-recurrent budgets)"
          },
          "disallowOverbudget": {
            "type": "boolean"
          },
          "excludeUnbillableTime": {
            "type": "boolean"
          },
          "excludeExpenses": {
            "type": "boolean"
          },
          "threshold": {
            "type": "number",
            "description": "Email admins when threshold reached. Threshold is percentage 1 - 100."
          },
          "progress": {
            "type": "number",
            "description": "Current budget usage in cents (for money) or seconds (for time)",
            "readOnly": true,
            "example": 0
          }
        },
        "required": [
          "type",
          "budget",
          "period"
        ]
      },
      "Project": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "as:1234567890"
          },
          "name": {
            "type": "string",
            "example": "Project Name"
          },
          "workspaceId": {
            "type": [
              "string",
              "null"
            ]
          },
          "workspaceName": {
            "type": [
              "string",
              "null"
            ]
          },
          "client": {
            "type": [
              "number",
              "null"
            ],
            "description": "Client ID"
          },
          "type": {
            "type": "string",
            "description": "Project Type",
            "enum": [
              "board",
              "list"
            ],
            "example": "board"
          },
          "favorite": {
            "type": "boolean",
            "example": false
          },
          "users": {
            "type": "array",
            "description": "List of assigned user IDs",
            "items": {
              "type": "number"
            },
            "example": [
              1304,
              1543
            ]
          },
          "billing": {
            "$ref": "#/components/schemas/ProjectBillingBilling"
          },
          "rate": {
            "$ref": "#/components/schemas/ProjectBillingRate"
          },
          "budget": {
            "$ref": "#/components/schemas/ProjectBillingBudget"
          }
        },
        "required": [
          "id",
          "name",
          "users"
        ]
      },
      "ProjectRequestCreateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Project Name"
          },
          "type": {
            "type": "string",
            "description": "Project type",
            "enum": [
              "board",
              "list"
            ],
            "example": "board"
          },
          "users": {
            "type": "array",
            "description": "Assigned user IDs",
            "items": {
              "type": "integer"
            },
            "example": [
              1304,
              1543
            ]
          },
          "client": {
            "type": "integer",
            "nullable": true,
            "description": "Client ID to assign the project to"
          },
          "privacy": {
            "type": "boolean",
            "description": "Restrict project visibility to its assigned members"
          },
          "changeProtected": {
            "type": "boolean",
            "description": "Prevent edits by non-admins"
          },
          "isTemplate": {
            "type": "boolean",
            "description": "Mark the project as a template"
          }
        },
        "required": [
          "name",
          "type"
        ]
      },
      "ProjectRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Project Name"
          },
          "type": {
            "type": "string",
            "description": "Project type",
            "enum": [
              "board",
              "list"
            ],
            "example": "board"
          },
          "users": {
            "type": "array",
            "description": "Assigned user IDs",
            "items": {
              "type": "integer"
            },
            "example": [
              1304,
              1543
            ]
          },
          "client": {
            "type": "integer",
            "nullable": true,
            "description": "Client ID to assign the project to"
          },
          "privacy": {
            "type": "boolean",
            "description": "Restrict project visibility to its assigned members"
          },
          "changeProtected": {
            "type": "boolean",
            "description": "Prevent edits by non-admins"
          },
          "isTemplate": {
            "type": "boolean",
            "description": "Mark the project as a template"
          },
          "icon": {
            "type": "string",
            "description": "Project icon (update only)."
          },
          "color": {
            "type": "string",
            "description": "Project color, hex #rrggbb (update only)."
          }
        }
      },
      "ProjectBillingBilling": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Project Type",
            "enum": [
              "non_billable",
              "hourly",
              "fixed_fee"
            ]
          },
          "fee": {
            "type": "number",
            "description": "Project fixed fee in cents"
          }
        },
        "required": [
          "type"
        ]
      },
      "ProjectBillingRate": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Project Type",
            "enum": [
              "project_rate",
              "user_rate"
            ]
          },
          "rate": {
            "type": "number",
            "description": "Flat-rate in cents"
          },
          "userRateOverrides": {
            "type": "object",
            "description": "Override user rates",
            "additionalProperties": {
              "type": "number"
            },
            "example": {
              "1304": 10000,
              "1543": 5000
            }
          }
        },
        "required": [
          "type"
        ]
      },
      "ProjectBillingBudget": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "Budget Type",
            "enum": [
              "money",
              "time",
              "costs"
            ],
            "example": "money"
          },
          "budget": {
            "type": "number",
            "description": "Budget value in cents (for money) or seconds (for time)",
            "example": 100000
          },
          "progress": {
            "type": "number",
            "description": "Current budget usage in cents (for money) or seconds (for time)",
            "readOnly": true,
            "example": 0
          },
          "timeProgress": {
            "type": "number",
            "description": "Budget progress belongs to time tracking",
            "readOnly": true,
            "example": 0
          },
          "expenseProgress": {
            "type": "number",
            "description": "Budget progress belongs to expenses",
            "readOnly": true,
            "example": 0
          },
          "period": {
            "type": "string",
            "description": "Budget periodicity",
            "enum": [
              "general",
              "monthly",
              "weekly",
              "daily",
              "quarterly",
              "yearly"
            ],
            "example": "general"
          },
          "appliedFrom": {
            "type": [
              "string",
              "null"
            ],
            "description": "Start budget from (available only for non-recurrent budgets)"
          },
          "disallowOverbudget": {
            "type": "boolean"
          },
          "excludeUnbillableTime": {
            "type": "boolean"
          },
          "excludeExpenses": {
            "type": "boolean"
          },
          "showToUsers": {
            "type": "boolean",
            "description": "Set true if all team members should see budget and its progress"
          },
          "threshold": {
            "type": "number",
            "description": "Email admins when threshold reached. Threshold is percentage 1 - 100."
          }
        },
        "required": [
          "type",
          "budget",
          "period"
        ]
      },
      "ProjectBilling": {
        "type": "object",
        "properties": {
          "billing": {
            "$ref": "#/components/schemas/ProjectBillingBilling"
          },
          "rate": {
            "$ref": "#/components/schemas/ProjectBillingRate"
          },
          "budget": {
            "$ref": "#/components/schemas/ProjectBillingBudget"
          }
        }
      },
      "Section": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 1234
          },
          "name": {
            "type": "string",
            "example": "Section Name"
          },
          "project": {
            "type": "string",
            "example": "ev:1234567890"
          },
          "position": {
            "type": "number",
            "example": 1
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "archived"
            ],
            "example": "open"
          },
          "collapsed": {
            "type": "boolean",
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "project",
          "position"
        ]
      },
      "SectionRequestCreateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Section Name"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "archived"
            ],
            "example": "open"
          },
          "placeBefore": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "IDs of sections to place this one before (create only)."
          },
          "collapsed": {
            "type": "boolean"
          }
        },
        "required": [
          "name"
        ]
      },
      "SectionRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Section Name"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "archived"
            ],
            "example": "open"
          },
          "collapsed": {
            "type": "boolean"
          }
        }
      },
      "ProjectArchiveRequest": {
        "type": "object",
        "properties": {
          "archived": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "archived"
        ]
      },
      "Task": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "example": "ev:9876543210"
          },
          "name": {
            "type": "string",
            "example": "Task Name"
          },
          "projects": {
            "type": "array",
            "description": "List of projects ID",
            "items": {
              "type": "string"
            },
            "example": [
              "ev:1234567890"
            ]
          },
          "section": {
            "type": [
              "number",
              "null"
            ],
            "description": "Section ID",
            "example": 1234
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "high",
              "bug"
            ]
          },
          "position": {
            "type": "number",
            "example": 1
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "dueAt": {
            "type": [
              "string",
              "null"
            ],
            "description": "Format: Y-m-d H:i:s",
            "example": "2018-03-05 16:00:00"
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ],
            "example": "open"
          },
          "time": {
            "$ref": "#/components/schemas/TaskTime"
          },
          "estimate": {
            "$ref": "#/components/schemas/TaskEstimate"
          },
          "attributes": {
            "type": "object",
            "description": "Custom attributes from integration",
            "additionalProperties": {
              "type": "string"
            },
            "example": {
              "Client": "Everhour",
              "Priority": "high"
            }
          },
          "metrics": {
            "type": "object",
            "description": "Custom metrics from integration",
            "additionalProperties": {
              "type": "number"
            },
            "example": {
              "efforts": 42,
              "expenses": 199
            }
          },
          "unbillable": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "name",
          "projects"
        ]
      },
      "TaskRequestCreateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Task Name"
          },
          "section": {
            "type": "integer",
            "description": "Section ID",
            "example": 1234
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "high",
              "bug"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ],
            "example": "open"
          },
          "color": {
            "type": "string",
            "description": "Label color, max 15 chars.",
            "example": "#fdb301"
          },
          "dueOn": {
            "type": "string",
            "description": "Due date, format Y-m-d. Send \"\" to clear.",
            "example": "2018-03-05"
          },
          "startOn": {
            "type": "string",
            "description": "Start date, format Y-m-d. Send \"\" to clear.",
            "example": "2018-03-01"
          },
          "description": {
            "type": "string",
            "description": "Plain-text description, max 2000 chars."
          },
          "assignees": {
            "type": "array",
            "description": "Task assignees.",
            "items": {
              "type": "object",
              "properties": {
                "userId": {
                  "type": "integer"
                },
                "accountId": {
                  "type": "string"
                }
              }
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Tag IDs, max 10."
          },
          "fields": {
            "type": "array",
            "description": "Custom field values.",
            "items": {
              "type": "object"
            }
          },
          "cover": {
            "type": "object",
            "properties": {
              "coverId": {
                "type": "integer"
              },
              "coverPick": {
                "type": "string",
                "example": "recent"
              }
            }
          },
          "placeBefore": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Encoded IDs of tasks to place this one before (create only)."
          }
        },
        "required": [
          "name"
        ]
      },
      "TaskRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Task Name"
          },
          "section": {
            "type": "integer",
            "description": "Section ID",
            "example": 1234
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "high",
              "bug"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ],
            "example": "open"
          },
          "color": {
            "type": "string",
            "description": "Label color, max 15 chars.",
            "example": "#fdb301"
          },
          "dueOn": {
            "type": "string",
            "description": "Due date, format Y-m-d. Send \"\" to clear.",
            "example": "2018-03-05"
          },
          "startOn": {
            "type": "string",
            "description": "Start date, format Y-m-d. Send \"\" to clear.",
            "example": "2018-03-01"
          },
          "description": {
            "type": "string",
            "description": "Plain-text description, max 2000 chars."
          },
          "assignees": {
            "type": "array",
            "description": "Task assignees.",
            "items": {
              "type": "object",
              "properties": {
                "userId": {
                  "type": "integer"
                },
                "accountId": {
                  "type": "string"
                }
              }
            }
          },
          "tags": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Tag IDs, max 10."
          },
          "fields": {
            "type": "array",
            "description": "Custom field values.",
            "items": {
              "type": "object"
            }
          },
          "cover": {
            "type": "object",
            "properties": {
              "coverId": {
                "type": "integer"
              },
              "coverPick": {
                "type": "string",
                "example": "recent"
              }
            }
          }
        }
      },
      "TaskBillingRequest": {
        "type": "object",
        "properties": {
          "unbillable": {
            "type": "boolean",
            "description": "Mark the task as non-billable.",
            "example": false
          },
          "rate": {
            "type": "integer",
            "description": "Hourly billable rate in cents. Use -1 to leave the current rate unchanged.",
            "example": 10000
          }
        }
      },
      "TaskBilling": {
        "type": "object",
        "properties": {
          "billable": {
            "type": "boolean",
            "description": "True if the task is not marked as non-billable and has at least one billable project",
            "example": true
          },
          "amount": {
            "type": "number",
            "description": "Total amount for all users in cents",
            "example": 16000
          }
        },
        "required": [
          "billable",
          "amount"
        ]
      },
      "TaskTimeBilling": {
        "type": "object",
        "properties": {
          "billable": {
            "type": "boolean",
            "example": true
          },
          "rate": {
            "type": "number",
            "description": "Rate in cents",
            "example": 10000
          },
          "amount": {
            "type": "number",
            "description": "Amount in cents",
            "example": 16000
          }
        },
        "required": [
          "billable",
          "rate",
          "amount"
        ]
      },
      "TaskTimeBillable": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Time record ID",
            "example": 2660155
          },
          "time": {
            "type": "number",
            "description": "Time recorded in seconds",
            "example": 3600
          },
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 1304
          },
          "date": {
            "type": "string",
            "description": "Date",
            "example": "2018-01-20"
          },
          "task": {
            "$ref": "#/components/schemas/Task"
          },
          "comment": {
            "type": "string",
            "example": "some notes"
          },
          "billing": {
            "$ref": "#/components/schemas/TaskTimeBilling"
          }
        },
        "required": [
          "id",
          "time",
          "user",
          "date"
        ]
      },
      "TaskTime": {
        "type": "object",
        "properties": {
          "total": {
            "type": "number",
            "description": "Total task time in seconds",
            "example": 7200
          },
          "users": {
            "type": "object",
            "description": "Task time per user ID",
            "additionalProperties": {
              "type": "number"
            },
            "example": {
              "1304": 3600,
              "1543": 3600
            }
          }
        },
        "required": [
          "total",
          "users"
        ]
      },
      "TaskEstimate": {
        "type": "object",
        "properties": {
          "total": {
            "type": "number",
            "description": "Total task estimate in seconds",
            "example": 7200
          },
          "type": {
            "type": "string",
            "enum": [
              "overall",
              "users"
            ],
            "example": "overall"
          },
          "users": {
            "type": "object",
            "description": "Task estimate per user ID",
            "additionalProperties": {
              "type": "number"
            },
            "example": {
              "1304": 3600,
              "1543": 3600
            }
          }
        },
        "required": [
          "total",
          "type"
        ]
      },
      "User": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 1304
          },
          "name": {
            "type": "string",
            "example": "User Name"
          },
          "headline": {
            "type": [
              "string",
              "null"
            ],
            "example": "CEO"
          },
          "avatarUrl": {
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "type": "string",
            "enum": [
              "admin",
              "supervisor",
              "member",
              "member_limited"
            ],
            "example": "admin"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "invited",
              "pending",
              "removed"
            ],
            "example": "active"
          },
          "phone": {
            "type": "string",
            "nullable": true
          },
          "capacity": {
            "type": "integer",
            "nullable": true,
            "description": "Weekly capacity in seconds."
          },
          "avatarUrlLarge": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "role",
          "status"
        ]
      },
      "CurrentUser": {
        "allOf": [
          {
            "$ref": "#/components/schemas/User"
          },
          {
            "type": "object",
            "description": "Additional fields returned only for the authenticated user.",
            "properties": {
              "timezone": {
                "type": "number",
                "description": "UTC offset in hours (e.g. -5, 5.5)."
              },
              "apiKey": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "employee",
                  "contractor"
                ]
              },
              "createdAt": {
                "type": "string",
                "description": "Format: Y-m-d H:i:s"
              },
              "dateFormat": {
                "type": "integer"
              },
              "timeFormat": {
                "type": "integer"
              },
              "timeRounding": {
                "type": "integer"
              },
              "country": {
                "type": "string",
                "description": "ISO 3166-1 alpha-2 country code."
              },
              "team": {
                "type": "object",
                "description": "The user's team."
              },
              "rate": {
                "type": "integer",
                "description": "Hourly bill rate in cents (admins only)."
              },
              "cost": {
                "type": "integer",
                "description": "Hourly cost in cents (requires cost permissions)."
              }
            }
          }
        ]
      },
      "Client": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 4567
          },
          "name": {
            "type": "string",
            "example": "Client Name"
          },
          "projects": {
            "type": "array",
            "description": "List of projects ID",
            "items": {
              "type": "string"
            },
            "example": [
              "ev:1234567890"
            ]
          },
          "businessDetails": {
            "type": [
              "string",
              "null"
            ]
          },
          "budget": {
            "$ref": "#/components/schemas/ClientBudget"
          }
        },
        "required": [
          "id",
          "name",
          "projects"
        ]
      },
      "ClientBillingDetails": {
        "type": "object",
        "description": "Client billing details (all fields optional).",
        "properties": {
          "companyName": {
            "type": "string",
            "nullable": true
          },
          "vatNumber": {
            "type": "string",
            "nullable": true
          },
          "addressLine1": {
            "type": "string",
            "nullable": true
          },
          "addressLine2": {
            "type": "string",
            "nullable": true
          },
          "city": {
            "type": "string",
            "nullable": true
          },
          "state": {
            "type": "string",
            "nullable": true
          },
          "postcode": {
            "type": "string",
            "nullable": true
          },
          "country": {
            "type": "string",
            "nullable": true,
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "contactName": {
            "type": "string",
            "nullable": true
          },
          "contactPhone": {
            "type": "string",
            "nullable": true
          },
          "contactEmail": {
            "type": "string",
            "nullable": true
          },
          "peppolEndpointId": {
            "type": "string",
            "nullable": true
          },
          "peppolEndpointScheme": {
            "type": "string",
            "nullable": true
          },
          "peppolMeansCode": {
            "type": "string",
            "nullable": true
          },
          "bankAccountNumber": {
            "type": "string",
            "nullable": true
          },
          "bankAccountRoutingNumber": {
            "type": "string",
            "nullable": true
          },
          "bankAccountHolderName": {
            "type": "string",
            "nullable": true
          }
        }
      },
      "ClientRequestCreateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Client Name"
          },
          "projects": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Project encoded IDs to assign to the client."
          },
          "lineItemMask": {
            "type": "string",
            "description": "Template for generated invoice line-item names."
          },
          "defaultTax": {
            "type": "object",
            "description": "Default tax for the client's invoices.",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Tax ID from a connected accounting integration."
              },
              "rate": {
                "type": "number",
                "description": "Tax rate as a percentage."
              }
            }
          },
          "defaultDiscount": {
            "type": "number",
            "description": "Default discount rate as a percentage (0-100)."
          },
          "paymentDueDays": {
            "type": "integer",
            "description": "Default invoice payment term in days (0-365)."
          },
          "reference": {
            "type": "string"
          },
          "invoicePublicNotes": {
            "type": "string"
          },
          "businessDetails": {
            "type": "string"
          },
          "billingDetails": {
            "$ref": "#/components/schemas/ClientBillingDetails"
          },
          "excludedLabels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Labels excluded from invoicing (max 8)."
          },
          "email": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Invoice recipient email addresses (max 10)."
          }
        },
        "required": [
          "name"
        ]
      },
      "ClientRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Client Name"
          },
          "projects": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Project encoded IDs to assign to the client."
          },
          "lineItemMask": {
            "type": "string",
            "description": "Template for generated invoice line-item names."
          },
          "defaultTax": {
            "type": "object",
            "description": "Default tax for the client's invoices.",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Tax ID from a connected accounting integration."
              },
              "rate": {
                "type": "number",
                "description": "Tax rate as a percentage."
              }
            }
          },
          "defaultDiscount": {
            "type": "number",
            "description": "Default discount rate as a percentage (0-100)."
          },
          "paymentDueDays": {
            "type": "integer",
            "description": "Default invoice payment term in days (0-365)."
          },
          "reference": {
            "type": "string"
          },
          "invoicePublicNotes": {
            "type": "string"
          },
          "businessDetails": {
            "type": "string"
          },
          "billingDetails": {
            "$ref": "#/components/schemas/ClientBillingDetails"
          },
          "excludedLabels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Labels excluded from invoicing (max 8)."
          },
          "email": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Invoice recipient email addresses (max 10)."
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "archived",
              "deleted"
            ],
            "description": "Client status (update only)."
          }
        }
      },
      "Timer": {
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "active",
              "stopped"
            ],
            "example": "active"
          },
          "duration": {
            "type": "number",
            "description": "Timer duration in seconds",
            "example": 16
          },
          "today": {
            "type": "number",
            "description": "Today time by user in the timer task",
            "example": 7200
          },
          "startedAt": {
            "type": "string",
            "example": "2018-01-16 12:42:59"
          },
          "userDate": {
            "type": "string",
            "example": "2018-01-16"
          },
          "comment": {
            "type": "string"
          },
          "task": {
            "$ref": "#/components/schemas/Task"
          },
          "user": {
            "$ref": "#/components/schemas/User"
          },
          "currentTaskTime": {
            "$ref": "#/components/schemas/TimeRecord"
          },
          "website": {
            "type": "object",
            "nullable": true,
            "properties": {
              "url": {
                "type": "string"
              },
              "title": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "status"
        ]
      },
      "TimerRequest": {
        "type": "object",
        "properties": {
          "task": {
            "type": "string",
            "description": "Task ID",
            "example": "ev:9876543210"
          },
          "userDate": {
            "type": "string",
            "example": "2018-01-16"
          },
          "comment": {
            "type": "string",
            "example": "some notes"
          }
        }
      },
      "TimeExportObject": {
        "type": "object",
        "properties": {
          "time": {
            "type": "number",
            "description": "Report time in seconds",
            "example": 7200
          },
          "date": {
            "type": "string",
            "description": "Will appear only if 'date' passed to fields parameter",
            "example": "2018-03-20"
          },
          "user": {
            "type": "object",
            "description": "Will appear only if 'user' passed to fields parameter",
            "properties": {
              "id": {
                "type": "number",
                "example": 1304
              },
              "name": {
                "type": "string",
                "example": "Chris Wonder"
              }
            }
          },
          "project": {
            "type": "object",
            "description": "Will appear only if 'project' passed to fields parameter",
            "properties": {
              "id": {
                "type": "string",
                "example": "ev:9876543210"
              },
              "name": {
                "type": "string",
                "example": "Project Name"
              },
              "workspace": {
                "type": "string",
                "example": "Project Workspace Name"
              }
            }
          },
          "task": {
            "type": "object",
            "description": "Will appear only if 'task' passed to fields parameter",
            "properties": {
              "id": {
                "type": "string",
                "example": "ev:1234567890"
              },
              "name": {
                "type": "string",
                "example": "Task Name"
              },
              "status": {
                "type": "string",
                "example": "open"
              },
              "type": {
                "type": "string",
                "example": "task"
              },
              "iteration": {
                "type": "string",
                "example": "Iteration/column/section name"
              },
              "number": {
                "type": "number",
                "example": 123
              },
              "dueAt": {
                "type": "string",
                "example": "2018-01-20"
              }
            }
          }
        },
        "required": [
          "time"
        ]
      },
      "EstimateExportObject": {
        "type": "object",
        "properties": {
          "time": {
            "$ref": "#/components/schemas/TaskTime"
          },
          "estimate": {
            "$ref": "#/components/schemas/TaskEstimate"
          },
          "project": {
            "type": "object",
            "description": "Will appear only if 'project' passed to fields parameter",
            "properties": {
              "id": {
                "type": "string",
                "example": "ev:9876543210"
              },
              "name": {
                "type": "string",
                "example": "Project Name"
              },
              "workspace": {
                "type": "string",
                "example": "Project Workspace Name"
              }
            }
          },
          "task": {
            "type": "object",
            "description": "Will appear only if 'task' passed to fields parameter",
            "properties": {
              "id": {
                "type": "string",
                "example": "ev:1234567890"
              },
              "name": {
                "type": "string",
                "example": "Task Name"
              },
              "status": {
                "type": "string",
                "example": "open"
              },
              "type": {
                "type": "string",
                "example": "task"
              },
              "iteration": {
                "type": "string",
                "example": "Iteration/column/section name"
              },
              "number": {
                "type": "number",
                "example": 123
              },
              "dueAt": {
                "type": "string",
                "example": "2018-01-20"
              }
            }
          }
        }
      },
      "TimeRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Time record ID",
            "example": 2660155
          },
          "time": {
            "type": "number",
            "description": "Time recorded in seconds",
            "example": 3600
          },
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 1304
          },
          "date": {
            "type": "string",
            "description": "Date",
            "example": "2018-01-20"
          },
          "task": {
            "$ref": "#/components/schemas/Task"
          },
          "isLocked": {
            "type": "boolean",
            "example": false
          },
          "isInvoiced": {
            "type": "boolean",
            "example": false
          },
          "comment": {
            "type": "string",
            "example": "some notes"
          }
        },
        "required": [
          "id",
          "time",
          "user",
          "date"
        ]
      },
      "TimeRecordExtended": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Time record ID",
            "example": 2660155
          },
          "time": {
            "type": "number",
            "description": "Time recorded in seconds",
            "example": 3600
          },
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 1304
          },
          "date": {
            "type": "string",
            "description": "Date",
            "example": "2018-01-20"
          },
          "task": {
            "$ref": "#/components/schemas/Task"
          },
          "isLocked": {
            "type": "boolean",
            "example": false
          },
          "isInvoiced": {
            "type": "boolean",
            "example": false
          },
          "comment": {
            "type": "string",
            "example": "some notes"
          },
          "history": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeHistory"
            }
          },
          "createdAt": {
            "type": "string",
            "description": "Format: Y-m-d H:i:s"
          },
          "warning": {
            "type": "object",
            "nullable": true,
            "description": "Validation warning, if any."
          },
          "lockReasons": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Reasons the record is locked, if any."
          },
          "website": {
            "type": "object",
            "nullable": true,
            "properties": {
              "url": {
                "type": "string"
              },
              "title": {
                "type": "string"
              }
            }
          }
        },
        "required": [
          "id",
          "time",
          "user",
          "date"
        ]
      },
      "TimeHistory": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Time record history ID",
            "example": 4622379
          },
          "createdBy": {
            "type": "number",
            "description": "User ID",
            "example": 1304
          },
          "time": {
            "type": "number",
            "description": "Time difference in seconds",
            "example": 3600
          },
          "previousTime": {
            "type": "number",
            "description": "Previous time in seconds",
            "example": 0
          },
          "action": {
            "type": "string",
            "enum": [
              "TIMER",
              "ADD",
              "EDIT",
              "REMOVE",
              "COMMENT",
              "MOVE"
            ],
            "example": "TIMER"
          },
          "createdAt": {
            "type": "string",
            "example": "2018-01-16 12:42:59"
          }
        },
        "required": [
          "id",
          "createdBy",
          "time",
          "previousTime",
          "action"
        ]
      },
      "TimeRecordRequest": {
        "type": "object",
        "properties": {
          "time": {
            "type": "integer",
            "description": "Time in seconds",
            "example": 3600
          },
          "date": {
            "type": "string",
            "description": "Date",
            "example": "2018-01-20"
          },
          "task": {
            "type": "string",
            "description": "Task ID",
            "example": "ev:3000010034"
          },
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 1304
          },
          "comment": {
            "type": "string",
            "description": "Comment",
            "example": "some notes"
          }
        },
        "required": [
          "time"
        ]
      },
      "Invoice": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Invoice ID",
            "example": 2660155
          },
          "client": {
            "$ref": "#/components/schemas/Client"
          },
          "createdAt": {
            "type": "string",
            "example": "2018-01-16 12:42:59"
          },
          "createdBy": {
            "$ref": "#/components/schemas/User"
          },
          "dateFrom": {
            "type": "string"
          },
          "dateTill": {
            "type": "string"
          },
          "dueDate": {
            "type": "string"
          },
          "discount": {
            "type": "object",
            "properties": {
              "amount": {
                "type": "number",
                "example": 4581
              },
              "rate": {
                "type": "number",
                "example": 25
              }
            }
          },
          "expenseMask": {
            "type": "string",
            "example": "%PROJECT% :: %CATEGORY%"
          },
          "includeExpenses": {
            "type": "boolean",
            "example": true
          },
          "includeTime": {
            "type": "boolean",
            "example": true
          },
          "invoiceItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoiceItem"
            }
          },
          "issueDate": {
            "type": "string",
            "example": "2019-03-22"
          },
          "limitDateFrom": {
            "type": "string"
          },
          "limitDateTill": {
            "type": "string"
          },
          "listAmount": {
            "type": "number",
            "description": "List amount in cents (without discount and taxes)",
            "example": 18325
          },
          "netAmount": {
            "type": "number",
            "description": "Net amount in cents (without taxes but with discount applied)",
            "example": 13744
          },
          "projects": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "gh:63301595"
            ]
          },
          "publicId": {
            "type": "string",
            "example": "1020"
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "sent",
              "paid",
              "deleted",
              "partial"
            ],
            "example": "draft"
          },
          "tax": {
            "type": "object",
            "properties": {
              "id": {
                "type": "integer",
                "description": "Tax ID from a connected accounting integration (external invoices)."
              },
              "rate": {
                "type": "number",
                "example": 11
              },
              "amount": {
                "type": "number",
                "example": 1512
              }
            }
          },
          "timeMask": {
            "type": "string",
            "example": "%PROJECT%"
          },
          "totalAmount": {
            "type": "number",
            "description": "Total invoice amount in cents (with discount and taxes applied)",
            "example": 15256
          },
          "totalTime": {
            "type": "number",
            "description": "Total invoice time in seconds",
            "example": 43980
          },
          "valid": {
            "type": "boolean",
            "example": true
          }
        },
        "required": [
          "id",
          "client",
          "createdAt",
          "createdBy",
          "status"
        ]
      },
      "InvoiceItem": {
        "type": "object",
        "properties": {
          "billedTime": {
            "type": "number",
            "description": "Time in seconds",
            "example": 415860
          },
          "createdAt": {
            "type": "string",
            "example": "2017-02-22 16:11:33"
          },
          "custom": {
            "type": "boolean",
            "example": false
          },
          "id": {
            "type": "number",
            "example": 52
          },
          "listAmount": {
            "type": "number",
            "description": "Amount in cents",
            "example": 288793
          },
          "name": {
            "type": "string",
            "example": "Software Development"
          },
          "netAmount": {
            "type": "number",
            "description": "Amount in cents",
            "example": 288793
          },
          "position": {
            "type": "number",
            "example": 1
          },
          "taxable": {
            "type": "number",
            "example": 1
          },
          "totalAmount": {
            "type": "number",
            "example": 288793
          }
        }
      },
      "InvoiceCreateRequest": {
        "type": "object",
        "properties": {
          "limitDateFrom": {
            "type": "string",
            "example": "2019-03-11"
          },
          "limitDateTill": {
            "type": "string",
            "example": "2019-03-13"
          },
          "includeExpenses": {
            "type": "boolean",
            "example": true
          },
          "includeTime": {
            "type": "boolean",
            "example": true
          },
          "projects": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "gh:63301595"
            ]
          },
          "tax": {
            "type": "object",
            "description": "Tax to apply. Set `rate` (percentage), or `id` to reference a tax from a connected accounting integration.",
            "properties": {
              "id": {
                "type": "integer",
                "description": "ID of a tax in a connected accounting integration (Xero, QuickBooks, FreshBooks)"
              },
              "rate": {
                "type": "number",
                "example": 11
              }
            }
          },
          "discount": {
            "type": "number",
            "description": "Discount rate as a percentage (0-100)",
            "example": 25
          }
        }
      },
      "InvoiceRefreshRequest": {
        "type": "object",
        "properties": {
          "limitDateFrom": {
            "type": "string",
            "example": "2019-03-11"
          },
          "limitDateTill": {
            "type": "string",
            "example": "2019-03-13"
          },
          "includeExpenses": {
            "type": "boolean",
            "example": true
          },
          "includeTime": {
            "type": "boolean",
            "example": true
          },
          "projects": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "example": [
              "gh:63301595"
            ]
          },
          "expenseMask": {
            "type": "string",
            "example": "%PROJECT% :: %CATEGORY%"
          },
          "timeMask": {
            "type": "string",
            "example": "%PROJECT%"
          },
          "showRowNumbers": {
            "type": "boolean"
          }
        }
      },
      "InvoiceUpdateRequest": {
        "type": "object",
        "properties": {
          "publicId": {
            "type": "string",
            "example": "1020"
          },
          "issueDate": {
            "type": "string",
            "example": "2019-03-20"
          },
          "dueDate": {
            "type": "string",
            "example": "2019-03-20"
          },
          "reference": {
            "type": "string",
            "example": "contract"
          },
          "publicNotes": {
            "type": "string"
          },
          "tax": {
            "type": "object",
            "description": "Tax to apply. Set `rate` (percentage), or `id` to reference a tax from a connected accounting integration.",
            "properties": {
              "id": {
                "type": "integer",
                "description": "ID of a tax in a connected accounting integration (Xero, QuickBooks, FreshBooks)"
              },
              "rate": {
                "type": "number",
                "example": 11
              }
            }
          },
          "discount": {
            "type": "number",
            "description": "Discount rate as a percentage (0-100)",
            "example": 25
          },
          "manualStatus": {
            "type": "string",
            "enum": [
              "draft",
              "sent",
              "paid"
            ],
            "description": "Manually set the invoice status. Overrides the automatically derived status."
          },
          "showRowNumbers": {
            "type": "boolean"
          },
          "invoiceItems": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/InvoiceItemRequest"
            }
          }
        }
      },
      "InvoiceItemRequest": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 52
          },
          "name": {
            "type": "string",
            "example": "Software Development"
          },
          "billedTime": {
            "type": "number",
            "description": "Time in seconds",
            "example": 415860
          },
          "listAmount": {
            "type": "number",
            "description": "Amount in cents",
            "example": 288793
          },
          "taxable": {
            "type": "boolean",
            "example": false
          },
          "position": {
            "type": "number",
            "example": 1
          }
        }
      },
      "Expense": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "integer",
            "example": 2278
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttachmentDetails"
            }
          },
          "billable": {
            "type": "boolean",
            "example": true
          },
          "category": {
            "type": "number",
            "example": 236046
          },
          "date": {
            "type": "string",
            "example": "2019-04-04"
          },
          "details": {
            "type": "string",
            "example": "Transportation notes"
          },
          "id": {
            "type": "number",
            "example": 234718
          },
          "project": {
            "type": "string",
            "example": "as:333045610521453"
          },
          "quantity": {
            "type": "number",
            "example": 17
          },
          "user": {
            "type": "number",
            "example": 6
          }
        }
      },
      "ExpenseRequestCreateRequest": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "integer",
            "description": "Amount in cents.",
            "example": 2278
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Attachment IDs to link."
          },
          "billable": {
            "type": "boolean",
            "example": true
          },
          "category": {
            "type": "integer",
            "description": "Expense category ID",
            "example": 236046
          },
          "date": {
            "type": "string",
            "example": "2019-04-04"
          },
          "details": {
            "type": "string",
            "example": "Transportation notes"
          },
          "project": {
            "type": "string",
            "example": "as:333045610521453"
          },
          "quantity": {
            "type": "number",
            "example": 17
          },
          "user": {
            "type": "integer",
            "example": 6
          },
          "type": {
            "type": "string",
            "enum": [
              "separate",
              "billable",
              "cost"
            ],
            "description": "Expense type."
          }
        },
        "required": [
          "category",
          "date"
        ]
      },
      "ExpenseRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "amount": {
            "type": "integer",
            "description": "Amount in cents.",
            "example": 2278
          },
          "attachments": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Attachment IDs to link."
          },
          "billable": {
            "type": "boolean",
            "example": true
          },
          "category": {
            "type": "integer",
            "description": "Expense category ID",
            "example": 236046
          },
          "date": {
            "type": "string",
            "example": "2019-04-04"
          },
          "details": {
            "type": "string",
            "example": "Transportation notes"
          },
          "project": {
            "type": "string",
            "example": "as:333045610521453"
          },
          "quantity": {
            "type": "number",
            "example": 17
          },
          "user": {
            "type": "integer",
            "example": 6
          },
          "type": {
            "type": "string",
            "enum": [
              "separate",
              "billable",
              "cost"
            ],
            "description": "Expense type."
          }
        }
      },
      "AttachmentDetails": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 514
          },
          "name": {
            "type": "string",
            "example": "avatar.jpg"
          },
          "token": {
            "type": "string",
            "example": "9a04b8a1fb99cbfadf3386ad6a338c14"
          }
        }
      },
      "AttachmentRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "avatar.jpg"
          },
          "content": {
            "type": "string",
            "description": "Base64 file content. Only jpg, png and pdf supported"
          },
          "type": {
            "type": "string",
            "enum": [
              "assignment",
              "task",
              "user",
              "expense"
            ],
            "description": "Object the attachment is linked to. Defaults to `expense`.",
            "example": "expense"
          }
        },
        "required": [
          "name",
          "content"
        ]
      },
      "ExpenseCategory": {
        "type": "object",
        "properties": {
          "color": {
            "type": "string",
            "example": "#92dfb5"
          },
          "id": {
            "type": "number",
            "example": 236046
          },
          "name": {
            "type": "string",
            "example": "Mileage"
          },
          "unitBased": {
            "type": "boolean",
            "example": true
          },
          "unitName": {
            "type": "string",
            "example": "Miles"
          },
          "unitPrice": {
            "type": "integer",
            "example": 134
          }
        }
      },
      "ExpenseCategoryRequestCreateRequest": {
        "type": "object",
        "properties": {
          "color": {
            "type": "string",
            "example": "#92dfb5"
          },
          "name": {
            "type": "string",
            "example": "Mileage"
          },
          "unitBased": {
            "type": "boolean",
            "example": true
          },
          "unitName": {
            "type": "string",
            "example": "Miles"
          },
          "unitPrice": {
            "type": "integer",
            "description": "Price per unit in cents.",
            "example": 134
          }
        },
        "required": [
          "name",
          "color"
        ]
      },
      "ExpenseCategoryRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "color": {
            "type": "string",
            "example": "#92dfb5"
          },
          "name": {
            "type": "string",
            "example": "Mileage"
          },
          "unitBased": {
            "type": "boolean",
            "example": true
          },
          "unitName": {
            "type": "string",
            "example": "Miles"
          },
          "unitPrice": {
            "type": "integer",
            "description": "Price per unit in cents.",
            "example": 134
          }
        }
      },
      "Assignment": {
        "type": "object",
        "properties": {
          "days": {
            "type": "number",
            "description": "Number of workdays",
            "example": 10
          },
          "endDate": {
            "type": "string",
            "example": "2019-02-01"
          },
          "id": {
            "type": "number",
            "example": 41827
          },
          "project": {
            "type": "string",
            "example": "as:981141080110246"
          },
          "startDate": {
            "type": "string",
            "example": "2019-01-21"
          },
          "time": {
            "type": "number",
            "description": "Scheduled time in seconds",
            "example": 252000
          },
          "type": {
            "type": "string",
            "enum": [
              "project",
              "time-off"
            ],
            "example": "project"
          },
          "user": {
            "type": "number",
            "example": 79786
          }
        }
      },
      "TimeOff": {
        "type": "object",
        "properties": {
          "days": {
            "type": "number",
            "description": "Number of workdays",
            "example": 10
          },
          "endDate": {
            "type": "string",
            "example": "2019-02-01"
          },
          "id": {
            "type": "number",
            "example": 41827
          },
          "startDate": {
            "type": "string",
            "example": "2019-01-21"
          },
          "type": {
            "type": "string",
            "example": "time-off"
          },
          "user": {
            "type": "number",
            "example": 79786
          },
          "timeOffPeriod": {
            "type": "string",
            "enum": [
              "full-day",
              "half-of-day",
              "quarter-of-day",
              "half-and-quarter-of-day"
            ],
            "example": "full-day"
          },
          "reviewer": {
            "type": "number",
            "description": "Admin who must receive notification for approval",
            "example": 79786
          },
          "attachments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AttachmentDetails"
            }
          }
        }
      },
      "AssignmentRequestCreateRequest": {
        "type": "object",
        "properties": {
          "user": {
            "type": "integer",
            "example": 79786
          },
          "project": {
            "type": "string",
            "description": "Project encoded ID",
            "example": "as:981141080110246"
          },
          "task": {
            "type": "string",
            "description": "Task encoded ID"
          },
          "client": {
            "type": "integer",
            "description": "Client ID"
          },
          "type": {
            "type": "string",
            "enum": [
              "project",
              "client",
              "task",
              "time-off"
            ],
            "example": "project"
          },
          "startDate": {
            "type": "string",
            "description": "Format: Y-m-d",
            "example": "2019-01-21"
          },
          "endDate": {
            "type": "string",
            "description": "Format: Y-m-d",
            "example": "2019-02-01"
          },
          "time": {
            "type": "integer",
            "description": "Scheduled time in seconds",
            "example": 252000
          },
          "note": {
            "type": "string",
            "description": "Max 1000 chars"
          },
          "includeWeekends": {
            "type": "boolean"
          },
          "color": {
            "type": "string",
            "description": "Hex color #rrggbb"
          },
          "sendNotification": {
            "type": "boolean"
          },
          "forceOverride": {
            "type": "boolean",
            "example": true
          },
          "timeOffType": {
            "type": "string",
            "description": "Time-off type (only when type is `time-off`)."
          },
          "timeOffPeriod": {
            "type": "string",
            "enum": [
              "full-day",
              "half-of-day",
              "quarter-of-day",
              "half-and-quarter-of-day"
            ],
            "description": "Time-off period (only when type is `time-off`)."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "approved"
            ],
            "description": "Time-off approval status (only when type is `time-off`)."
          },
          "users": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Create the same schedule for multiple users (create only).",
            "example": [
              79786,
              80012
            ]
          },
          "reviewer": {
            "type": "integer",
            "description": "Reviewer user ID for time-off (create only)."
          }
        },
        "required": [
          "startDate",
          "endDate"
        ]
      },
      "AssignmentRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "user": {
            "type": "integer",
            "example": 79786
          },
          "project": {
            "type": "string",
            "description": "Project encoded ID",
            "example": "as:981141080110246"
          },
          "task": {
            "type": "string",
            "description": "Task encoded ID"
          },
          "client": {
            "type": "integer",
            "description": "Client ID"
          },
          "type": {
            "type": "string",
            "enum": [
              "project",
              "client",
              "task",
              "time-off"
            ],
            "example": "project"
          },
          "startDate": {
            "type": "string",
            "description": "Format: Y-m-d",
            "example": "2019-01-21"
          },
          "endDate": {
            "type": "string",
            "description": "Format: Y-m-d",
            "example": "2019-02-01"
          },
          "time": {
            "type": "integer",
            "description": "Scheduled time in seconds",
            "example": 252000
          },
          "note": {
            "type": "string",
            "description": "Max 1000 chars"
          },
          "includeWeekends": {
            "type": "boolean"
          },
          "color": {
            "type": "string",
            "description": "Hex color #rrggbb"
          },
          "sendNotification": {
            "type": "boolean"
          },
          "forceOverride": {
            "type": "boolean",
            "example": true
          },
          "timeOffType": {
            "type": "string",
            "description": "Time-off type (only when type is `time-off`)."
          },
          "timeOffPeriod": {
            "type": "string",
            "enum": [
              "full-day",
              "half-of-day",
              "quarter-of-day",
              "half-and-quarter-of-day"
            ],
            "description": "Time-off period (only when type is `time-off`)."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "approved"
            ],
            "description": "Time-off approval status (only when type is `time-off`)."
          }
        }
      },
      "TimeOffAllocationRequest": {
        "type": "object",
        "properties": {
          "startDate": {
            "type": "string",
            "example": "2019-01-01"
          },
          "endDate": {
            "type": "string",
            "example": "2019-12-31"
          },
          "contractStartDate": {
            "type": "string",
            "example": "2019-03-01"
          },
          "users": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "example": [
              79786,
              79787
            ]
          },
          "timeOffType": {
            "type": "number",
            "example": 16539
          },
          "days": {
            "type": "number",
            "example": 24
          },
          "daysCarried": {
            "type": "number",
            "example": 24
          },
          "accrualFrequency": {
            "type": "string",
            "enum": [
              "daily",
              "immediately"
            ],
            "example": "daily"
          },
          "restrictOverAllocation": {
            "type": "boolean",
            "example": false
          },
          "completed": {
            "type": "boolean",
            "example": false
          },
          "notes": {
            "type": "string",
            "example": "some notes"
          }
        }
      },
      "TimeOffAllocation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 876534
          },
          "startDate": {
            "type": "string",
            "example": "2019-01-01"
          },
          "endDate": {
            "type": "string",
            "example": "2019-12-31"
          },
          "contractStartDate": {
            "type": "string",
            "example": "2019-03-01"
          },
          "user": {
            "type": "number",
            "example": 79786
          },
          "timeOffType": {
            "type": "number",
            "example": 16539
          },
          "days": {
            "type": "number",
            "example": 24
          },
          "daysCarried": {
            "type": "number",
            "example": 24
          },
          "daysAllocated": {
            "type": "number",
            "example": 6.2
          },
          "daysUsed": {
            "type": "number",
            "example": 8
          },
          "accrualFrequency": {
            "type": "string",
            "enum": [
              "daily",
              "immediately"
            ],
            "example": "daily"
          },
          "restrictOverAllocation": {
            "type": "boolean",
            "example": false
          },
          "completed": {
            "type": "boolean",
            "example": false
          },
          "notes": {
            "type": "string",
            "example": "some notes"
          },
          "createdBy": {
            "type": "number",
            "example": 79562
          },
          "createdAt": {
            "type": "string",
            "example": "2018-06-01"
          }
        }
      },
      "TimeOffTypeRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "Sick"
          },
          "color": {
            "type": "string",
            "example": "#4babe5"
          },
          "paid": {
            "type": "boolean",
            "example": true
          },
          "description": {
            "type": "string",
            "example": "some notes"
          }
        }
      },
      "TimeOffType": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 876534
          },
          "name": {
            "type": "string",
            "example": "Sick"
          },
          "color": {
            "type": "string",
            "example": "#4babe5"
          },
          "paid": {
            "type": "boolean",
            "example": true
          },
          "description": {
            "type": "string",
            "example": "some notes"
          }
        }
      },
      "ProjectsDashboardItem": {
        "type": "object",
        "properties": {
          "projectId": {
            "type": "string",
            "example": "as:123456789012345"
          },
          "projectName": {
            "type": "string",
            "example": "Sample Project"
          },
          "projectStatus": {
            "type": "string",
            "enum": [
              "open",
              "archived"
            ],
            "example": "open"
          },
          "workspaceId": {
            "type": "string",
            "example": "as:2345678901234"
          },
          "workspaceName": {
            "type": "string",
            "example": "Team Workspace"
          },
          "clientId": {
            "type": "number",
            "example": 12345
          },
          "clientName": {
            "type": "string",
            "example": "Awesome Inc."
          },
          "billingType": {
            "type": "string",
            "enum": [
              "non_billable",
              "hourly",
              "fixed_fee"
            ],
            "example": "hourly"
          },
          "time": {
            "type": "number",
            "description": "Time total",
            "example": 7200
          },
          "billableTime": {
            "type": "number",
            "example": 3600
          },
          "nonBillableTime": {
            "type": "number",
            "example": 3600
          },
          "timerTimePc": {
            "type": "number",
            "example": 70
          },
          "billableAmount": {
            "type": "number",
            "example": 50000
          },
          "billableAmountTime": {
            "type": "number",
            "example": 40000
          },
          "billableAmountExpenses": {
            "type": "number",
            "example": 10000
          },
          "costs": {
            "type": "number",
            "example": 30000
          },
          "costsTime": {
            "type": "number",
            "example": 20000
          },
          "costsExpenses": {
            "type": "number",
            "example": 5000
          },
          "profit": {
            "type": "number",
            "example": 20000
          },
          "profitCosts": {
            "type": "number",
            "example": 3000
          },
          "uninvoicedAmount": {
            "type": "number",
            "example": 30000
          },
          "expenses": {
            "type": "number",
            "example": 17000
          },
          "billableExpenses": {
            "type": "number",
            "example": 10000
          },
          "separateExpenses": {
            "type": "number",
            "example": 2000
          }
        }
      },
      "ClientsDashboardItem": {
        "type": "object",
        "properties": {
          "clientId": {
            "type": "number",
            "example": 12345
          },
          "clientName": {
            "type": "string",
            "example": "Awesome Inc."
          },
          "time": {
            "type": "number",
            "example": 7200
          },
          "billableTime": {
            "type": "number",
            "example": 3600
          },
          "nonBillableTime": {
            "type": "number",
            "example": 3600
          },
          "timerTimePc": {
            "type": "number",
            "example": 70
          },
          "billableAmount": {
            "type": "number",
            "example": 50000
          },
          "billableAmountTime": {
            "type": "number",
            "example": 40000
          },
          "billableAmountExpenses": {
            "type": "number",
            "example": 10000
          },
          "costs": {
            "type": "number",
            "example": 30000
          },
          "costsTime": {
            "type": "number",
            "example": 20000
          },
          "costsExpenses": {
            "type": "number",
            "example": 5000
          },
          "profit": {
            "type": "number",
            "example": 20000
          },
          "profitCosts": {
            "type": "number",
            "example": 3000
          },
          "uninvoicedAmount": {
            "type": "number",
            "example": 30000
          },
          "expenses": {
            "type": "number",
            "example": 17000
          },
          "billableExpenses": {
            "type": "number",
            "example": 10000
          },
          "separateExpenses": {
            "type": "number",
            "example": 2000
          }
        }
      },
      "UsersDashboardItem": {
        "type": "object",
        "properties": {
          "memberId": {
            "type": "number",
            "example": 12345
          },
          "memberName": {
            "type": "string",
            "example": "John Bender"
          },
          "memberHeadline": {
            "type": "string",
            "example": "CEO"
          },
          "memberStatus": {
            "type": "string",
            "enum": [
              "active",
              "invited",
              "pending",
              "removed"
            ],
            "example": "active"
          },
          "memberAvatarUrl": {
            "type": "string",
            "example": "https://..."
          },
          "time": {
            "type": "number",
            "example": 7200
          },
          "billableTime": {
            "type": "number",
            "example": 3600
          },
          "nonBillableTime": {
            "type": "number",
            "example": 3600
          },
          "timeOffTime": {
            "type": "number",
            "example": 3600
          },
          "timeOffDays": {
            "type": "number",
            "example": 1
          },
          "timerTimePc": {
            "type": "number",
            "example": 70
          },
          "billableAmount": {
            "type": "number",
            "example": 50000
          },
          "billableAmountTime": {
            "type": "number",
            "example": 40000
          },
          "billableAmountExpenses": {
            "type": "number",
            "example": 10000
          },
          "costs": {
            "type": "number",
            "example": 30000
          },
          "costsTime": {
            "type": "number",
            "example": 20000
          },
          "costsTimeOff": {
            "type": "number",
            "example": 5000
          },
          "costsExpenses": {
            "type": "number",
            "example": 5000
          },
          "profit": {
            "type": "number",
            "example": 20000
          },
          "profitCosts": {
            "type": "number",
            "example": 3000
          },
          "uninvoicedAmount": {
            "type": "number",
            "example": 30000
          },
          "expenses": {
            "type": "number",
            "example": 17000
          },
          "billableExpenses": {
            "type": "number",
            "example": 10000
          },
          "separateExpenses": {
            "type": "number",
            "example": 2000
          }
        }
      },
      "TimecardHistory": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "description": "What data are changed",
            "enum": [
              "clock-in",
              "clock-out",
              "break"
            ],
            "example": "clock-in"
          },
          "previousTime": {
            "type": "string",
            "description": "Old value for clockIn, clockOut or break",
            "example": "08:00"
          },
          "time": {
            "type": "string",
            "description": "New value for clockIn, clockOut or break",
            "example": "09:00"
          },
          "trigger": {
            "type": "string",
            "description": "Action trigger",
            "enum": [
              "manually",
              "timer",
              "button",
              "day-end",
              "idle-state"
            ],
            "example": "manually"
          }
        }
      },
      "Timecard": {
        "type": "object",
        "properties": {
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 69
          },
          "clockIn": {
            "type": "string",
            "description": "Clock-in time in user timezone",
            "example": "09:00"
          },
          "clockOut": {
            "type": "string",
            "description": "Clock-out time in user timezone",
            "example": "18:00"
          },
          "breakTime": {
            "type": "number",
            "description": "Breaks duration in seconds",
            "example": 3600
          },
          "workTime": {
            "type": "number",
            "description": "Working time in seconds",
            "example": 28800
          },
          "history": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimecardHistory"
            }
          },
          "date": {
            "type": "string",
            "description": "Format: Y-m-d"
          },
          "weekId": {
            "type": "integer",
            "description": "Week identifier (YYWW)."
          },
          "isLocked": {
            "type": "boolean"
          },
          "invalid": {
            "type": "object",
            "nullable": true,
            "description": "Validation issues for the timecard, if any."
          },
          "lockReasons": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "user",
          "workTime"
        ]
      },
      "Week": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 2535
          },
          "from": {
            "type": "string",
            "example": "2025-08-25"
          },
          "to": {
            "type": "string",
            "example": "2025-08-31"
          },
          "beginningOfWeek": {
            "type": "number",
            "description": "0 if Sunday, 1 if Monday",
            "example": 1
          }
        }
      },
      "DailyTime": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "example": "25-08-2025"
          },
          "time": {
            "type": "number",
            "description": "Total daily time in seconds",
            "example": 18000
          },
          "timeWithoutTask": {
            "type": "number",
            "description": "Time tracked without task",
            "example": 7200
          },
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 14856
          }
        }
      },
      "Timesheet": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Timesheet ID",
            "example": 148562535
          },
          "week": {
            "$ref": "#/components/schemas/Week"
          },
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 14856
          },
          "tasks": {
            "type": "array",
            "description": "List of tasks added in the timesheet",
            "items": {
              "$ref": "#/components/schemas/Task"
            }
          },
          "dailyTime": {
            "type": "array",
            "description": "Daily time",
            "items": {
              "$ref": "#/components/schemas/DailyTime"
            }
          },
          "taskTime": {
            "type": "array",
            "description": "List of task time records",
            "items": {
              "$ref": "#/components/schemas/TaskTime"
            }
          },
          "approval": {
            "$ref": "#/components/schemas/TimesheetApproval"
          },
          "timecards": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Timecard"
            }
          },
          "timeOffAssignments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeOff"
            }
          }
        }
      },
      "TimesheetApproval": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Timesheet ID",
            "example": 148562535
          },
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 14856
          },
          "weekId": {
            "type": "number",
            "example": 2535
          },
          "reviewer": {
            "type": "number",
            "description": "Reviewer User ID",
            "example": 14854
          },
          "history": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimesheetApprovalHistory"
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "rejected",
              "approved",
              "partial_approved",
              "discarded"
            ]
          },
          "totalTime": {
            "type": "integer",
            "description": "Total approved time in seconds.",
            "nullable": true
          }
        }
      },
      "TimesheetApprovalRequest": {
        "type": "object",
        "properties": {
          "comment": {
            "type": "string",
            "example": "some text"
          },
          "reviewer": {
            "type": "number",
            "description": "User ID, must be admin in team",
            "example": 14854
          },
          "sendNotification": {
            "type": "boolean",
            "example": false
          }
        }
      },
      "TimesheetApprovalReviewRequest": {
        "type": "object",
        "properties": {
          "days": {
            "$ref": "#/components/schemas/ApprovalHistoryDays"
          },
          "status": {
            "type": "string",
            "enum": [
              "approved",
              "rejected"
            ],
            "example": "approved"
          },
          "comment": {
            "type": "string",
            "example": "some text"
          },
          "sendNotification": {
            "type": "boolean",
            "example": false
          }
        }
      },
      "TimesheetApprovalHistory": {
        "type": "object",
        "properties": {
          "action": {
            "type": "string",
            "enum": [
              "submitted",
              "rejected",
              "approved",
              "discarded"
            ],
            "example": "submitted"
          },
          "days": {
            "$ref": "#/components/schemas/ApprovalHistoryDays"
          },
          "user": {
            "type": "number",
            "description": "User ID",
            "example": 2535
          },
          "comment": {
            "type": "string",
            "example": "some text"
          },
          "createdAt": {
            "type": "string",
            "description": "Datetime when action was created",
            "example": "2025-08-05 16:17:14"
          }
        }
      },
      "ApprovalHistoryDays": {
        "type": "object",
        "properties": {
          "monday": {
            "type": "boolean",
            "example": true
          },
          "tuesday": {
            "type": "boolean",
            "example": true
          },
          "wednesday": {
            "type": "boolean",
            "example": true
          },
          "thursday": {
            "type": "boolean",
            "example": true
          },
          "friday": {
            "type": "boolean",
            "example": true
          },
          "saturday": {
            "type": "boolean",
            "example": false
          },
          "sunday": {
            "type": "boolean",
            "example": false
          }
        }
      },
      "Field": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "description": "Custom field ID",
            "example": 406
          },
          "name": {
            "type": "string",
            "example": "field name"
          },
          "type": {
            "type": "string",
            "example": "date"
          },
          "format": {
            "$ref": "#/components/schemas/FieldFormat"
          },
          "options": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FieldOption"
            }
          },
          "position": {
            "type": "number",
            "example": 1
          },
          "icon": {
            "type": "string",
            "description": "Field icon name"
          }
        }
      },
      "FieldRequestCreateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "field name"
          },
          "type": {
            "type": "string",
            "enum": [
              "number",
              "text",
              "select",
              "date"
            ],
            "example": "select"
          },
          "format": {
            "$ref": "#/components/schemas/FieldFormat"
          },
          "icon": {
            "type": "string"
          },
          "options": {
            "type": "array",
            "description": "Up to 10 options, required when `type` is `select`.",
            "items": {
              "$ref": "#/components/schemas/FieldOption"
            }
          }
        },
        "required": [
          "name",
          "type"
        ]
      },
      "FieldRequestUpdateRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "example": "field name"
          },
          "type": {
            "type": "string",
            "enum": [
              "number",
              "text",
              "select",
              "date"
            ],
            "example": "select"
          },
          "format": {
            "$ref": "#/components/schemas/FieldFormat"
          },
          "icon": {
            "type": "string"
          },
          "options": {
            "type": "array",
            "description": "Up to 10 options, required when `type` is `select`.",
            "items": {
              "$ref": "#/components/schemas/FieldOption"
            }
          }
        }
      },
      "FieldOption": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number",
            "example": 806
          },
          "name": {
            "type": "string",
            "example": "option value"
          },
          "color": {
            "type": "string",
            "example": "#FC5500"
          }
        }
      },
      "FieldFormat": {
        "type": "object",
        "properties": {
          "format": {
            "type": "string",
            "enum": [
              "number",
              "currency",
              "percent",
              "label"
            ]
          },
          "type": {
            "type": "string",
            "description": "Optional type for date field",
            "enum": [
              "date",
              "dob"
            ]
          },
          "decimals": {
            "type": "number",
            "example": 2
          },
          "label": {
            "type": "string",
            "description": "Label up to 8 symbols",
            "example": "US$"
          },
          "labelAt": {
            "type": "string",
            "description": "Label position left/right",
            "enum": [
              "left",
              "right"
            ]
          }
        }
      },
      "FieldOrderRequest": {
        "type": "object",
        "properties": {
          "order": {
            "type": "array",
            "description": "Custom field ID",
            "items": {
              "type": "number"
            }
          }
        },
        "required": [
          "order"
        ]
      }
    }
  },
  "security": [
    {
      "ApiKeyAuth": []
    }
  ]
}
