openapi: 3.1.0 info: title: API Reference version: 1.0.0 paths: /oauth/token: post: operationId: post-oauth-token summary: Get OAuth Token description: Exchange credentials for an access token. Supports `client_credentials` grant type. tags: - oauth parameters: - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful token response content: application/json: schema: $ref: '#/components/schemas/Oauth_post_oauth_token_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: OAuth 2.0 parameters content: application/json: schema: type: object properties: grant_type: $ref: '#/components/schemas/OauthTokenPostRequestBodyContentApplicationXWwwFormUrlencodedSchemaGrantType' description: Grant type for the request. Must be 'client_credentials'. client_id: type: string description: The client ID issued to the client. client_secret: type: string description: The client secret issued to the client. scope: type: string description: The scope of the access request. required: - grant_type - client_id - client_secret /accounts/{id}/companies: get: operationId: get-accounts-id-companies summary: Retrieve companies for an account description: Returns a paginated list of companies associated with the specified account. tags: - accounts parameters: - name: id in: path description: Account ID required: true schema: type: string - name: search in: query description: Search term for company name required: false schema: type: string - name: limit in: query description: Number of items per page required: false schema: type: integer - name: page in: query description: Page number for pagination required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated company list content: application/json: schema: $ref: '#/components/schemas/Accounts_get_accounts_id_companies_Response_200' /accounts/{id}/locations: get: operationId: get-accounts-id-locations summary: Retrieve locations for an account description: Returns a paginated list of locations associated with the specified account. tags: - accounts parameters: - name: id in: path description: Account ID required: true schema: type: string - name: search in: query description: Search term for location name required: false schema: type: string - name: limit in: query description: Number of items per page required: false schema: type: integer - name: page in: query description: Page number for pagination required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated location list content: application/json: schema: $ref: '#/components/schemas/Accounts_get_accounts_id_locations_Response_200' /accounts: get: operationId: get-accounts-root summary: Retrieve accounts for the authenticated user description: >- Returns a paginated list of Ottimate accounts that the authenticated user has access to, based on partner associations linked to the OAuth client credentials. tags: - accounts parameters: - name: search in: query description: Search term to filter accounts by name required: false schema: type: string - name: limit in: query description: Number of items per page required: false schema: type: integer - name: page in: query description: Page number for pagination required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated account list content: application/json: schema: $ref: '#/components/schemas/Accounts_get_accounts_root_Response_200' /vendors: get: operationId: get-vendors-root summary: Retrieve a paginated list of accounting vendors description: >- Returns a paginated list of accounting vendors, filterable by company. The `detail=basic` query parameter returns a simplified response. tags: - vendors parameters: - name: ottimate_company_id in: query description: Filter vendors by company ID required: false schema: type: integer - name: detail in: query description: Specify the level of detail in the response required: false schema: $ref: '#/components/schemas/VendorsGetParametersDetail' - name: last_modified_date_from in: query description: >- Filter vendors last modified on or after this date. Requires ottimate_company_id. Accepted formats: YYYY-MM-DD or YYYY-MM-DD HH:MM:SS. All times are interpreted as UTC. A date-only value is treated as 00:00:00 UTC. required: false schema: type: string - name: last_modified_date_from_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string - name: last_modified_date_to in: query description: >- Filter vendors last modified on or before this date. Requires ottimate_company_id. Accepted formats: YYYY-MM-DD or YYYY-MM-DD HH:MM:SS. All times are interpreted as UTC. A date-only value is treated as 00:00:00 UTC — to include the full day pass an explicit time (e.g. 2024-12-31 23:59:59). required: false schema: type: string - name: last_modified_date_to_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string - name: page in: query description: Page number (default 1) required: false schema: type: integer - name: limit in: query description: Number of results per page (default 20) required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated vendor list content: application/json: schema: $ref: '#/components/schemas/Vendors_get_vendors_root_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: post-vendors-root summary: Create a single new accounting vendor description: >- Creates a new vendor with the provided details. The `erp_vendor_id` is required and will be mapped to both `accounting_id` and `dd_unique_key`. tags: - vendors parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Successfully created content: application/json: schema: $ref: '#/components/schemas/Vendors_post_vendors_root_Response_201' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: ottimate_company_id: type: integer erp_vendor_name: type: string erp_vendor_id: type: string email: type: string phone: type: string net_terms: type: string payment_method: $ref: '#/components/schemas/VendorsPostRequestBodyContentApplicationJsonSchemaPaymentMethod' description: (Optional) Vendor payment method city: type: string description: (Optional) Vendor city state: type: string description: (Optional) Vendor state zipcode: type: string description: (Optional) Vendor zipcode address_line_1: type: string description: (Optional) Vendor address line 1 address_line_2: type: string description: (Optional) Vendor address line 2 required: - ottimate_company_id - erp_vendor_name - erp_vendor_id /vendors/{id}: get: operationId: get-vendors-id summary: Retrieve a specific vendor by ID description: Returns detailed information for a single accounting vendor using its unique ID. tags: - vendors parameters: - name: id in: path description: The unique ID of the vendor required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with vendor details content: application/json: schema: $ref: '#/components/schemas/Vendors_get_vendors_id_Response_200' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /vendors/bulk: post: operationId: post-vendors-bulk summary: Create or update multiple accounting vendors description: Allows for the creation or updating of multiple vendors in a single request. Maximum 100 vendors per request. tags: - vendors parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Successfully created or updated content: application/json: schema: $ref: '#/components/schemas/Vendors_post_vendors_bulk_Response_201' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: ottimate_company_id: type: integer vendors: type: array items: $ref: '#/components/schemas/VendorsBulkPostRequestBodyContentApplicationJsonSchemaVendorsItems' required: - ottimate_company_id /dimensions: get: operationId: get-dimensions-root summary: Retrieve a paginated list of dimensions description: >- Returns a paginated list of dimensions, filterable by company and type. The `detail=basic` query parameter returns a simplified response. tags: - dimensions parameters: - name: ottimate_company_id in: query description: Filter dimensions by company ID required: false schema: type: integer - name: erp_type in: query description: Filter dimensions by ERP type required: false schema: type: string - name: detail in: query description: Specify the level of detail in the response required: false schema: $ref: '#/components/schemas/DimensionsGetParametersDetail' - name: page in: query description: Page number (default 1) required: false schema: type: integer - name: limit in: query description: Number of results per page (default 20) required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated dimension list content: application/json: schema: $ref: '#/components/schemas/Dimensions_get_dimensions_root_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: post-dimensions-root summary: Create a single new dimension description: >- Creates a new dimension with the provided details. The `reference_id` and `erp_dimension_id` are required for a successful creation. tags: - dimensions parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Successfully created content: application/json: schema: $ref: '#/components/schemas/Dimensions_post_dimensions_root_Response_201' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: ottimate_company_id: type: integer description: The Ottimate company ID this dimension belongs to erp_type: type: string description: >- The dimension category label as displayed in the client's ERP system (e.g., 'Account', 'GLACCOUNT', 'Department'). This is client-specific. ottimate_type: $ref: '#/components/schemas/DimensionsPostRequestBodyContentApplicationJsonSchemaOttimateType' description: Ottimate's standardized dimension type code for consistent categorization. name: type: string description: Display name of the dimension code: type: string description: The GL code or short identifier for this dimension in the client's ERP system reference_id: type: string description: >- A unique reference identifier that tracks this dimension across all client systems (ERP, inventory management, Ottimate) erp_dimension_id: type: string description: The identifier assigned to this dimension by the client's ERP software required: - ottimate_company_id - erp_type - ottimate_type - name - code - reference_id - erp_dimension_id /dimensions/{id}: get: operationId: get-dimensions-id summary: Retrieve a specific dimension by ID description: Returns detailed information for a single dimension using its unique ID. tags: - dimensions parameters: - name: id in: path description: The unique ID of the dimension required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with dimension details content: application/json: schema: $ref: '#/components/schemas/Dimensions_get_dimensions_id_Response_200' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /dimensions/bulk: post: operationId: post-dimensions-bulk summary: Create or update multiple dimensions description: >- Allows for the creation or updating of multiple dimensions in a single request. The request body should contain a `ottimate_company_id` and an array of `dimensions`. Maximum 100 dimensions per request. tags: - dimensions parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Successfully created or updated content: application/json: schema: $ref: '#/components/schemas/Dimensions_post_dimensions_bulk_Response_201' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: ottimate_company_id: type: integer description: The Ottimate company ID these dimensions belong to dimensions: type: array items: $ref: '#/components/schemas/DimensionsBulkPostRequestBodyContentApplicationJsonSchemaDimensionsItems' required: - ottimate_company_id - dimensions /purchase-orders: get: operationId: get-purchase-orders-root summary: Retrieve a paginated list of purchase orders description: Returns a paginated list of purchase orders, filterable by company, location, vendor, status, and date range. tags: - purchaseOrders parameters: - name: ottimate_company_id in: query description: Filter by company ID required: false schema: type: integer - name: ottimate_location_id in: query description: Filter by location ID required: false schema: type: integer - name: erp_vendor_id in: query description: Filter by ERP vendor ID (external vendor identifier) required: false schema: type: string - name: status in: query description: Filter by PO status required: false schema: $ref: '#/components/schemas/PurchaseOrdersGetParametersStatus' - name: date_from in: query description: Filter by start date (YYYY-MM-DD) required: false schema: type: string format: date - name: date_to in: query description: Filter by end date (YYYY-MM-DD) required: false schema: type: string format: date - name: expand in: query description: >- Comma-separated list of fields to expand. Supported values: items. When expand=items is used, date_from and date_to must both be provided and within a 30-day window. required: false schema: type: string - name: external_id in: query description: Filter by external (ERP) purchase order ID required: false schema: type: string - name: page in: query description: Page number (default 1) required: false schema: type: integer - name: limit in: query description: Number of results per page (default 20) required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated purchase order list content: application/json: schema: $ref: '#/components/schemas/Purchase-Orders_get_purchase-orders_root_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: post-purchase-orders-root summary: Create a single purchase order description: >- Creates a new purchase order with the provided details. The `po_number` field is required and must be provided by the client (no auto-generation). tags: - purchaseOrders parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Successfully created content: application/json: schema: $ref: '#/components/schemas/PurchaseOrderCreateResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: $ref: '#/components/schemas/PurchaseOrderCreateRequest' /purchase-orders/{id}: get: operationId: get-purchase-orders-id summary: Retrieve a specific purchase order by ID description: Returns detailed information for a single purchase order including all line items. tags: - purchaseOrders parameters: - name: id in: path description: The unique ID of the purchase order required: true schema: type: string format: uuid - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with purchase order details content: application/json: schema: $ref: '#/components/schemas/PurchaseOrderDetail' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' patch: operationId: patch-purchase-orders-id summary: Update an existing purchase order description: >- Updates a purchase order. Note: `status`, `po_number`, `external_id`, `erp_vendor_id`, and `ottimate_location_id` cannot be changed. tags: - purchaseOrders parameters: - name: id in: path description: The unique ID of the purchase order required: true schema: type: string format: uuid - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successfully updated content: application/json: schema: $ref: '#/components/schemas/PurchaseOrderUpdateResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: erp_vendor_name: type: string description: Vendor name from ERP system date: type: string format: date total_amount: type: number format: double tax: type: number format: double freight: type: number format: double miscellaneous_charges: type: number format: double invoice_number_ref: type: string is_2_way: type: boolean items: type: array items: $ref: '#/components/schemas/PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaItemsItems' description: >- Items with `id` update the existing item. Items without `id` create a new item. When creating, `name`, `quantity`, and `price` are required. custom_fields: $ref: '#/components/schemas/PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaCustomFields' description: Optional custom fields configured for this company's purchase orders /purchase-orders/bulk: post: operationId: post-purchase-orders-bulk summary: Bulk create or update purchase orders description: >- Creates or updates multiple purchase orders in a single request. Maximum 100 purchase orders and 1000 total line items per request. Processing is always asynchronous via Celery and returns a batch tracking ID for polling progress. tags: - purchaseOrders parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '202': description: Asynchronous processing started. Poll batch_url for progress. content: application/json: schema: $ref: '#/components/schemas/BulkUpsertAsyncResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: $ref: '#/components/schemas/PurchaseOrderBulkUpsertRequest' /receipts: get: operationId: get-receipts-root summary: Retrieve a paginated list of receipts description: Returns a paginated list of receipts, filterable by company, location, purchase order, status, and date range. tags: - receipts parameters: - name: ottimate_company_id in: query description: Filter by company ID required: false schema: type: integer - name: ottimate_location_id in: query description: Filter by location ID required: false schema: type: integer - name: ottimate_po_id in: query description: Filter by purchase order ID required: false schema: type: string - name: status in: query description: Filter by receipt status required: false schema: type: string - name: date_from in: query description: Filter by start date (YYYY-MM-DD) required: false schema: type: string format: date - name: date_to in: query description: Filter by end date (YYYY-MM-DD) required: false schema: type: string format: date - name: expand in: query description: >- Comma-separated list of fields to expand. Supported values: items. When expand=items is used, date_from and date_to must both be provided and within a 30-day window. required: false schema: type: string - name: external_id in: query description: Filter by external (ERP) receipt ID required: false schema: type: string - name: page in: query description: Page number (default 1) required: false schema: type: integer - name: limit in: query description: Number of results per page (default 20) required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated receipt list content: application/json: schema: $ref: '#/components/schemas/Receipts_get_receipts_root_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: post-receipts-root summary: Create a single receipt description: >- Creates a new receipt linked to an existing purchase order. The `receipt_number` field is required and must be provided by the client tags: - receipts parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Successfully created content: application/json: schema: $ref: '#/components/schemas/ReceiptCreateResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: $ref: '#/components/schemas/ReceiptCreateRequest' /receipts/{id}: get: operationId: get-receipts-id summary: Retrieve a specific receipt by ID description: Returns detailed information for a single receipt including all line items. tags: - receipts parameters: - name: id in: path description: The unique ID of the receipt required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with receipt details content: application/json: schema: $ref: '#/components/schemas/ReceiptDetail' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' patch: operationId: patch-receipts-id summary: Update an existing receipt description: 'Updates a receipt. Note: `status`, `receipt_number`, `external_id`, and `ottimate_po_id` cannot be changed.' tags: - receipts parameters: - name: id in: path description: The unique ID of the receipt required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successfully updated content: application/json: schema: $ref: '#/components/schemas/ReceiptUpdateResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: receipt_number: type: string date: type: string format: date total_amount: type: number format: double invoice_number_ref: type: string note: type: string items: type: array items: $ref: '#/components/schemas/ReceiptsIdPatchRequestBodyContentApplicationJsonSchemaItemsItems' description: >- Items with `id` update the existing item. Items without `id` create a new item. When creating, `quantity` and one of `ottimate_po_item_id`, `po_external_item_id`, or `sku` are required. /receipts/bulk: post: operationId: post-receipts-bulk summary: Bulk create or update receipts description: >- Creates or updates multiple receipts in a single request. Maximum 100 receipts and 1000 total line items per request. Processing is always asynchronous via Celery and returns a batch tracking ID for polling progress. tags: - receipts parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '202': description: Asynchronous processing started. Poll batch_url for progress. content: application/json: schema: $ref: '#/components/schemas/ReceiptBulkUpsertAsyncResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: $ref: '#/components/schemas/ReceiptBulkUpsertRequest' /invoices: get: operationId: get-invoices-root summary: Retrieve paginated list of invoices description: >- Returns a paginated list of invoices with comprehensive filtering capabilities. ### Filtering Options - Date range filtering by creation date (from/to dates) - Date range filtering by last modified date (last_modified_date_from/last_modified_date_to) - Filter by the user who last modified the invoice (last_modified_user_id) - Vendor filtering by name or ID - Location filtering by ottimate_location_id - Status filtering (approved, incomplete, processing, etc.) ### Pagination Results are returned in pages with configurable size (1-100 items per page). Results are ordered by creation date (newest first). tags: - invoices parameters: - name: page in: query description: Page number for pagination required: false schema: type: integer - name: limit in: query description: Number of items per page required: false schema: type: integer - name: date_from in: query description: >- Filter invoices from this date. Accepted formats: YYYY-MM-DD or YYYY-MM-DD HH:MM:SS. All times are interpreted as UTC. When using expand=items, either date_from or last_modified_date_from is required. required: false schema: type: string - name: date_from_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string format: date-time - name: date_to in: query description: >- Filter invoices to this date. Accepted formats: YYYY-MM-DD or YYYY-MM-DD HH:MM:SS. All times are interpreted as UTC. When using expand=items and omitted, defaults to the current UTC datetime. required: false schema: type: string - name: date_to_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string format: date-time - name: status in: query description: Filter by invoice status required: false schema: $ref: '#/components/schemas/InvoicesGetParametersStatus' - name: ottimate_location_ids in: query description: Filter by a comma-separated list of location IDs required: false schema: type: string - name: payment_status in: query description: Filter by payment status required: false schema: $ref: '#/components/schemas/InvoicesGetParametersPaymentStatus' - name: ottimate_vendor_id in: query description: Filter by specific vendor ID required: false schema: type: string - name: expand in: query description: >- Comma-separated list of fields to expand. Options: items. When used, returns full line item details along with catalog entry details. Requires date_from or last_modified_date_from (within a 30-day window); date_to and last_modified_date_to are optional and default to the current datetime if omitted. required: false schema: type: string - name: invoice_ids in: query description: Filter by a comma-separated list of invoice IDs required: false schema: type: string - name: search in: query description: Search across multiple invoice fields required: false schema: type: string - name: custom_fields in: query description: >- Filter by custom field values. Pass a JSON object where each key is a custom field name and each value is the exact value to match. Multiple keys are ANDed together. required: false schema: type: string - name: last_modified_date_from in: query description: >- Filter invoices last modified on or after this date. Accepted formats: YYYY-MM-DD or YYYY-MM-DD HH:MM:SS. All times are interpreted as UTC. When using expand=items, either last_modified_date_from or date_from is required. required: false schema: type: string - name: last_modified_date_from_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string - name: last_modified_date_to in: query description: >- Filter invoices last modified on or before this date. Accepted formats: YYYY-MM-DD or YYYY-MM-DD HH:MM:SS. All times are interpreted as UTC. When using expand=items and omitted, defaults to the current UTC datetime. required: false schema: type: string - name: last_modified_date_to_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string - name: last_modified_user_id in: query description: Filter invoices by the ID of the user who last modified them required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated invoice list content: application/json: schema: $ref: '#/components/schemas/Invoices_get_invoices_root_Response_200' '400': description: Bad request - Invalid parameters provided content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error - Server-side processing error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /invoices/{id}: get: operationId: get-invoices-id summary: Retrieve detailed information for a specific invoice description: >- Returns **comprehensive details** for a single invoice including all metadata, processing information, and payment status. ## 📋 What You Get This endpoint provides the **complete invoice record** with: - 🧾 **Full invoice metadata** (dates, amounts, status) - 🏢 **Vendor information** and contact details - 📍 **Location** where invoice was received - 💳 **Payment information** (when invoice is paid) - ⚠️ **Error details** (if invoice has processing issues) - 📤 **Export tracking** (integration status) ## 🔍 Usage Examples ### Basic Retrieval ```bash curl -H "X-Api-Key: your-api-key" \ https://api.acme.com/v1/invoices/550e8400-e29b-41d4-a716-446655440000 ``` ### With Version Header ```bash curl -H "X-Api-Key: your-api-key" \ -H "X-API-Version: 1.0.0" \ https://api.acme.com/v1/invoices/550e8400-e29b-41d4-a716-446655440000 ``` ## ⚡ Performance Notes - **Response time**: Typically < 100ms - **Caching**: Results cached for 5 minutes - **Rate limits**: Applies to your overall API quota > 💡 **Tip**: Use this endpoint after getting results from the list endpoint to get full details for specific invoices. tags: - invoices parameters: - name: id in: path description: Invoice UUID - Unique identifier of the invoice to retrieve required: true schema: type: string - name: expand in: query description: >- Comma-separated list of fields to expand. Options: `history`, `gl_splits`. Use `history` to include the full audit log. Use `gl_splits` to include GL account splits (real splits or virtual splits derived from line-item mappings). required: false schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with invoice details content: application/json: schema: $ref: '#/components/schemas/InvoiceDetailObject' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error - Server-side processing error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' patch: operationId: patch-invoices-id summary: Update invoice header, line items, and dimensions description: >- Updates an invoice along with its line items and dimensions. ### Features - Update invoice header fields (date, amount, vendor, notes, etc.) - Create new line items (omit `id`) - Update existing line items (include `id`) - Set, update, or remove header and item-level dimensions - Update custom metadata fields at header and item level (requires account-level custom field spec configuration) ### Use Cases - Invoice corrections - Invoice reconciliation with updated line items - Adding or updating dimensions after initial invoice creation - Multi-field updates in a single request tags: - invoices parameters: - name: id in: path description: Invoice ID to update required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Invoice updated successfully content: application/json: schema: $ref: '#/components/schemas/InvoiceDetailObject' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '412': description: Precondition failed - concurrent modification content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error - Server-side processing error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: Invoice update payload with optional items array content: application/json: schema: type: object properties: ottimate_location_id: type: integer description: The ID of the location for this invoice. erp_vendor_id: type: string description: The ERP ID of the vendor for this invoice. erp_vendor_name: type: string description: ERP vendor name. Required when creating a new vendor via erp_vendor_id. invoice_number: type: string invoice_date: type: string format: date due_date: type: string format: date posting_date: type: string format: date total_amount: type: number format: double total_tax: type: number format: double discount_amount: type: number format: double purchase_order: type: string notes: type: string currency: type: string type: $ref: '#/components/schemas/InvoicesIdPatchRequestBodyContentApplicationJsonSchemaType' description: Type of document. dimensions: $ref: '#/components/schemas/InvoicesIdPatchRequestBodyContentApplicationJsonSchemaDimensions' description: >- Header-level dimension mappings. Keys are dimension types (e.g., 'DEPARTMENT') and values are `erp_dimension_id` strings from the `GET /dimensions` endpoint. Replaces all header dimensions with the provided set. Omit the field entirely to preserve existing dimensions. Pass `{}` to clear all header dimensions. custom_fields: oneOf: - $ref: '#/components/schemas/InvoicesIdPatchRequestBodyContentApplicationJsonSchemaCustomFields' - type: 'null' description: >- Header-level custom metadata fields. Replaces the stored custom fields with the provided object — any keys not included are reset to their configured default values. **Requirements**: Custom fields must be configured for your account before use. Returns a `400` error if no spec is found or if unrecognised keys are sent. **Behaviour**: Omit the field entirely to preserve existing custom fields. items: type: array items: $ref: '#/components/schemas/InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItems' description: >- Line items to create or update. Include `id` to update an existing item, omit `id` to create a new item. image_urls: type: array items: type: string format: uri description: >- Replaces all existing invoice images with the provided URLs. Pass an empty array to delete all images. Omit the field entirely to leave existing images unchanged. Supported formats: PDF, JPG, JPEG, PNG. raw_images: type: array items: $ref: '#/components/schemas/InvoicesIdPatchRequestBodyContentApplicationJsonSchemaRawImagesItems' description: >- Replaces all existing invoice images with the provided base64-encoded images. Pass an empty array to delete all images. Omit the field entirely to leave existing images unchanged. Supported formats: PDF, JPG, JPEG, PNG. /invoices/upload: post: operationId: post-invoices-upload summary: Create invoice from file upload or URL download description: >- Creates a new invoice by uploading a file directly or downloading from a URL. This endpoint combines file processing, S3 storage, and invoice creation in a single API call. ### File Processing - Multiple formats supported: PDF, JPG, PNG, TIFF - Direct file upload via multipart form data - URL-based file download and ingestion - Automatic format and size validation - Secure S3 storage integration ### Invoice Creation Features - Single-step upload and creation process - Custom metadata support for tracking - Location assignment - Email sender tracking - Integration with existing document processing pipeline ### Use Cases - Email attachment processing - Mobile application file uploads - Webhook-based ingestion from vendor portals - Programmatic batch processing ### Technical Specifications - File size limit: 25MB per file - Supported formats: PDF, JPG, JPEG, PNG, TIFF - Authentication: API key required - Access control: Location-level validation - Storage: Automatic S3 upload with encryption tags: - invoices parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '200': description: >- Invoice created successfully. Returns the reference ID for the uploaded document. Invoice processing happens asynchronously. content: application/json: schema: $ref: '#/components/schemas/InvoiceCreationResponse' '400': description: >- Bad request - Invalid request data or file format. Common causes include missing required fields, invalid file format, file too large, or invalid location ID. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '413': description: Payload too large - File exceeds maximum size limit of 25MB. content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '422': description: Unprocessable entity - Request validation failed content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error - Server-side processing error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: Invoice creation data - supports both file upload and URL-based ingestion content: multipart/form-data: schema: type: object properties: ottimate_location_id: type: integer description: Location ID where invoice should be processed file: type: string format: binary description: Invoice file to upload (PDF, JPG, PNG, TIFF) - max 25MB filename: type: string description: Original filename (optional, derived from file if not provided) metadata: type: string description: JSON string containing additional invoice metadata created_email: type: string format: email description: Email address of invoice sender (for tracking) required: - ottimate_location_id - file /invoices/mark-exported: post: operationId: post-invoices-mark-exported summary: Mark multiple invoices as exported description: '' tags: - invoices parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: X-Export-Batch-Id in: header description: Optional export batch identifier used for logging required: false schema: type: string responses: '200': description: Operation result content: application/json: schema: $ref: '#/components/schemas/BulkInvoiceOperationResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error - Server-side processing error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: Bulk export request payload content: application/json: schema: type: object properties: invoices: type: array items: $ref: '#/components/schemas/InvoicesMarkExportedPostRequestBodyContentApplicationJsonSchemaInvoicesItems' export_transaction_id: type: string description: Batch-level transaction ID for all invoices marked_reason: type: string description: Batch-level reason for all invoices required: - invoices /invoices/mark-unexported: post: operationId: post-invoices-mark-unexported summary: Unexport multiple invoices description: '' tags: - invoices parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Operation result content: application/json: schema: $ref: '#/components/schemas/BulkInvoiceUnexportOperationResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '500': description: Internal server error - Server-side processing error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: Bulk unexport request payload content: application/json: schema: type: object properties: invoices: type: array items: $ref: >- #/components/schemas/InvoicesMarkUnexportedPostRequestBodyContentApplicationJsonSchemaInvoicesItems marked_reason: type: string description: Batch-level reason for all invoices flag_invoice: type: boolean description: Flag the invoice as unexported required: - invoices /invoices/uploads: get: operationId: get-invoices-uploads summary: Retrieve uploads description: Returns a list of uploads that have been uploaded but not yet processed. tags: - invoices parameters: - name: ottimate_location_id in: query description: Filter by a specific location ID required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with a list of uploads content: application/json: schema: $ref: '#/components/schemas/Invoices_get_invoices_uploads_Response_200' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /invoices/{id}/approvers: get: operationId: get-invoices-id-approvers summary: Retrieve list of approvers for a specific invoice description: |- Returns a list of all approvers assigned to an invoice, including their approval status. ### Features - View all assigned approvers for an invoice - Check approval status (pending, approved) - See approver details (name, email) - View policy-based and manual approvers ### Use Cases - Check who needs to approve an invoice - Monitor approval progress - Audit approval chain tags: - invoices parameters: - name: id in: path description: Invoice ID required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with list of approvers content: application/json: schema: $ref: '#/components/schemas/Invoices_get_invoices_id_approvers_Response_200' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /invoices/{id}/flag: post: operationId: post-invoices-id-flag summary: Flag an invoice for review description: |- Flags an invoice for review, moving it to incomplete status with a flagging reason. ### Features - Flags invoice and moves to incomplete status - Supports optional flagging reason - Triggers notifications to relevant users ### Use Cases - Flag invoices with issues for review - Request corrections or additional information - Mark invoices needing manual intervention tags: - invoices parameters: - name: id in: path description: Invoice ID required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Invoice flagged successfully content: application/json: schema: $ref: '#/components/schemas/Invoices_post_invoices_id_flag_Response_200' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: Optional flagging options content: application/json: schema: type: object properties: flagging_reason: type: string description: Reason for flagging the invoice /invoices/import: post: operationId: post-invoices-import summary: Bulk import invoices description: >- Asynchronously creates up to 100 invoices in a single request. Each invoice must include a unique `upload_id` and a valid `ottimate_location_id`. Processing is queued via backgrund job and returns a `batch_id` for polling progress and results. tags: - invoices parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '202': description: Bulk import accepted and queued for processing. content: application/json: schema: $ref: '#/components/schemas/Invoices_post_invoices_import_Response_202' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: array items: $ref: '#/components/schemas/InvoicesImportPostRequestBodyContentApplicationJsonSchemaItems' /invoices/{id}/images: patch: operationId: patch-invoices-id-images summary: Replace all invoice images with uploaded files description: >- Accepts one or more image files via multipart/form-data under the 'images' key. Deletes all existing images and replaces them with the uploaded files. Supported formats: PDF, JPG, JPEG, PNG. Maximum file size per image: 50 MB. Per-file validation failures are reported in image_errors rather than rejecting the entire request. tags: - invoices parameters: - name: id in: path description: The unique ID of the invoice required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: All images replaced successfully. image_errors is empty. content: application/json: schema: $ref: '#/components/schemas/Invoices_patch_invoices_id_images_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: One or more image files to attach to the invoice content: multipart/form-data: schema: type: object properties: images: type: array items: type: string format: binary description: 'One or more image files to replace existing invoice images. Supported formats: PDF, JPG, JPEG, PNG.' required: - images /invoices/receiver-export: get: operationId: get-invoices-receiver-export summary: Retrieve catalog-matched invoice lines as receiver/quantity export description: >- Returns a paginated list of exported invoices with their catalog-matched line items. Only invoices in exported state, from vendors with item validation enabled, are returned. Fringe catalog entries and unmatched lines are excluded. If an invoice has zero qualifying lines after filtering it is omitted entirely. tags: - invoices parameters: - name: ottimate_company_id in: query description: Ottimate company ID to scope the response required: true schema: type: integer - name: ottimate_location_id in: query description: Ottimate location (restaurant) ID to scope the response required: true schema: type: integer - name: exported_after in: query description: ISO 8601 datetime; returns invoices exported after this timestamp required: false schema: type: string format: date-time - name: exported_after_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string format: date-time - name: exported_before in: query description: ISO 8601 datetime; returns invoices exported before this timestamp required: false schema: type: string format: date-time - name: exported_before_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string format: date-time - name: vendor_id in: query description: Filter by vendor ID required: false schema: type: string - name: page in: query description: Page number required: false schema: type: integer - name: limit in: query description: Max results per page (default 50, max 200) required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Paginated list of receiver export invoices content: application/json: schema: $ref: '#/components/schemas/Invoices_get_invoices_receiver-export_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /catalog/entries: get: operationId: get-catalog-entries summary: List catalog entries description: Returns a paginated list of catalog entries, filterable by company, vendor, and search term. tags: - catalog parameters: - name: ottimate_company_id in: query description: Filter entries by company ID (required) required: true schema: type: integer - name: erp_vendor_id in: query description: Filter entries by vendor name required: false schema: type: string - name: search in: query description: Search term based on item description or name required: false schema: type: string - name: page in: query description: 'Page number (default: 1)' required: false schema: type: integer - name: limit in: query description: 'Items per page (default: 50, max: 100)' required: false schema: type: integer - name: expand in: query description: >- Comma-separated list of fields to expand. Options: prices, allowances. When used, returns full CatalogEntryObject instead of CatalogEntryBasicObject. required: false schema: type: string - name: sku in: query description: SKU code required: false schema: type: string - name: upc in: query description: UPC code required: false schema: type: string - name: buying_format in: query description: >- Buying format (e.g. 'CASE', 'EACH'). Pass 'null' to filter entries that have no buying format (NULL or empty). required: false schema: type: string - name: size in: query description: Pack size (e.g. '6 CT', '10 LB') required: false schema: type: string - name: uom in: query description: Unit of measure (e.g. 'CASE', 'EACH', 'LB') required: false schema: type: string - name: price in: query description: Price for the pack size required: false schema: type: number format: double - name: unit_price in: query description: Price per individual unit within the pack required: false schema: type: number format: double - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated catalog entry list content: application/json: schema: $ref: '#/components/schemas/CatalogEntryListResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: post-catalog-entries summary: Create a catalog entry description: Creates a new catalog entry or updates an existing one if catalog_unique_key matches. tags: - catalog parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Catalog entry created successfully content: application/json: schema: $ref: '#/components/schemas/CatalogEntryObject' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: ottimate_company_id: type: integer description: The Ottimate company ID this catalog entry belongs to erp_vendor_id: type: string description: ERP Vendor id from ERP/accounting system item_name: type: string description: Item name for the catalog entry description: type: string description: 'Deprecated: use item_name instead. This field will be removed in a future API version.' original_description: type: string description: Original item description from source system sku: type: string description: SKU code upc: type: string description: UPC code buying_format: type: - string - 'null' description: >- Buying format distinguishing multiple purchasing formats for the same item (e.g., 'CASE', 'EACH'). Used as part of the composite unique key for integrations that differentiate catalog entries by buying format. Optional — null or omitted for integrations that do not use buying format. size: type: string description: Pack size (e.g., '6 CT', '10 LB') uom: type: string description: Unit of measure (e.g., 'CASE', 'EACH', 'LB') price: type: number format: double description: Price for the pack size unit_price: type: number format: double description: Price per individual unit within the pack is_split_case: type: boolean description: Whether items can be purchased in split case quantities authorized_vendor: type: boolean description: Whether the vendor is authorized for this item catalog_unique_key: type: string description: >- Unique key used to match existing entries for upsert. If omitted, the API auto-generates a key from erp_vendor_id, sku, size, and description. Key normalization: the value is derived from the entry's core identifying fields — the key returned in the response may differ from what you submitted. Always store and reuse the returned catalog_unique_key. Key regeneration: modifying erp_vendor_id, sku, size, or description will generate a new key that no longer matches the existing entry — the API will create a new entry instead of updating the old one, leaving the previous entry as an orphan. To avoid duplicates, store the latest catalog_unique_key from the response and include it in subsequent requests. last_purchased_price: type: number format: double description: Last purchased price for this item reference_id: type: string description: External reference ID for tracking dimensions: description: >- POS dimensions for this catalog entry — these are point-of-sale system dimensions, separate from ERP/accounting dimensions and not validated against your accounting configuration. Input Structure: a list of objects, each with one dimension-type key (value = dimension name) plus an optional 'code', e.g. [{"DEPARTMENT": "Marketing", "code": "321654"}]. Omit the field or pass null to leave dimensions unchanged. properties: $ref: '#/components/schemas/CatalogEntriesPostRequestBodyContentApplicationJsonSchema' description: Additional custom properties as key-value pairs prices: type: - array - 'null' items: $ref: '#/components/schemas/CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItems' description: >- Prices to create with this catalog entry. Must be present in the request — pass null to explicitly indicate no prices. Omitting this field is deprecated and will return a warning in the response. allowances: type: - array - 'null' items: $ref: '#/components/schemas/CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItems' description: >- Allowances to create with this catalog entry. Must be present in the request — pass null to explicitly indicate no allowances. Omitting this field is deprecated and will return a warning in the response. required: - ottimate_company_id - erp_vendor_id - item_name - prices - allowances /catalog/entries/{id}: get: operationId: get-catalog-entries-id summary: Retrieve a catalog entry description: Returns detailed information for a single catalog entry. tags: - catalog parameters: - name: id in: path description: The unique ID of the catalog entry required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with catalog entry details content: application/json: schema: $ref: '#/components/schemas/CatalogEntryObject' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' patch: operationId: patch-catalog-entries-id summary: Update a catalog entry description: Updates an existing catalog entry by ID. tags: - catalog parameters: - name: id in: path description: The unique ID of the catalog entry required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Catalog entry updated successfully content: application/json: schema: $ref: '#/components/schemas/CatalogEntryObject' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: erp_vendor_id: type: string description: ERP Vendor id from ERP/accounting system item_name: type: string description: Item name for the catalog entry description: type: string description: 'Deprecated: use item_name instead. This field will be removed in a future API version.' original_description: type: string description: Original item description sku: type: string description: SKU code upc: type: string description: UPC code buying_format: type: - string - 'null' description: >- Buying format distinguishing multiple purchasing formats for the same item (e.g., 'CASE', 'EACH'). Used as part of the composite unique key for integrations that differentiate catalog entries by buying format. Optional — null or omitted for integrations that do not use buying format. size: type: string description: Pack size uom: type: string description: Unit of measure price: type: number format: double description: Price unit_price: type: number format: double description: Unit price is_split_case: type: boolean description: Split case indicator authorized_vendor: type: boolean description: Whether vendor is authorized erp_vendor_name: type: - string - 'null' description: >- Optional. Human-readable vendor name attached to erp_vendor_id, sourced from the originating system. Note: reads return the resolved vendor name for the entry, which may come from upstream ERP/sync sources rather than this field. Omit to leave unchanged; pass empty string to clear. dimensions: description: >- POS dimensions for this catalog entry — these are point-of-sale system dimensions, separate from ERP/accounting dimensions and not validated against your accounting configuration. Input Structure: a list of objects, each with one dimension-type key (value = dimension name) plus an optional 'code', e.g. [{"DEPARTMENT": "Marketing", "code": "321654"}]. Omit the field or pass null to leave dimensions unchanged. properties: $ref: '#/components/schemas/CatalogEntriesIdPatchRequestBodyContentApplicationJsonSchema' description: Additional properties /catalog/allowances: get: operationId: get-catalog-allowances summary: List catalog allowances description: >- Returns a paginated list of catalog allowances, filterable by company, catalog entry, location, and effective date. tags: - catalog parameters: - name: ottimate_company_id in: query description: Filter allowances by company ID (required) required: true schema: type: integer - name: catalog_entry_id in: query description: Filter by catalog entry ID required: false schema: type: string - name: ottimate_location_id in: query description: Filter by location ID required: false schema: type: integer - name: effective_date in: query description: Filter allowances valid on this date (YYYY-MM-DD) required: false schema: type: string format: date - name: page in: query description: Page number (default 1) required: false schema: type: integer - name: limit in: query description: Number of results per page (default 20) required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated allowance list content: application/json: schema: $ref: '#/components/schemas/CatalogAllowanceListResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: post-catalog-allowances summary: Create a catalog allowance description: Creates a new catalog allowance for a catalog entry. tags: - catalog parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Catalog allowance created successfully content: application/json: schema: $ref: '#/components/schemas/CatalogAllowanceObject' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: ottimate_company_id: type: integer description: The Ottimate company ID this allowance belongs to catalog_entry_id: type: integer description: The ID of the catalog entry this allowance applies to allowance_type: $ref: '#/components/schemas/CatalogAllowancesPostRequestBodyContentApplicationJsonSchemaAllowanceType' description: 'Type of allowance (default: ''allowance'')' amount: type: number format: double description: Allowance amount for the pack size unit_allowance: type: number format: double description: 'Allowance amount per individual unit (default: 0)' target: $ref: '#/components/schemas/CatalogAllowancesPostRequestBodyContentApplicationJsonSchemaTarget' description: 'Allowance target: company (default), location_group, or location' ottimate_location_id: type: integer description: Location ID (required when target is location) ottimate_group_id: type: integer description: Location group ID (required when target is 15/location_group) start_date: type: string format: date-time description: Allowance effective start date (ISO 8601) end_date: type: string format: date-time description: Allowance effective end date (ISO 8601, optional) reference_id: type: string description: Unique reference ID for upsert operations required: - ottimate_company_id - catalog_entry_id - amount - start_date /catalog/allowances/{id}: patch: operationId: patch-catalog-allowances-id summary: Update a catalog allowance description: Updates an existing catalog allowance by ID. tags: - catalog parameters: - name: id in: path description: The unique ID of the catalog allowance required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Catalog allowance updated successfully content: application/json: schema: $ref: '#/components/schemas/CatalogAllowanceObject' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: allowance_type: $ref: '#/components/schemas/CatalogAllowancesIdPatchRequestBodyContentApplicationJsonSchemaAllowanceType' description: Type of allowance amount: type: number format: double description: Allowance amount unit_allowance: type: number format: double description: Unit allowance amount target: $ref: '#/components/schemas/CatalogAllowancesIdPatchRequestBodyContentApplicationJsonSchemaTarget' description: 'Allowance target: company, location_group, or location' ottimate_location_id: type: integer description: Location ID ottimate_group_id: type: integer description: Restaurant group ID start_date: type: string format: date-time description: Start date end_date: type: string format: date-time description: End date /catalog/variances: get: operationId: get-catalog-variances summary: List catalog variances description: >- Returns catalog entries with price variance information from invoice items. By default, returns all items that had purchases in the specified period, including items with zero variance. Use variance_only=true to return only entries with non-zero variance. Use expand=invoice_items to include all invoice items inline (otherwise only the most recent invoice item is returned). tags: - catalog parameters: - name: ottimate_company_id in: query description: Filter by company ID (required) required: true schema: type: integer - name: variance_only in: query description: >- If true, returns only entries with non-zero variance. Default: false (returns all items including zero variance) required: false schema: type: boolean - name: expand in: query description: >- Comma-separated list of fields to expand. Supports 'invoice_items' to include all invoice items for each entry. required: false schema: type: string - name: invoice_start_date in: query description: Start of date range (YYYY-MM-DD) required: false schema: type: string format: date - name: invoice_end_date in: query description: End of date range (YYYY-MM-DD) required: false schema: type: string format: date - name: erp_vendor_ids in: query description: Comma-separated ERP vendor IDs (accounting vendor IDs) to filter variances by vendor. required: false schema: type: string - name: ottimate_location_ids in: query description: Comma-separated location IDs required: false schema: type: string - name: exception_type in: query description: Filter by variance type required: false schema: $ref: '#/components/schemas/CatalogVariancesGetParametersExceptionType' - name: page in: query description: Page number for pagination required: false schema: type: integer - name: limit in: query description: Number of items per page required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated variance list content: application/json: schema: $ref: '#/components/schemas/VarianceListResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /catalog/entries/bulk: post: operationId: post-catalog-entries-bulk summary: Bulk create/update catalog entries (async) description: >- Creates or updates multiple catalog entries asynchronously. Returns 202 with batch tracking info. Maximum 1000 entries per request. Poll GET /batch/{id}/progress for status. **Deprecation notice:** The previous synchronous bulk API has been deprecated. This async endpoint is the recommended behavior going forward — it avoids timeouts on large batches and provides progress tracking via the batch polling API. tags: - catalog parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '202': description: Asynchronous processing started. Poll batch_url for status. content: application/json: schema: $ref: '#/components/schemas/CatalogEntriesBulkAsyncResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /catalog/allowances/bulk: post: operationId: post-catalog-allowances-bulk summary: Bulk create/update catalog allowances (async) description: >- Creates or updates multiple catalog allowances asynchronously. Returns 202 with batch tracking info. Maximum 1000 allowances per request. Poll GET /batch/{id}/progress for status. **Deprecation notice:** The previous synchronous bulk API has been deprecated. This async endpoint is the recommended behavior going forward — it avoids timeouts on large batches and provides progress tracking via the batch polling API. tags: - catalog parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '202': description: Asynchronous processing started. Poll batch_url for status. content: application/json: schema: $ref: '#/components/schemas/CatalogAllowancesBulkAsyncResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /catalog/prices/bulk: post: operationId: post-catalog-prices-bulk summary: Bulk create catalog prices (async) description: >- Creates multiple catalog prices asynchronously (create-only, skips duplicates). Returns 202 with batch tracking info. Maximum 1000 prices per request. Poll GET /batch/{id}/progress for status. **Deprecation notice:** The previous synchronous bulk API has been deprecated. This async endpoint is the recommended behavior going forward — it avoids timeouts on large batches and provides progress tracking via the batch polling API. tags: - catalog parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '202': description: Asynchronous processing started. Poll batch_url for status. content: application/json: schema: $ref: '#/components/schemas/CatalogPricesBulkAsyncResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /catalog/variances/{id}/invoice-items: get: operationId: get-catalog-variances-id-invoice-items summary: Get invoice items for a catalog entry description: >- Returns paginated invoice items with price variances for a specific catalog entry. Use this endpoint when the expand=invoice_items response indicates has_more=true. tags: - catalog parameters: - name: id in: path description: The catalog entry ID required: true schema: type: string - name: page in: query description: Page number required: false schema: type: integer - name: limit in: query description: 'Items per page (default: 20)' required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated invoice items content: application/json: schema: $ref: '#/components/schemas/InvoiceItemVarianceListResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /catalog/variance-batches: get: operationId: get-catalog-variance-batches summary: List exported catalog variance batches description: >- Returns exported Catalog Variance Manager batches for the given company. Only batches with export_status='exported' are ever returned — drafts and failed batches are excluded. The costbatch_payload in each result matches the Pyxis /costbatch format exactly. tags: - catalog parameters: - name: ottimate_company_id in: query description: Company ID to filter by (required) required: true schema: type: integer - name: batch_number in: query description: Filter by exact batch number required: false schema: type: integer - name: exported_after in: query description: Return batches exported on or after this datetime (ISO 8601) required: false schema: type: string format: date-time - name: exported_after_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string format: date-time - name: exported_before in: query description: Return batches exported on or before this datetime (ISO 8601) required: false schema: type: string format: date-time - name: exported_before_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string format: date-time - name: page in: query description: Page number for pagination required: false schema: type: integer - name: limit in: query description: Number of items per page required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated exported batch list content: application/json: schema: $ref: '#/components/schemas/CatalogVarianceBatchListResponse' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /catalog/variance-batches/{id}/export: post: operationId: post-catalog-variance-batches-id-export summary: Export a catalog variance batch (local only) description: >- Marks the batch as exported without sending data to any external system. Sets exported_at to the current timestamp and api_status to success. Returns the exported batch with its costbatch_payload. Returns 400 if the batch is already exported. tags: - catalog parameters: - name: id in: path description: The catalog variance batch ID (ctb_xxx) required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '200': description: Batch successfully marked as exported content: application/json: schema: $ref: '#/components/schemas/CatalogVarianceBatchObject' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '404': description: Not found - Resource does not exist content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /catalog/prices: get: operationId: get-catalog-prices summary: List catalog prices description: >- Returns a paginated list of catalog prices, filterable by company, catalog entry, location, effective date, and price type. tags: - catalog parameters: - name: ottimate_company_id in: query description: Filter prices by company ID (required) required: true schema: type: integer - name: catalog_entry_id in: query description: Filter by catalog entry ID required: false schema: type: string - name: ottimate_location_id in: query description: Filter by location ID required: false schema: type: integer - name: effective_date in: query description: Filter prices valid on this date (YYYY-MM-DD) required: false schema: type: string format: date - name: price_type in: query description: Filter by price type required: false schema: $ref: '#/components/schemas/CatalogPricesGetParametersPriceType' - name: page in: query description: Page number (default 1) required: false schema: type: integer - name: limit in: query description: Number of results per page (default 20) required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with paginated price list content: application/json: schema: $ref: '#/components/schemas/Catalog_get_catalog_prices_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' post: operationId: post-catalog-prices summary: Create a catalog price description: Creates a new catalog price for a catalog entry. tags: - catalog parameters: - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string - name: Idempotency-Key in: header description: >- Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details. required: false schema: type: string responses: '201': description: Price created successfully content: application/json: schema: $ref: '#/components/schemas/CatalogPriceItem' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' requestBody: description: '' content: application/json: schema: type: object properties: ottimate_company_id: type: integer description: The Ottimate company ID this price belongs to catalog_entry_id: type: string description: The ID of the catalog entry this price applies to price: type: number format: double description: Price amount for the pack size unit_price: type: number format: double description: Price amount per individual unit (optional) price_type: $ref: '#/components/schemas/CatalogPricesPostRequestBodyContentApplicationJsonSchemaPriceType' description: 'Price type: company (default), location_group, or location' ottimate_location_id: type: integer description: Location ID (required when price_type is 'location') ottimate_group_id: type: integer description: Location group ID (required when price_type is 'location_group') start_date: type: string format: date-time description: Price effective start date (ISO 8601) end_date: type: string format: date-time description: Price effective end date (ISO 8601, optional) reference_id: type: string description: External reference ID for the price required: - ottimate_company_id - catalog_entry_id - price - start_date /batch/{id}/progress: get: operationId: get-batch-id-progress summary: Poll batch progress description: >- Returns the current progress of a batch operation. Poll this endpoint until `status` is `completed`. When completed, a `results_url` is included. If all tasks failed, an `error` field is included with the failure reason. tags: - batch parameters: - name: id in: path description: The batch ID returned from the initiating bulk operation required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with current batch progress content: application/json: schema: $ref: '#/components/schemas/BatchProgressResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /batch/{id}/results: get: operationId: get-batch-id-results summary: Retrieve batch results description: >- Returns the per-task results for a batch operation. Call this endpoint after polling `/progress` until `status` is `completed`. Each entry in `results` corresponds to one task, with the task outcome in `result` and any error message in `message`. tags: - batch parameters: - name: id in: path description: The batch ID returned from the initiating bulk operation required: true schema: type: string - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Successful response with batch results content: application/json: schema: $ref: '#/components/schemas/BatchResultsResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '403': description: Forbidden - Access denied or insufficient permissions content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' /batch: get: operationId: get-batch-root summary: List batches description: >- Returns a paginated list of batch jobs belonging to the authenticated user, sorted by last modified time descending. Use the `status` filter to narrow results to in-progress or completed batches. Use `date_from` / `date_to` to filter by last modified time range. tags: - batch parameters: - name: status in: query description: Filter by batch status. `processing` returns in-progress batches; `completed` returns finished batches. required: false schema: $ref: '#/components/schemas/BatchGetParametersStatus' - name: date_from in: query description: Return only batches last modified at or after this ISO 8601 datetime (e.g. `2024-01-01T00:00:00Z`). required: false schema: type: string format: date-time - name: date_from_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string format: date-time - name: date_to in: query description: Return only batches last modified at or before this ISO 8601 datetime (e.g. `2024-12-31T23:59:59Z`). required: false schema: type: string format: date-time - name: date_to_utc in: query description: >- UTC filter. Accepts ISO 8601 with optional Z/offset, or YYYY-MM-DD[ HH:MM:SS] (assumed UTC). Takes precedence over the non-_utc variant. required: false schema: type: string format: date-time - name: limit in: query description: Number of results per page (default 20). required: false schema: type: integer - name: page in: query description: Page number. required: false schema: type: integer - name: Authorization in: header description: OAuth2 authentication flows. Auth server URLs will vary by environment required: true schema: type: string - name: X-Api-Key in: header description: API key for authentication required: true schema: type: string - name: X-API-Version in: header description: 'API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.' required: false schema: type: string responses: '200': description: Paginated list of batch jobs content: application/json: schema: $ref: '#/components/schemas/Batch_get_batch_root_Response_200' '400': description: Bad request - Invalid parameters or request format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' '401': description: Unauthorized - Authentication required or invalid credentials content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' servers: - url: https://api.ottimate.com/v1 description: Production - url: https://sandbox-api.ottimate.com/v1 description: Sandbox components: schemas: OauthTokenPostRequestBodyContentApplicationXWwwFormUrlencodedSchemaGrantType: type: string enum: - client_credentials description: Grant type for the request. Must be 'client_credentials'. title: OauthTokenPostRequestBodyContentApplicationXWwwFormUrlencodedSchemaGrantType Oauth_post_oauth_token_Response_200: type: object properties: access_token: type: string description: The access token. token_type: type: string description: The type of the token (e.g., Bearer). expires_in: type: integer description: The lifetime in seconds of the access token. scope: type: string description: The scope of the access token. title: Oauth_post_oauth_token_Response_200 ErrorResponse: type: object properties: code: type: string description: Human-readable error message request_id: type: string description: Unique identifier for the request message: description: Additional error details, can be an object, a string, or null. timestamp: type: string description: Timestamp when error occurred required: - code - message title: ErrorResponse CompanyObject: type: object properties: id: type: integer name: type: string location_count: type: integer plan: type: string required: - id - name title: CompanyObject Accounts_get_accounts_id_companies_Response_200: type: object properties: count: type: integer page: type: integer limit: type: integer results: type: array items: $ref: '#/components/schemas/CompanyObject' title: Accounts_get_accounts_id_companies_Response_200 LocationObject: type: object properties: id: type: integer name: type: string company: type: string location_group: type: string description: 'The group this location belongs to. Returned when X-API-Version: 1.1.0 or later.' group: type: string description: >- Deprecated. Use location_group (requires X-API-Version: 1.1.0). Returned for X-API-Version: 1.0.0 and unversioned requests. required: - id - name title: LocationObject Accounts_get_accounts_id_locations_Response_200: type: object properties: count: type: integer page: type: integer limit: type: integer results: type: array items: $ref: '#/components/schemas/LocationObject' title: Accounts_get_accounts_id_locations_Response_200 AccountObject: type: object properties: id: type: string description: Account ID (racc_ prefixed) name: type: string description: Account name created_date: type: string description: Account creation timestamp created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". company_count: type: integer description: Number of companies in this account location_count: type: integer description: Number of active locations in this account required: - id - name title: AccountObject Accounts_get_accounts_root_Response_200: type: object properties: count: type: integer page: type: integer limit: type: integer results: type: array items: $ref: '#/components/schemas/AccountObject' title: Accounts_get_accounts_root_Response_200 VendorsGetParametersDetail: type: string enum: - basic title: VendorsGetParametersDetail VendorsGetResponsesContentApplicationJsonSchemaVendorsItemsPaymentMethod: type: string enum: - credit_card - ach - check - wire_transfer - unknown title: VendorsGetResponsesContentApplicationJsonSchemaVendorsItemsPaymentMethod VendorsGetResponsesContentApplicationJsonSchemaVendorsItems: type: object properties: id: type: integer ottimate_company_id: type: integer company_name: type: string erp_vendor_id: type: - string - 'null' erp_vendor_name: type: - string - 'null' email: type: - string - 'null' phone: type: - string - 'null' net_terms: type: - string - 'null' payment_method: oneOf: - $ref: '#/components/schemas/VendorsGetResponsesContentApplicationJsonSchemaVendorsItemsPaymentMethod' - type: 'null' address_line_1: type: - string - 'null' address_line_2: type: - string - 'null' city: type: - string - 'null' state: type: - string - 'null' zipcode: type: - string - 'null' last_modified_date: type: - string - 'null' format: date-time last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - erp_vendor_name title: VendorsGetResponsesContentApplicationJsonSchemaVendorsItems Vendors_get_vendors_root_Response_200: type: object properties: version: type: string count: type: integer page: type: integer limit: type: integer vendors: type: array items: $ref: '#/components/schemas/VendorsGetResponsesContentApplicationJsonSchemaVendorsItems' required: - version - count - page - limit - vendors title: Vendors_get_vendors_root_Response_200 VendorsIdGetResponsesContentApplicationJsonSchemaVendorPaymentMethod: type: string enum: - credit_card - ach - check - wire_transfer - unknown title: VendorsIdGetResponsesContentApplicationJsonSchemaVendorPaymentMethod VendorsIdGetResponsesContentApplicationJsonSchemaVendor: type: object properties: id: type: integer ottimate_company_id: type: integer company_name: type: string erp_vendor_id: type: - string - 'null' erp_vendor_name: type: - string - 'null' email: type: - string - 'null' phone: type: - string - 'null' net_terms: type: - string - 'null' payment_method: oneOf: - $ref: '#/components/schemas/VendorsIdGetResponsesContentApplicationJsonSchemaVendorPaymentMethod' - type: 'null' address_line_1: type: - string - 'null' address_line_2: type: - string - 'null' city: type: - string - 'null' state: type: - string - 'null' zipcode: type: - string - 'null' required: - id - ottimate_company_id - erp_vendor_id - erp_vendor_name title: VendorsIdGetResponsesContentApplicationJsonSchemaVendor Vendors_get_vendors_id_Response_200: type: object properties: version: type: string vendor: $ref: '#/components/schemas/VendorsIdGetResponsesContentApplicationJsonSchemaVendor' required: - version - vendor title: Vendors_get_vendors_id_Response_200 VendorsPostRequestBodyContentApplicationJsonSchemaPaymentMethod: type: string enum: - credit_card - ach - check - wire_transfer - unknown description: (Optional) Vendor payment method title: VendorsPostRequestBodyContentApplicationJsonSchemaPaymentMethod VendorsPostResponsesContentApplicationJsonSchemaVendorPaymentMethod: type: string enum: - credit_card - ach - check - wire_transfer - unknown title: VendorsPostResponsesContentApplicationJsonSchemaVendorPaymentMethod VendorsPostResponsesContentApplicationJsonSchemaVendor: type: object properties: id: type: integer ottimate_company_id: type: integer erp_vendor_id: type: - string - 'null' erp_vendor_name: type: - string - 'null' email: type: - string - 'null' phone: type: - string - 'null' net_terms: type: - string - 'null' payment_method: oneOf: - $ref: '#/components/schemas/VendorsPostResponsesContentApplicationJsonSchemaVendorPaymentMethod' - type: 'null' address_line_1: type: - string - 'null' address_line_2: type: - string - 'null' city: type: - string - 'null' state: type: - string - 'null' zipcode: type: - string - 'null' required: - id - ottimate_company_id title: VendorsPostResponsesContentApplicationJsonSchemaVendor Vendors_post_vendors_root_Response_201: type: object properties: version: type: string vendor: $ref: '#/components/schemas/VendorsPostResponsesContentApplicationJsonSchemaVendor' required: - version - vendor title: Vendors_post_vendors_root_Response_201 VendorsBulkPostRequestBodyContentApplicationJsonSchemaVendorsItemsPaymentMethod: type: string enum: - credit_card - ach - check - wire_transfer - unknown description: (Optional) Vendor payment method title: VendorsBulkPostRequestBodyContentApplicationJsonSchemaVendorsItemsPaymentMethod VendorsBulkPostRequestBodyContentApplicationJsonSchemaVendorsItems: type: object properties: erp_vendor_name: type: string description: Vendor name erp_vendor_id: type: string description: Unique vendor ID in ERP system email: type: string description: (Optional) Vendor email phone: type: string description: (Optional) Vendor phone number net_terms: type: string description: (Optional) Payment terms payment_method: $ref: '#/components/schemas/VendorsBulkPostRequestBodyContentApplicationJsonSchemaVendorsItemsPaymentMethod' description: (Optional) Vendor payment method address_line_1: type: string description: (Optional) Vendor address line 1 address_line_2: type: string description: (Optional) Vendor address line 2 city: type: string description: (Optional) Vendor city state: type: string description: (Optional) Vendor state zipcode: type: string description: (Optional) Vendor zipcode required: - erp_vendor_id title: VendorsBulkPostRequestBodyContentApplicationJsonSchemaVendorsItems VendorsBulkPostResponsesContentApplicationJsonSchemaCreatedItemsPaymentMethod: type: string enum: - credit_card - ach - check - wire_transfer - unknown title: VendorsBulkPostResponsesContentApplicationJsonSchemaCreatedItemsPaymentMethod VendorsBulkPostResponsesContentApplicationJsonSchemaCreatedItems: type: object properties: id: type: integer ottimate_company_id: type: integer erp_vendor_id: type: - string - 'null' erp_vendor_name: type: - string - 'null' email: type: - string - 'null' phone: type: - string - 'null' net_terms: type: - string - 'null' payment_method: oneOf: - $ref: '#/components/schemas/VendorsBulkPostResponsesContentApplicationJsonSchemaCreatedItemsPaymentMethod' - type: 'null' address_line_1: type: - string - 'null' address_line_2: type: - string - 'null' city: type: - string - 'null' state: type: - string - 'null' zipcode: type: - string - 'null' title: VendorsBulkPostResponsesContentApplicationJsonSchemaCreatedItems VendorsBulkPostResponsesContentApplicationJsonSchemaUpdatedItemsPaymentMethod: type: string enum: - credit_card - ach - check - wire_transfer - unknown title: VendorsBulkPostResponsesContentApplicationJsonSchemaUpdatedItemsPaymentMethod VendorsBulkPostResponsesContentApplicationJsonSchemaUpdatedItems: type: object properties: id: type: integer ottimate_company_id: type: integer erp_vendor_id: type: - string - 'null' erp_vendor_name: type: - string - 'null' email: type: - string - 'null' phone: type: - string - 'null' net_terms: type: - string - 'null' payment_method: oneOf: - $ref: '#/components/schemas/VendorsBulkPostResponsesContentApplicationJsonSchemaUpdatedItemsPaymentMethod' - type: 'null' address_line_1: type: - string - 'null' address_line_2: type: - string - 'null' city: type: - string - 'null' state: type: - string - 'null' zipcode: type: - string - 'null' title: VendorsBulkPostResponsesContentApplicationJsonSchemaUpdatedItems VendorsBulkPostResponsesContentApplicationJsonSchemaErrorsItems: type: object properties: index: type: integer erp_vendor_id: type: - string - 'null' error: type: string type: type: string title: VendorsBulkPostResponsesContentApplicationJsonSchemaErrorsItems Vendors_post_vendors_bulk_Response_201: type: object properties: version: type: string success_count: type: integer created_count: type: integer updated_count: type: integer error_count: type: integer created: type: array items: $ref: '#/components/schemas/VendorsBulkPostResponsesContentApplicationJsonSchemaCreatedItems' updated: type: array items: $ref: '#/components/schemas/VendorsBulkPostResponsesContentApplicationJsonSchemaUpdatedItems' errors: type: array items: $ref: '#/components/schemas/VendorsBulkPostResponsesContentApplicationJsonSchemaErrorsItems' title: Vendors_post_vendors_bulk_Response_201 DimensionsGetParametersDetail: type: string enum: - basic title: DimensionsGetParametersDetail DimensionsGetResponsesContentApplicationJsonSchemaDimensionsItemsOttimateType: type: string enum: - account - location - department - class - project - customer - entity - item - warehouse - task - costtype - employee - taxcode - property - company - subsidiary description: >- Ottimate's standardized dimension type code. This maps to Ottimate's internal dimension classification system, providing a consistent categorization regardless of how the client's ERP names it. title: DimensionsGetResponsesContentApplicationJsonSchemaDimensionsItemsOttimateType DimensionsGetResponsesContentApplicationJsonSchemaDimensionsItems: type: object properties: id: type: string description: Unique Ottimate dimension identifier name: type: string description: Display name of the dimension erp_type: type: string description: >- The dimension category label as displayed in the client's ERP system. This is client-specific and varies by accounting software (e.g., 'Account', 'GLACCOUNT', 'GL_ACCOUNT' may all represent GL accounts). code: type: string description: The GL code or short identifier associated with this dimension in the client's general ledger or ERP system. reference_id: type: string description: >- A unique reference identifier that tracks this dimension across all client systems (ERP, inventory management, Ottimate). Used to correlate the same dimension across different platforms. ottimate_type: $ref: '#/components/schemas/DimensionsGetResponsesContentApplicationJsonSchemaDimensionsItemsOttimateType' description: >- Ottimate's standardized dimension type code. This maps to Ottimate's internal dimension classification system, providing a consistent categorization regardless of how the client's ERP names it. erp_dimension_id: type: string description: The identifier assigned to this dimension by the client's ERP software ottimate_company_id: type: integer description: The Ottimate company ID this dimension belongs to required: - id - name - erp_type - erp_dimension_id title: DimensionsGetResponsesContentApplicationJsonSchemaDimensionsItems Dimensions_get_dimensions_root_Response_200: type: object properties: version: type: string count: type: integer page: type: integer limit: type: integer dimensions: type: array items: $ref: '#/components/schemas/DimensionsGetResponsesContentApplicationJsonSchemaDimensionsItems' required: - version - count - page - limit - dimensions title: Dimensions_get_dimensions_root_Response_200 DimensionsIdGetResponsesContentApplicationJsonSchemaDimensionOttimateType: type: string enum: - account - location - department - class - project - customer - entity - item - warehouse - task - costtype - employee - taxcode - property - company - subsidiary description: Ottimate's standardized dimension type code. title: DimensionsIdGetResponsesContentApplicationJsonSchemaDimensionOttimateType DimensionsIdGetResponsesContentApplicationJsonSchemaDimension: type: object properties: id: type: string description: Unique Ottimate dimension identifier name: type: string description: Display name of the dimension erp_type: type: string description: The dimension category label as displayed in the client's ERP system. code: type: string description: The GL code or short identifier associated with this dimension. reference_id: type: string description: A unique reference identifier that tracks this dimension across all client systems. ottimate_type: $ref: '#/components/schemas/DimensionsIdGetResponsesContentApplicationJsonSchemaDimensionOttimateType' description: Ottimate's standardized dimension type code. erp_dimension_id: type: string description: The identifier assigned to this dimension by the client's ERP software. ottimate_company_id: type: integer description: The Ottimate company ID this dimension belongs to required: - id - name - erp_type - erp_dimension_id title: DimensionsIdGetResponsesContentApplicationJsonSchemaDimension Dimensions_get_dimensions_id_Response_200: type: object properties: version: type: string dimension: $ref: '#/components/schemas/DimensionsIdGetResponsesContentApplicationJsonSchemaDimension' required: - version - dimension title: Dimensions_get_dimensions_id_Response_200 DimensionsPostRequestBodyContentApplicationJsonSchemaOttimateType: type: string enum: - account - location - department - class - project - customer - entity - item - warehouse - task - costtype - employee - taxcode - property - company - subsidiary description: Ottimate's standardized dimension type code for consistent categorization. title: DimensionsPostRequestBodyContentApplicationJsonSchemaOttimateType DimensionsPostResponsesContentApplicationJsonSchemaOttimateType: type: string enum: - account - location - department - class - project - customer - entity - item - warehouse - task - costtype - employee - taxcode - property - company - subsidiary description: Ottimate's standardized dimension type code title: DimensionsPostResponsesContentApplicationJsonSchemaOttimateType Dimensions_post_dimensions_root_Response_201: type: object properties: version: type: string id: type: string name: type: string erp_type: type: string description: The dimension category label in client's ERP system code: type: string reference_id: type: string ottimate_type: $ref: '#/components/schemas/DimensionsPostResponsesContentApplicationJsonSchemaOttimateType' description: Ottimate's standardized dimension type code erp_dimension_id: type: string ottimate_company_id: type: integer title: Dimensions_post_dimensions_root_Response_201 DimensionsBulkPostRequestBodyContentApplicationJsonSchemaDimensionsItemsOttimateType: type: string enum: - account - location - department - class - project - customer - entity - item - warehouse - task - costtype - employee - taxcode - property - company - subsidiary description: Ottimate's standardized dimension type code title: DimensionsBulkPostRequestBodyContentApplicationJsonSchemaDimensionsItemsOttimateType DimensionsBulkPostRequestBodyContentApplicationJsonSchemaDimensionsItems: type: object properties: erp_type: type: string description: The dimension category label in client's ERP system ottimate_type: $ref: '#/components/schemas/DimensionsBulkPostRequestBodyContentApplicationJsonSchemaDimensionsItemsOttimateType' description: Ottimate's standardized dimension type code name: type: string description: Display name of the dimension code: type: string description: The GL code or short identifier for this dimension reference_id: type: string description: A unique reference identifier that tracks this dimension across all client systems erp_dimension_id: type: string description: The identifier assigned to this dimension by the client's ERP software required: - erp_type - ottimate_type - name - code - reference_id - erp_dimension_id title: DimensionsBulkPostRequestBodyContentApplicationJsonSchemaDimensionsItems DimensionsBulkPostResponsesContentApplicationJsonSchemaCreatedItems: type: object properties: id: type: string name: type: string title: DimensionsBulkPostResponsesContentApplicationJsonSchemaCreatedItems DimensionsBulkPostResponsesContentApplicationJsonSchemaUpdatedItems: type: object properties: id: type: string name: type: string title: DimensionsBulkPostResponsesContentApplicationJsonSchemaUpdatedItems DimensionsBulkPostResponsesContentApplicationJsonSchemaErrorsItems: type: object properties: id: type: string name: type: string title: DimensionsBulkPostResponsesContentApplicationJsonSchemaErrorsItems Dimensions_post_dimensions_bulk_Response_201: type: object properties: version: type: string success_count: type: integer created_count: type: integer updated_count: type: integer error_count: type: integer created: type: array items: $ref: '#/components/schemas/DimensionsBulkPostResponsesContentApplicationJsonSchemaCreatedItems' updated: type: array items: $ref: '#/components/schemas/DimensionsBulkPostResponsesContentApplicationJsonSchemaUpdatedItems' errors: type: array items: $ref: '#/components/schemas/DimensionsBulkPostResponsesContentApplicationJsonSchemaErrorsItems' title: Dimensions_post_dimensions_bulk_Response_201 PurchaseOrdersGetParametersStatus: type: string enum: - pending_review - approved - rejected - closed title: PurchaseOrdersGetParametersStatus PurchaseOrderSummaryStatus: type: string enum: - pending - open - received - closed - flagged - archived - deleted title: PurchaseOrderSummaryStatus PurchaseOrderSummaryCustomFields: type: object properties: {} description: Custom fields configured for this company's purchase orders title: PurchaseOrderSummaryCustomFields PurchaseOrderSummary: type: object properties: id: type: string format: uuid external_id: type: string description: External unique identifier for idempotent operations po_number: type: string description: PO number (client-provided, mandatory) status: $ref: '#/components/schemas/PurchaseOrderSummaryStatus' ottimate_location_id: type: integer ottimate_company_id: type: integer date: type: string format: date erp_vendor_id: type: string description: External vendor identifier from ERP system erp_vendor_name: type: string description: Vendor name from ERP system total_amount: type: number format: double created_date: type: string format: date-time created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". custom_fields: $ref: '#/components/schemas/PurchaseOrderSummaryCustomFields' description: Custom fields configured for this company's purchase orders required: - id - status title: PurchaseOrderSummary Purchase-Orders_get_purchase-orders_root_Response_200: type: object properties: version: type: string count: type: integer page: type: integer limit: type: integer purchase_orders: type: array items: $ref: '#/components/schemas/PurchaseOrderSummary' title: Purchase-Orders_get_purchase-orders_root_Response_200 PurchaseOrderDetailPurchaseOrderStatus: type: string enum: - pending - open - received - closed - flagged - archived - deleted title: PurchaseOrderDetailPurchaseOrderStatus PurchaseOrderDetailPurchaseOrderItemsItemsDimensions: type: object properties: {} description: >- Resolved dimensions keyed by dimension type. Each value is an object containing the dimension's id, erp_dimension_id, name, and code — unlike the POST/PATCH request format which expects plain string values. title: PurchaseOrderDetailPurchaseOrderItemsItemsDimensions PurchaseOrderDetailPurchaseOrderItemsItems: type: object properties: id: type: string format: uuid external_id: type: string name: type: string sku: type: string quantity: type: number format: double price: type: number format: double uom: type: string dimensions: oneOf: - $ref: '#/components/schemas/PurchaseOrderDetailPurchaseOrderItemsItemsDimensions' - type: 'null' description: >- Resolved dimensions keyed by dimension type. Each value is an object containing the dimension's id, erp_dimension_id, name, and code — unlike the POST/PATCH request format which expects plain string values. created_date: type: string format: date-time created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". title: PurchaseOrderDetailPurchaseOrderItemsItems PurchaseOrderDetailPurchaseOrderCustomFields: type: object properties: {} description: Custom fields configured for this company's purchase orders title: PurchaseOrderDetailPurchaseOrderCustomFields PurchaseOrderDetailPurchaseOrder: type: object properties: id: type: string format: uuid external_id: type: string po_number: type: string status: $ref: '#/components/schemas/PurchaseOrderDetailPurchaseOrderStatus' ottimate_location_id: type: integer ottimate_company_id: type: integer date: type: string format: date erp_vendor_id: type: string erp_vendor_name: type: string total_amount: type: number format: double tax: type: number format: double freight: type: number format: double miscellaneous_charges: type: number format: double invoice_number_ref: type: string is_2_way: type: boolean items: type: array items: $ref: '#/components/schemas/PurchaseOrderDetailPurchaseOrderItemsItems' created_date: type: string format: date-time created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". custom_fields: $ref: '#/components/schemas/PurchaseOrderDetailPurchaseOrderCustomFields' description: Custom fields configured for this company's purchase orders required: - id - status title: PurchaseOrderDetailPurchaseOrder PurchaseOrderDetail: type: object properties: version: type: string purchase_order: $ref: '#/components/schemas/PurchaseOrderDetailPurchaseOrder' required: - purchase_order title: PurchaseOrderDetail PurchaseOrderCreateRequestItemsItemsDimensions: type: object properties: {} description: >- Dimension values keyed by type (e.g. PROJECT, CLASS). Each value is the ERP external_id of the dimension. When provided, REPLACES all existing dimensions on the item — include every dimension you want to keep. Omit the field or pass null to leave dimensions unchanged. Passing {} returns 400. title: PurchaseOrderCreateRequestItemsItemsDimensions PurchaseOrderCreateRequestItemsItems: type: object properties: external_id: type: string name: type: string sku: type: string quantity: type: number format: double price: type: number format: double uom: type: string dimensions: oneOf: - $ref: '#/components/schemas/PurchaseOrderCreateRequestItemsItemsDimensions' - type: 'null' description: >- Dimension values keyed by type (e.g. PROJECT, CLASS). Each value is the ERP external_id of the dimension. When provided, REPLACES all existing dimensions on the item — include every dimension you want to keep. Omit the field or pass null to leave dimensions unchanged. Passing {} returns 400. required: - name - quantity - price title: PurchaseOrderCreateRequestItemsItems PurchaseOrderCreateRequestCustomFields: type: object properties: {} description: Optional custom fields configured for this company's purchase orders title: PurchaseOrderCreateRequestCustomFields PurchaseOrderCreateRequest: type: object properties: ottimate_location_id: type: integer external_id: type: string po_number: type: string erp_vendor_id: type: string description: External vendor identifier from ERP system erp_vendor_name: type: string description: Vendor name from ERP system date: type: string format: date total_amount: type: number format: double tax: type: number format: double freight: type: number format: double miscellaneous_charges: type: number format: double invoice_number_ref: type: string description: Invoice reference number is_2_way: type: boolean description: Whether this is a 2-way match PO items: type: array items: $ref: '#/components/schemas/PurchaseOrderCreateRequestItemsItems' custom_fields: $ref: '#/components/schemas/PurchaseOrderCreateRequestCustomFields' description: Optional custom fields configured for this company's purchase orders required: - ottimate_location_id - po_number - erp_vendor_id - date - total_amount - items title: PurchaseOrderCreateRequest PurchaseOrderCreateResponseStatus: type: string enum: - pending - open - received - closed - flagged - archived - deleted title: PurchaseOrderCreateResponseStatus PurchaseOrderCreateResponseItemsItemsDimensions: type: object properties: {} description: >- Resolved dimensions keyed by dimension type. Each value is an object containing the dimension's id, erp_dimension_id, name, and code — unlike the POST/PATCH request format which expects plain string values. title: PurchaseOrderCreateResponseItemsItemsDimensions PurchaseOrderCreateResponseItemsItems: type: object properties: id: type: string format: uuid external_id: type: string name: type: string sku: type: string quantity: type: number format: double price: type: number format: double uom: type: string dimensions: $ref: '#/components/schemas/PurchaseOrderCreateResponseItemsItemsDimensions' description: >- Resolved dimensions keyed by dimension type. Each value is an object containing the dimension's id, erp_dimension_id, name, and code — unlike the POST/PATCH request format which expects plain string values. created_date: type: string format: date-time last_modified_date: type: string format: date-time required: - name - quantity - price title: PurchaseOrderCreateResponseItemsItems PurchaseOrderCreateResponseCustomFields: type: object properties: {} description: Optional custom fields configured for this company's purchase orders title: PurchaseOrderCreateResponseCustomFields PurchaseOrderCreateResponse: type: object properties: id: type: string format: uuid external_id: type: string po_number: type: string status: $ref: '#/components/schemas/PurchaseOrderCreateResponseStatus' ottimate_location_id: type: integer ottimate_company_id: type: integer date: type: string format: date erp_vendor_id: type: string erp_vendor_name: type: string total_amount: type: number format: double items_count: type: integer items: type: array items: $ref: '#/components/schemas/PurchaseOrderCreateResponseItemsItems' created_date: type: string format: date-time description: Creation timestamp. UTC ISO 8601, e.g. "2024-01-15T10:30:00Z". custom_fields: $ref: '#/components/schemas/PurchaseOrderCreateResponseCustomFields' description: Optional custom fields configured for this company's purchase orders required: - id - status title: PurchaseOrderCreateResponse PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsDimensions: type: object properties: {} description: >- Dimension values keyed by dimension type. Each value must be a string — the ERP dimension code or ID (e.g. "DEPT-001"). Example: {"DEPARTMENT": "DEPT-001", "CLASS": "CLASS-001"}. Important: the GET response returns dimensions as rich objects (with id, name, code); passing an object here instead of a string will return a PO4000 validation error. When provided, REPLACES all existing dimensions on the item — include every dimension you want to keep. Omit the field or pass null to leave dimensions unchanged. Passing {} returns 400. title: PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsDimensions PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaItemsItems: type: object properties: id: type: string format: uuid description: Existing item ID. If provided, updates that item; if omitted, creates a new item. external_id: type: string name: type: string description: Required when creating a new item (no id). sku: type: string quantity: type: number format: double description: Required when creating a new item (no id). price: type: number format: double description: Required when creating a new item (no id). uom: type: string dimensions: oneOf: - $ref: '#/components/schemas/PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsDimensions' - type: 'null' description: >- Dimension values keyed by dimension type. Each value must be a string — the ERP dimension code or ID (e.g. "DEPT-001"). Example: {"DEPARTMENT": "DEPT-001", "CLASS": "CLASS-001"}. Important: the GET response returns dimensions as rich objects (with id, name, code); passing an object here instead of a string will return a PO4000 validation error. When provided, REPLACES all existing dimensions on the item — include every dimension you want to keep. Omit the field or pass null to leave dimensions unchanged. Passing {} returns 400. title: PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaItemsItems PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaCustomFields: type: object properties: {} description: Optional custom fields configured for this company's purchase orders title: PurchaseOrdersIdPatchRequestBodyContentApplicationJsonSchemaCustomFields PurchaseOrderUpdateResponseStatus: type: string enum: - pending - open - received - closed - flagged - archived - deleted title: PurchaseOrderUpdateResponseStatus PurchaseOrderUpdateResponse: type: object properties: version: type: string id: type: string format: uuid external_id: type: string po_number: type: string status: $ref: '#/components/schemas/PurchaseOrderUpdateResponseStatus' ottimate_location_id: type: integer ottimate_company_id: type: integer date: type: string format: date erp_vendor_id: type: string erp_vendor_name: type: string total_amount: type: number format: double items_count: type: integer last_modified_date: type: string format: date-time description: Last modification timestamp. UTC ISO 8601, e.g. "2024-01-15T10:30:00Z". required: - id - status title: PurchaseOrderUpdateResponse PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsItemsItemsDimensions: type: object properties: {} description: >- Dimension values keyed by type (e.g. PROJECT, CLASS). Each value is the ERP external_id of the dimension. When provided, REPLACES all existing dimensions on the item — include every dimension you want to keep. Omit the field or pass null to leave dimensions unchanged. Passing {} returns 400. title: PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsItemsItemsDimensions PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsItemsItems: type: object properties: external_id: type: string name: type: string sku: type: string quantity: type: number format: double price: type: number format: double uom: type: string dimensions: oneOf: - $ref: '#/components/schemas/PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsItemsItemsDimensions' - type: 'null' description: >- Dimension values keyed by type (e.g. PROJECT, CLASS). Each value is the ERP external_id of the dimension. When provided, REPLACES all existing dimensions on the item — include every dimension you want to keep. Omit the field or pass null to leave dimensions unchanged. Passing {} returns 400. required: - name - quantity - price title: PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsItemsItems PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsCustomFields: type: object properties: {} description: Optional custom fields configured for this company's purchase orders title: PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsCustomFields PurchaseOrderBulkUpsertRequestPurchaseOrdersItems: type: object properties: external_id: type: string po_number: type: string erp_vendor_id: type: string description: External vendor identifier from ERP system erp_vendor_name: type: string description: Vendor name from ERP system date: type: string format: date total_amount: type: number format: double tax: type: number format: double freight: type: number format: double miscellaneous_charges: type: number format: double invoice_number_ref: type: string description: Invoice reference number is_2_way: type: boolean description: Whether this is a 2-way match PO items: type: array items: $ref: '#/components/schemas/PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsItemsItems' custom_fields: $ref: '#/components/schemas/PurchaseOrderBulkUpsertRequestPurchaseOrdersItemsCustomFields' description: Optional custom fields configured for this company's purchase orders required: - po_number - erp_vendor_id - date - total_amount - items title: PurchaseOrderBulkUpsertRequestPurchaseOrdersItems PurchaseOrderBulkUpsertRequest: type: object properties: ottimate_company_id: type: integer description: Company ID for all purchase orders in this batch ottimate_location_id: type: integer description: Default location ID for all purchase orders in this batch purchase_orders: type: array items: $ref: '#/components/schemas/PurchaseOrderBulkUpsertRequestPurchaseOrdersItems' description: Max 100 POs with max 1000 total items required: - ottimate_company_id - ottimate_location_id - purchase_orders title: PurchaseOrderBulkUpsertRequest BulkUpsertAsyncResponseStatus: type: string enum: - processing title: BulkUpsertAsyncResponseStatus BulkUpsertAsyncResponseSummary: type: object properties: count: type: integer total_items: type: integer title: BulkUpsertAsyncResponseSummary BulkUpsertAsyncResponse: type: object properties: version: type: string status: $ref: '#/components/schemas/BulkUpsertAsyncResponseStatus' batch_id: type: string batch_url: type: string results_url: type: string summary: $ref: '#/components/schemas/BulkUpsertAsyncResponseSummary' required: - status - batch_id title: BulkUpsertAsyncResponse ReceiptSummaryStatus: type: string enum: - open - pending - flagged - closed - archived - deleted title: ReceiptSummaryStatus ReceiptSummary: type: object properties: id: type: string external_id: type: string receipt_number: type: string status: $ref: '#/components/schemas/ReceiptSummaryStatus' ottimate_po_id: type: string date: type: string format: date total_amount: type: number format: double created_date: type: string format: date-time created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - status title: ReceiptSummary Receipts_get_receipts_root_Response_200: type: object properties: version: type: string count: type: integer page: type: integer limit: type: integer receipts: type: array items: $ref: '#/components/schemas/ReceiptSummary' title: Receipts_get_receipts_root_Response_200 ReceiptDetailReceiptStatus: type: string enum: - open - pending - flagged - closed - archived - deleted title: ReceiptDetailReceiptStatus ReceiptDetailReceiptItemsItems: type: object properties: id: type: string external_id: type: string ottimate_po_item_id: type: string name: type: string sku: type: string quantity: type: number format: double price: type: number format: double uom: type: string created_date: type: string format: date-time created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". title: ReceiptDetailReceiptItemsItems ReceiptDetailReceipt: type: object properties: id: type: string external_id: type: string receipt_number: type: string status: $ref: '#/components/schemas/ReceiptDetailReceiptStatus' ottimate_po_id: type: string date: type: string format: date total_amount: type: number format: double invoice_number_ref: type: string note: type: string items: type: array items: $ref: '#/components/schemas/ReceiptDetailReceiptItemsItems' created_date: type: string format: date-time created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - status title: ReceiptDetailReceipt ReceiptDetail: type: object properties: version: type: string receipt: $ref: '#/components/schemas/ReceiptDetailReceipt' required: - receipt title: ReceiptDetail ReceiptCreateRequestItemsItems: type: object properties: external_id: type: string description: External unique identifier for this receipt item. ottimate_po_item_id: type: string description: Ottimate-assigned PO item ID. Required unless po_external_item_id or sku is provided. po_external_item_id: type: string description: External ID (dd_unique_key) of the PO item — used for lookup when ottimate_po_item_id is not provided. sku: type: string description: >- SKU of the PO item — used for lookup when ottimate_po_item_id and po_external_item_id are not provided. Must match exactly one item on the PO. quantity: type: number format: double price: type: number format: double uom: type: string required: - quantity description: 'Each item requires quantity and one of: ottimate_po_item_id, po_external_item_id, or sku.' title: ReceiptCreateRequestItemsItems ReceiptCreateRequest: type: object properties: ottimate_po_id: type: string description: >- Ottimate-assigned purchase order ID. Required unless using PO lookup fields (erp_vendor_id + ottimate_location_id + po_number/po_external_id). ottimate_location_id: type: integer description: Location ID for PO lookup. Required when using lookup fields instead of ottimate_po_id. erp_vendor_id: type: string description: ERP vendor ID for PO lookup. Required when using lookup fields instead of ottimate_po_id. po_number: type: string description: PO number for lookup. Use with erp_vendor_id + ottimate_location_id when ottimate_po_id is not provided. po_external_id: type: string description: External ID (dd_unique_key) of the PO for lookup. Alternative to po_number. external_id: type: string description: External unique identifier for this receipt. receipt_number: type: string date: type: string format: date total_amount: type: number format: double invoice_number_ref: type: string description: Invoice reference number note: type: string items: type: array items: $ref: '#/components/schemas/ReceiptCreateRequestItemsItems' required: - receipt_number - date - total_amount - items description: >- To identify the PO, provide either ottimate_po_id OR the lookup combination: erp_vendor_id + ottimate_location_id + (po_number OR po_external_id). title: ReceiptCreateRequest ReceiptCreateResponseStatus: type: string enum: - open - pending - flagged - closed - archived - deleted title: ReceiptCreateResponseStatus ReceiptCreateResponse: type: object properties: id: type: string external_id: type: string receipt_number: type: string status: $ref: '#/components/schemas/ReceiptCreateResponseStatus' ottimate_po_id: type: string date: type: string format: date total_amount: type: number format: double items_count: type: integer created_date: type: string format: date-time description: Creation timestamp. UTC ISO 8601, e.g. "2024-01-16T14:30:00Z". required: - id - status title: ReceiptCreateResponse ReceiptsIdPatchRequestBodyContentApplicationJsonSchemaItemsItems: type: object properties: id: type: string description: Existing receipt item ID. If provided, updates that item; if omitted, creates a new item. external_id: type: string ottimate_po_item_id: type: string description: >- Ottimate-assigned PO item ID. Required when creating a new item (no id), unless po_external_item_id or sku is provided. po_external_item_id: type: string description: External ID (dd_unique_key) of the PO item — used for lookup when ottimate_po_item_id is not provided. sku: type: string description: >- SKU of the PO item — used for lookup when ottimate_po_item_id and po_external_item_id are not provided. Must match exactly one item on the PO. quantity: type: number format: double description: Required when creating a new item (no id). price: type: number format: double uom: type: string title: ReceiptsIdPatchRequestBodyContentApplicationJsonSchemaItemsItems ReceiptUpdateResponseStatus: type: string enum: - open - pending - flagged - closed - archived - deleted title: ReceiptUpdateResponseStatus ReceiptUpdateResponse: type: object properties: version: type: string id: type: string external_id: type: string receipt_number: type: string status: $ref: '#/components/schemas/ReceiptUpdateResponseStatus' ottimate_po_id: type: string date: type: string format: date total_amount: type: number format: double items_count: type: integer last_modified_date: type: string format: date-time description: Last modification timestamp. UTC ISO 8601, e.g. "2024-01-16T14:30:00Z". required: - id - status title: ReceiptUpdateResponse ReceiptBulkUpsertRequestReceiptsItemsItemsItems: type: object properties: external_id: type: string ottimate_po_item_id: type: string description: Ottimate-assigned PO item ID. Required unless po_external_item_id or sku is provided. po_external_item_id: type: string description: External ID (dd_unique_key) of the PO item — used for lookup when ottimate_po_item_id is not provided. sku: type: string description: >- SKU of the PO item — used for lookup when ottimate_po_item_id and po_external_item_id are not provided. Must match exactly one item on the PO. quantity: type: number format: double price: type: number format: double uom: type: string required: - quantity description: 'Each item requires quantity and one of: ottimate_po_item_id, po_external_item_id, or sku.' title: ReceiptBulkUpsertRequestReceiptsItemsItemsItems ReceiptBulkUpsertRequestReceiptsItems: type: object properties: ottimate_po_id: type: string description: Ottimate-assigned PO ID. Required unless using PO lookup fields. ottimate_location_id: type: integer description: Location (restaurant) ID for PO lookup. Required when using lookup fields instead of ottimate_po_id. erp_vendor_id: type: string description: ERP vendor ID for PO lookup. po_number: type: string description: PO number for lookup. po_external_id: type: string description: External ID (dd_unique_key) of the PO for lookup. Alternative to po_number. external_id: type: string receipt_number: type: string date: type: string format: date total_amount: type: number format: double invoice_number_ref: type: string description: Invoice reference number note: type: string items: type: array items: $ref: '#/components/schemas/ReceiptBulkUpsertRequestReceiptsItemsItemsItems' required: - receipt_number - date - total_amount - items description: >- To identify the PO, provide either ottimate_po_id OR erp_vendor_id + ottimate_location_id + (po_number OR po_external_id). title: ReceiptBulkUpsertRequestReceiptsItems ReceiptBulkUpsertRequest: type: object properties: ottimate_company_id: type: integer description: Company ID for all receipts in this batch receipts: type: array items: $ref: '#/components/schemas/ReceiptBulkUpsertRequestReceiptsItems' description: Max 100 receipts with max 1000 total items required: - ottimate_company_id - receipts title: ReceiptBulkUpsertRequest ReceiptBulkUpsertAsyncResponseStatus: type: string enum: - processing title: ReceiptBulkUpsertAsyncResponseStatus ReceiptBulkUpsertAsyncResponseSummary: type: object properties: count: type: integer total_items: type: integer title: ReceiptBulkUpsertAsyncResponseSummary ReceiptBulkUpsertAsyncResponse: type: object properties: version: type: string status: $ref: '#/components/schemas/ReceiptBulkUpsertAsyncResponseStatus' batch_id: type: string batch_url: type: string results_url: type: string summary: $ref: '#/components/schemas/ReceiptBulkUpsertAsyncResponseSummary' required: - status - batch_id title: ReceiptBulkUpsertAsyncResponse InvoicesGetParametersStatus: type: string enum: - approved - incomplete - archived - processing - needs-attention - ready-for-export - exported - pending-approval title: InvoicesGetParametersStatus InvoicesGetParametersPaymentStatus: type: string enum: - paid - partial - unpaid title: InvoicesGetParametersPaymentStatus InvoiceObjectType: type: string enum: - invoice - credit_memo - other description: Type of invoice document title: InvoiceObjectType InvoiceObjectPaymentStatus: type: string enum: - paid - partial - unpaid description: Payment status (paid, partial, unpaid) title: InvoiceObjectPaymentStatus InvoiceObjectLastModifiedUser: type: object properties: id: type: integer email: type: string format: email first_name: type: string last_name: type: string description: User who last modified the invoice title: InvoiceObjectLastModifiedUser InvoiceObjectOnHold: type: object properties: is_held: type: boolean description: Whether invoice is on hold reason: type: string description: Reason for hold description: Hold status information title: InvoiceObjectOnHold InvoiceObjectImagesItems: type: object properties: id: type: integer description: Unique image identifier url: type: string description: CDN URL to the invoice image title: InvoiceObjectImagesItems InvoiceObjectDimensions: type: object properties: {} description: >- Header-level dimension mappings. Contains accounting dimensions assigned to the invoice header (e.g., Department, Class, Location). title: InvoiceObjectDimensions InvoiceObject: type: object properties: id: type: string description: Unique invoice identifier in UUID v4 format invoice_number: type: string description: Invoice number from vendor ottimate_vendor_name: type: string description: Vendor name ottimate_location_name: type: string description: Location name invoice_date: type: string format: date description: Date invoice was issued due_date: type: string format: date description: Payment due date total_amount: type: number format: double description: Total invoice amount total_tax: type: number format: double description: Total tax amount currency: type: string description: Currency code (ISO 4217) outstanding_balance: type: number format: double description: Remaining unpaid amount type: $ref: '#/components/schemas/InvoiceObjectType' description: Type of invoice document status: type: string description: Invoice processing status (processing, incomplete, approved, archived) payment_status: $ref: '#/components/schemas/InvoiceObjectPaymentStatus' description: Payment status (paid, partial, unpaid) purchase_order: type: string description: Associated purchase order number created_at: type: string format: date-time description: Timestamp when invoice was created created_at_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_at. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". approved_date: type: string format: date-time description: Date when invoice was approved approved_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of approved_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". exported_date: type: string format: date-time description: Date when invoice was exported exported_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of exported_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time description: Timestamp when invoice was last modified last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_user: oneOf: - $ref: '#/components/schemas/InvoiceObjectLastModifiedUser' - type: 'null' description: User who last modified the invoice posting_date: type: string format: date description: Date when invoice was posted error: type: string description: Processing error message if invoice has issues has_price_variance: type: boolean description: Whether invoice has price discrepancies has_unmatched_items: type: boolean description: Whether invoice has unmatched line items on_hold: $ref: '#/components/schemas/InvoiceObjectOnHold' description: Hold status information url: type: string description: URL to view the invoice in the Ottimate dashboard images: type: array items: $ref: '#/components/schemas/InvoiceObjectImagesItems' description: List of invoice images dimensions: $ref: '#/components/schemas/InvoiceObjectDimensions' description: >- Header-level dimension mappings. Contains accounting dimensions assigned to the invoice header (e.g., Department, Class, Location). required: - id - status - payment_status - created_at title: InvoiceObject Invoices_get_invoices_root_Response_200: type: object properties: version: type: string description: API version count: type: integer description: Total number of invoices matching the query results: type: array items: $ref: '#/components/schemas/InvoiceObject' description: Array of invoice objects required: - version - count - results title: Invoices_get_invoices_root_Response_200 InvoiceDetailObjectType: type: string enum: - invoice - credit_memo - other description: Type of invoice document title: InvoiceDetailObjectType InvoiceDetailObjectPaymentStatus: type: string enum: - paid - partial - unpaid description: Payment status title: InvoiceDetailObjectPaymentStatus InvoiceDetailObjectPaymentInfo: type: object properties: payment_method: type: string description: Method used for payment reference: type: string description: Payment reference number description: Payment information (only present if payment_status is 'paid') title: InvoiceDetailObjectPaymentInfo InvoiceDetailObjectImagesItems: type: object properties: id: type: integer description: Unique image identifier url: type: string description: CDN URL to the invoice image title: InvoiceDetailObjectImagesItems InvoiceDetailObjectDimensions: type: object properties: {} description: >- Header-level dimension mappings. Contains accounting dimensions assigned to the invoice header (e.g., Department, Class, Location). title: InvoiceDetailObjectDimensions InvoiceDetailObjectGlSplitsItemsCustomFields: type: object properties: {} description: Custom metadata fields for this split title: InvoiceDetailObjectGlSplitsItemsCustomFields InvoiceDetailObjectGlSplitsItemsDimensions: type: object properties: {} description: Accounting dimensions for this split. Same structure as header-level dimensions. Keys are dimension type codes. title: InvoiceDetailObjectGlSplitsItemsDimensions InvoiceDetailObjectGlSplitsItems: type: object properties: memo: type: - string - 'null' description: Optional note on the split amount: type: string description: Split amount formatted to 2 decimal places custom_fields: oneOf: - $ref: '#/components/schemas/InvoiceDetailObjectGlSplitsItemsCustomFields' - type: 'null' description: Custom metadata fields for this split dimensions: oneOf: - $ref: '#/components/schemas/InvoiceDetailObjectGlSplitsItemsDimensions' - type: 'null' description: >- Accounting dimensions for this split. Same structure as header-level dimensions. Keys are dimension type codes. title: InvoiceDetailObjectGlSplitsItems InvoiceDetailObjectItemsProcessingResultSuccess: type: object properties: {} description: Map of request array index to created/updated item ID title: InvoiceDetailObjectItemsProcessingResultSuccess InvoiceDetailObjectItemsProcessingResultFailure: type: object properties: {} description: Map of request array index to error message title: InvoiceDetailObjectItemsProcessingResultFailure InvoiceDetailObjectItemsProcessingResultStatus: type: string enum: - success - partial_success - failure description: 'Overall processing status: success (all items processed), partial_success (some failed), failure (all failed)' title: InvoiceDetailObjectItemsProcessingResultStatus InvoiceDetailObjectItemsProcessingResult: type: object properties: success: $ref: '#/components/schemas/InvoiceDetailObjectItemsProcessingResultSuccess' description: Map of request array index to created/updated item ID failure: $ref: '#/components/schemas/InvoiceDetailObjectItemsProcessingResultFailure' description: Map of request array index to error message status: $ref: '#/components/schemas/InvoiceDetailObjectItemsProcessingResultStatus' description: >- Overall processing status: success (all items processed), partial_success (some failed), failure (all failed) description: Result of items processing (only present in PATCH response when items were included in request) title: InvoiceDetailObjectItemsProcessingResult InvoiceDetailObjectHistoryItemsUser: type: object properties: id: type: integer description: User ID email: type: string description: Email address first_name: type: string description: First name last_name: type: string description: Last name description: User who performed the action title: InvoiceDetailObjectHistoryItemsUser InvoiceDetailObjectHistoryItems: type: object properties: id: type: integer description: History log entry ID date: type: string format: date-time description: Timestamp of the history event date_utc: type: - string - 'null' format: date-time description: UTC equivalent of date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". reason: type: string description: Type of action that occurred message: type: string description: Details about the action user: oneOf: - $ref: '#/components/schemas/InvoiceDetailObjectHistoryItemsUser' - type: 'null' description: User who performed the action title: InvoiceDetailObjectHistoryItems InvoiceDetailObjectLastModifiedUser: type: object properties: id: type: integer email: type: string format: email first_name: type: string last_name: type: string description: User who last modified the invoice title: InvoiceDetailObjectLastModifiedUser InvoiceDetailObject: type: object properties: version: type: string description: API version id: type: string description: Unique invoice identifier number: type: string description: Invoice number from vendor ottimate_vendor_name: type: string description: Vendor name ottimate_location_name: type: string description: Location name invoice_date: type: string format: date description: Date invoice was issued due_date: type: string format: date description: Payment due date total_amount: type: number format: double description: Total invoice amount total_tax: type: number format: double description: Total tax amount currency: type: string description: Currency code (ISO 4217) outstanding_balance: type: number format: double description: Remaining unpaid amount type: $ref: '#/components/schemas/InvoiceDetailObjectType' description: Type of invoice document status: type: string description: Processing status payment_status: $ref: '#/components/schemas/InvoiceDetailObjectPaymentStatus' description: Payment status payment_info: $ref: '#/components/schemas/InvoiceDetailObjectPaymentInfo' description: Payment information (only present if payment_status is 'paid') purchase_order: type: string description: Associated purchase order number created_at: type: string format: date-time description: Timestamp when invoice was created created_at_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_at. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". exported_date: type: string format: date-time description: Date when invoice was exported exported_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of exported_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". error: type: string description: Error message if invoice is flagged url: type: string description: URL to view the invoice in the Ottimate dashboard images: type: array items: $ref: '#/components/schemas/InvoiceDetailObjectImagesItems' description: List of invoice images dimensions: $ref: '#/components/schemas/InvoiceDetailObjectDimensions' description: >- Header-level dimension mappings. Contains accounting dimensions assigned to the invoice header (e.g., Department, Class, Location). gl_splits: type: - array - 'null' items: $ref: '#/components/schemas/InvoiceDetailObjectGlSplitsItems' description: >- GL account splits for the invoice. Returns real splits if they exist, otherwise falls back to virtual splits derived from vendor split rules. null when no splits or rules are configured. items_processing_result: $ref: '#/components/schemas/InvoiceDetailObjectItemsProcessingResult' description: Result of items processing (only present in PATCH response when items were included in request) history: type: array items: $ref: '#/components/schemas/InvoiceDetailObjectHistoryItems' description: Audit history of the invoice. Only present when expand=history is passed as a query parameter. last_modified_date: type: - string - 'null' format: date-time description: Timestamp when invoice was last modified last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_user: oneOf: - $ref: '#/components/schemas/InvoiceDetailObjectLastModifiedUser' - type: 'null' description: User who last modified the invoice required: - id - status - payment_status - created_at title: InvoiceDetailObject InvoicesIdPatchRequestBodyContentApplicationJsonSchemaType: type: string enum: - invoice - credit_memo description: Type of document. title: InvoicesIdPatchRequestBodyContentApplicationJsonSchemaType InvoicesIdPatchRequestBodyContentApplicationJsonSchemaDimensions: type: object properties: {} description: >- Header-level dimension mappings. Keys are dimension types (e.g., 'DEPARTMENT') and values are `erp_dimension_id` strings from the `GET /dimensions` endpoint. Replaces all header dimensions with the provided set. Omit the field entirely to preserve existing dimensions. Pass `{}` to clear all header dimensions. title: InvoicesIdPatchRequestBodyContentApplicationJsonSchemaDimensions InvoicesIdPatchRequestBodyContentApplicationJsonSchemaCustomFields: type: object properties: {} description: >- Header-level custom metadata fields. Replaces the stored custom fields with the provided object — any keys not included are reset to their configured default values. **Requirements**: Custom fields must be configured for your account before use. Returns a `400` error if no spec is found or if unrecognised keys are sent. **Behaviour**: Omit the field entirely to preserve existing custom fields. title: InvoicesIdPatchRequestBodyContentApplicationJsonSchemaCustomFields InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsDimensions: type: object properties: {} description: >- Item-level dimension mappings. Keys are dimension types, values are `erp_dimension_id` strings. Merges with existing dimensions. Set a value to `null` to remove only that dimension. Pass `{}` or omit the field to preserve existing dimensions. title: InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsDimensions InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsCustomFields: type: object properties: {} description: >- Item-level custom metadata fields. Replaces the stored item custom fields — omitted keys are reset to their configured default values. **Requirements**: Invoice item custom fields must be configured for your account before use. Returns a `400` error if no spec is found or if unrecognised keys are sent. title: InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsCustomFields InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItems: type: object properties: id: type: integer description: Existing item ID to update. Omit to create a new item. item: type: integer description: Inventory item ID name: type: string sku: type: string quantity: type: number format: double price: type: number format: double is_taxed: type: boolean dimensions: $ref: '#/components/schemas/InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsDimensions' description: >- Item-level dimension mappings. Keys are dimension types, values are `erp_dimension_id` strings. Merges with existing dimensions. Set a value to `null` to remove only that dimension. Pass `{}` or omit the field to preserve existing dimensions. custom_fields: oneOf: - $ref: '#/components/schemas/InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItemsCustomFields' - type: 'null' description: >- Item-level custom metadata fields. Replaces the stored item custom fields — omitted keys are reset to their configured default values. **Requirements**: Invoice item custom fields must be configured for your account before use. Returns a `400` error if no spec is found or if unrecognised keys are sent. title: InvoicesIdPatchRequestBodyContentApplicationJsonSchemaItemsItems InvoicesIdPatchRequestBodyContentApplicationJsonSchemaRawImagesItems: type: object properties: filename: type: string description: Original filename including extension (e.g. invoice.pdf). Used to determine file format. data: type: string description: Base64-encoded image content. required: - filename - data title: InvoicesIdPatchRequestBodyContentApplicationJsonSchemaRawImagesItems InvoiceCreationResponse: type: object properties: version: type: string description: API response version reference_id: type: string description: The reference ID for the uploaded document. Use this to track the invoice through processing. required: - version - reference_id title: InvoiceCreationResponse InvoicesMarkExportedPostRequestBodyContentApplicationJsonSchemaInvoicesItems: type: object properties: invoice_id: type: integer description: Unique identifier for the invoice marked_reason: type: string description: Invoice specific reason displayed in the invoice history; overrides the batch-level reason export_transaction_id: type: string description: Invoice-specific transaction ID; overrides the batch-level transaction ID title: InvoicesMarkExportedPostRequestBodyContentApplicationJsonSchemaInvoicesItems BulkInvoiceOperationResponseFailedItems: type: object properties: id: type: integer description: Invoice ID that failed error: type: string description: Failure reason required: - id - error title: BulkInvoiceOperationResponseFailedItems BulkInvoiceOperationResponse: type: object properties: updated: type: array items: type: integer description: Successfully processed invoice IDs failed: type: array items: $ref: '#/components/schemas/BulkInvoiceOperationResponseFailedItems' description: Per-invoice errors required: - updated - failed title: BulkInvoiceOperationResponse InvoicesMarkUnexportedPostRequestBodyContentApplicationJsonSchemaInvoicesItems: type: object properties: invoice_id: type: integer description: Unique identifier for the invoice marked_reason: type: string description: Invoice specific reason displayed in the invoice history; overrides the batch-level reason title: InvoicesMarkUnexportedPostRequestBodyContentApplicationJsonSchemaInvoicesItems BulkInvoiceUnexportOperationResponseFailedItems: type: object properties: id: type: integer description: Invoice ID that failed error: type: string description: Failure reason required: - id - error title: BulkInvoiceUnexportOperationResponseFailedItems BulkInvoiceUnexportOperationResponseSkippedItems: type: object properties: id: type: integer description: Invoice ID that skipped error: type: string description: Skipped reason required: - id - error title: BulkInvoiceUnexportOperationResponseSkippedItems BulkInvoiceUnexportOperationResponse: type: object properties: updated: type: array items: type: integer description: Successfully processed invoice IDs flagged: type: array items: type: integer description: Successfully flagged invoice IDs failed: type: array items: $ref: '#/components/schemas/BulkInvoiceUnexportOperationResponseFailedItems' description: Per-invoice errors skipped: type: array items: $ref: '#/components/schemas/BulkInvoiceUnexportOperationResponseSkippedItems' description: Per-invoice errors required: - updated - failed title: BulkInvoiceUnexportOperationResponse InstantCaptureFileObject: type: object properties: id: type: string description: Unique file identifier filename: type: string description: Name of the file status: type: string description: Processing status of the file date: type: string format: date-time description: Date when the file was uploaded no_of_pages: type: integer description: Number of pages in the file ottimate_location_name: type: string description: Name of the location preview_url: type: string description: URL to preview the file required: - id - filename - status - date - no_of_pages title: InstantCaptureFileObject Invoices_get_invoices_uploads_Response_200: type: object properties: version: type: string description: API version count: type: integer description: Total number of files matching the query results: type: array items: $ref: '#/components/schemas/InstantCaptureFileObject' title: Invoices_get_invoices_uploads_Response_200 ApproverObjectApprover: type: object properties: id: type: string description: User ID email: type: string format: email description: User email address display_name: type: string description: User display name description: Approver user details title: ApproverObjectApprover ApproverObjectPolicy: type: object properties: id: type: string description: Policy ID name: type: string description: Policy name description: Policy that assigned this approver (null if manually added) title: ApproverObjectPolicy ApproverObject: type: object properties: id: type: string description: Unique approval record identifier approver: $ref: '#/components/schemas/ApproverObjectApprover' description: Approver user details policy: oneOf: - $ref: '#/components/schemas/ApproverObjectPolicy' - type: 'null' description: Policy that assigned this approver (null if manually added) created_date: type: string format: date-time description: Date when approver was added required: - id - approver - created_date title: ApproverObject Invoices_get_invoices_id_approvers_Response_200: type: object properties: version: type: string description: API version approvers: type: array items: $ref: '#/components/schemas/ApproverObject' title: Invoices_get_invoices_id_approvers_Response_200 InvoicesIdFlagPostResponsesContentApplicationJsonSchemaInvoice: type: object properties: id: type: string description: Invoice ID invoice_number: type: string description: Invoice number status: type: string description: Invoice status after flagging title: InvoicesIdFlagPostResponsesContentApplicationJsonSchemaInvoice Invoices_post_invoices_id_flag_Response_200: type: object properties: version: type: string description: API version success: type: boolean description: Whether the operation was successful message: type: string description: Success message invoice: $ref: '#/components/schemas/InvoicesIdFlagPostResponsesContentApplicationJsonSchemaInvoice' title: Invoices_post_invoices_id_flag_Response_200 InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsType: type: string enum: - invoice - credit_memo description: Type of document. title: InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsType InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsDimensions: type: object properties: {} description: >- Header-level dimension mappings. Keys are dimension types (e.g., 'DEPARTMENT', 'CLASS') and values are `erp_dimension_id` strings from the `GET /dimensions` endpoint. If omitted, no dimensions are set. Invalid dimension types or IDs return a `400` error. title: InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsDimensions InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsCustomFields: type: object properties: {} description: >- Header-level custom metadata fields for this invoice. Keys and value types are validated against the custom field spec configured for your account in Ottimate. **Requirements**: Custom fields must be configured for your account before use. Sending `custom_fields` when no spec is configured returns a `400` error. Unrecognised keys return a `400` error. **Behaviour**: Omitted keys are filled with their configured default values. title: InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsCustomFields InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItemsDimensions: type: object properties: {} description: >- Item-level dimension mappings. Same format as header-level dimensions: keys are dimension types and values are `erp_dimension_id` strings. If omitted, no item-level dimensions are set. title: InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItemsDimensions InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItemsCustomFields: type: object properties: {} description: >- Item-level custom metadata fields. Keys and value types are validated against the invoice item custom field spec configured for your account in Ottimate. **Requirements**: Invoice item custom fields must be configured for your account before use. Returns a `400` error if no spec is found or if unrecognised keys are sent. **Behaviour**: Omitted keys are filled with their configured default values. title: InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItemsCustomFields InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItems: type: object properties: name: type: string sku: type: string quantity: type: number format: double price: type: number format: double is_taxed: type: boolean dimensions: oneOf: - $ref: '#/components/schemas/InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItemsDimensions' - type: 'null' description: >- Item-level dimension mappings. Same format as header-level dimensions: keys are dimension types and values are `erp_dimension_id` strings. If omitted, no item-level dimensions are set. custom_fields: oneOf: - $ref: >- #/components/schemas/InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItemsCustomFields - type: 'null' description: >- Item-level custom metadata fields. Keys and value types are validated against the invoice item custom field spec configured for your account in Ottimate. **Requirements**: Invoice item custom fields must be configured for your account before use. Returns a `400` error if no spec is found or if unrecognised keys are sent. **Behaviour**: Omitted keys are filled with their configured default values. required: - name - quantity - price title: InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItems InvoicesImportPostRequestBodyContentApplicationJsonSchemaItems: type: object properties: upload_id: type: string description: A mandatory unique identifier for creating an invoice. ottimate_location_id: type: integer description: The ID of the location for this invoice. erp_vendor_id: type: string description: The ERP ID of the vendor for this invoice. invoice_number: type: string invoice_date: type: string format: date due_date: type: string format: date posting_date: type: string format: date total_amount: type: number format: double total_tax: type: number format: double purchase_order: type: string notes: type: string currency: type: string type: $ref: '#/components/schemas/InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsType' description: Type of document. dimensions: oneOf: - $ref: '#/components/schemas/InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsDimensions' - type: 'null' description: >- Header-level dimension mappings. Keys are dimension types (e.g., 'DEPARTMENT', 'CLASS') and values are `erp_dimension_id` strings from the `GET /dimensions` endpoint. If omitted, no dimensions are set. Invalid dimension types or IDs return a `400` error. custom_fields: oneOf: - $ref: '#/components/schemas/InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsCustomFields' - type: 'null' description: >- Header-level custom metadata fields for this invoice. Keys and value types are validated against the custom field spec configured for your account in Ottimate. **Requirements**: Custom fields must be configured for your account before use. Sending `custom_fields` when no spec is configured returns a `400` error. Unrecognised keys return a `400` error. **Behaviour**: Omitted keys are filled with their configured default values. image_urls: type: array items: type: string format: uri description: >- List of HTTPS image URLs to attach to the invoice. Supported formats: PDF, JPG, JPEG, PNG. raw_images is not supported for bulk import. items: type: array items: $ref: '#/components/schemas/InvoicesImportPostRequestBodyContentApplicationJsonSchemaItemsItemsItems' description: Line items to create for the invoice. required: - upload_id - ottimate_location_id title: InvoicesImportPostRequestBodyContentApplicationJsonSchemaItems InvoicesImportPostResponsesContentApplicationJsonSchemaSummary: type: object properties: invoice_count: type: integer description: Number of invoices accepted for processing. title: InvoicesImportPostResponsesContentApplicationJsonSchemaSummary Invoices_post_invoices_import_Response_202: type: object properties: status: type: string description: Always "processing" — indicates the job was queued. batch_id: type: string description: >- Unique ID for this batch job. Use with GET /v1/batch/{batch_id}/progress to poll status and GET /v1/batch/{batch_id}/results to fetch per-invoice outcomes. batch_url: type: string description: Relative URL to poll for batch progress. results_url: type: string description: Relative URL to fetch per-invoice results once the batch completes. summary: $ref: '#/components/schemas/InvoicesImportPostResponsesContentApplicationJsonSchemaSummary' title: Invoices_post_invoices_import_Response_202 InvoicesIdImagesPatchResponsesContentApplicationJsonSchemaImagesItems: type: object properties: id: type: integer url: type: string title: InvoicesIdImagesPatchResponsesContentApplicationJsonSchemaImagesItems InvoicesIdImagesPatchResponsesContentApplicationJsonSchemaImageErrorsItems: type: object properties: source: type: string description: Filename of the file that failed. error: type: string description: Human-readable error message. title: InvoicesIdImagesPatchResponsesContentApplicationJsonSchemaImageErrorsItems Invoices_patch_invoices_id_images_Response_200: type: object properties: images: type: array items: $ref: '#/components/schemas/InvoicesIdImagesPatchResponsesContentApplicationJsonSchemaImagesItems' image_errors: type: array items: $ref: '#/components/schemas/InvoicesIdImagesPatchResponsesContentApplicationJsonSchemaImageErrorsItems' description: Always empty on 200. title: Invoices_patch_invoices_id_images_Response_200 InvoicesReceiverExportGetResponsesContentApplicationJsonSchemaResultsItemsReceiverLinesItems: type: object properties: catalog_unique_key: type: - string - 'null' description: Unique key identifying the matched catalog entry, suitable for cross-referencing with your catalog system upc: type: string description: >- Universal Product Code from the catalog entry, zero-padded to 13 digits (EAN-13 / GTIN-13). Empty string if no UPC is on file description: type: string description: Item name sourced from the matched catalog entry uom: type: string description: >- Catalog-normalized unit of measure (e.g. CS, EA, LB). Always reflects the catalog UOM, not the raw invoice UOM case_pack: type: number format: double description: Number of units per case as defined in the catalog entry quantity_received: type: number format: double description: >- UOM-normalized received quantity. For unit-matched lines billed per unit (UNIT_PRICE), the raw quantity is divided by case_pack to convert to cases. For all other matches the raw invoice quantity is returned as-is unit_price: type: number format: double description: Absolute unit price from the invoice line item extended_price: type: number format: double description: Absolute extended (total) price for this line item pack_size: type: - string - 'null' description: Human-readable pack size description from the catalog entry (e.g. '25 LB', '6 CT') vendor_id: type: - string - 'null' description: >- Vendor identifier for the inventory system (e.g. LOCSMS). Sourced from the vendor configuration on the location, not the invoice vendor object ottimate_catalog_id: type: string description: Ottimate-internal catalog entry identifier for audit and lookup. Not recognized by LOCSMS or servicers title: InvoicesReceiverExportGetResponsesContentApplicationJsonSchemaResultsItemsReceiverLinesItems InvoicesReceiverExportGetResponsesContentApplicationJsonSchemaResultsItems: type: object properties: ottimate_invoice_id: type: string description: Unique invoice identifier in Ottimate ottimate_company_id: type: integer description: Ottimate company identifier this invoice belongs to ottimate_location_id: type: integer description: Ottimate location identifier this invoice was received against invoice_number: type: - string - 'null' description: Invoice number as it appears on the vendor document vendor_name: type: string description: Name of the vendor in Ottimate invoice_date: type: - string - 'null' format: date description: Date the invoice was issued by the vendor exported_at: type: - string - 'null' format: date-time description: Timestamp when the invoice was exported from Ottimate to the ERP system exported_at_utc: type: - string - 'null' format: date-time description: UTC equivalent of exported_at. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". receiver_status: type: string description: >- 'success' for all returned records. Only invoices that are exported and have at least one catalog-matched non-fringe line are returned, so all results are by definition in a valid receivable state receiver_lines: type: array items: $ref: >- #/components/schemas/InvoicesReceiverExportGetResponsesContentApplicationJsonSchemaResultsItemsReceiverLinesItems description: >- Catalog-matched line items from this invoice. Unmatched lines and fringe catalog lines are excluded. Invoices with zero qualifying lines are omitted entirely. title: InvoicesReceiverExportGetResponsesContentApplicationJsonSchemaResultsItems Invoices_get_invoices_receiver-export_Response_200: type: object properties: count: type: integer description: Total number of invoices matching the query next: type: - string - 'null' format: uri description: URL for the next page of results, or null if on the last page previous: type: - string - 'null' format: uri description: URL for the previous page of results, or null if on the first page page: type: integer description: Current page number per_page: type: integer description: Number of results per page results: type: array items: $ref: '#/components/schemas/InvoicesReceiverExportGetResponsesContentApplicationJsonSchemaResultsItems' title: Invoices_get_invoices_receiver-export_Response_200 CatalogEntryListResponseResultsItems: type: object properties: id: type: string description: Unique identifier (prefixed with cte_) ottimate_company_id: type: integer description: Company ID reference_id: type: string description: Unique key for the catalog entry item_name: type: string description: Item name for the catalog entry description: type: string description: 'Deprecated: use item_name instead. This field will be removed in a future API version.' sku: type: string description: SKU code upc: type: string description: UPC code buying_format: type: - string - 'null' description: >- Buying format distinguishing multiple purchasing formats for the same item (e.g., 'CASE', 'EACH'). Used as part of the composite unique key for integrations that differentiate catalog entries by buying format. Optional — null or omitted for integrations that do not use buying format. pack_size: type: string description: Pack size uom: type: string description: Unit of measure price: type: string description: Price (decimal string) unit_price: type: string description: Unit price (decimal string) last_purchased_price: type: string description: Last purchased price (decimal string) erp_vendor_id: type: string description: ERP Vendor id from ERP/accounting system ottimate_vendor_name: type: - string - 'null' description: >- Deprecated. Use `erp_vendor_name` instead. Same value, kept for backward compatibility; will be removed in a future API version. erp_vendor_name: type: - string - 'null' description: >- Human-readable vendor name attached to erp_vendor_id, sourced from the originating system. Nullable when not provided. is_split_case: type: boolean description: Split case indicator last_purchased_date: type: string description: Last purchased date last_purchased_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_purchased_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". created_date: type: string format: date-time description: Record creation date created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time description: Record last modified date last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - ottimate_company_id - item_name description: Basic catalog entry object returned for list operations title: CatalogEntryListResponseResultsItems CatalogEntryListResponse: type: object properties: count: type: integer description: Total number of results results: type: array items: $ref: '#/components/schemas/CatalogEntryListResponseResultsItems' description: List of catalog entries (uses CatalogEntryBasicObject by default, CatalogEntryObject when expand is used) page: type: integer description: Current page number per_page: type: integer description: Items per page required: - count - results title: CatalogEntryListResponse CatalogEntriesPostRequestBodyContentApplicationJsonSchema: type: object properties: {} description: Additional custom properties as key-value pairs title: CatalogEntriesPostRequestBodyContentApplicationJsonSchema CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItemsPriceType: type: string enum: - company - location_group - location description: 'Price type: company (default), location_group, or location' title: CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItemsPriceType CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItemsData: type: object properties: {} description: Additional custom properties for this price title: CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItemsData CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItems: type: object properties: price: type: number format: double description: Price amount (required) unit_price: type: number format: double description: Price per individual unit price_type: $ref: '#/components/schemas/CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItemsPriceType' description: 'Price type: company (default), location_group, or location' ottimate_location_id: type: integer description: Location ID (required when price_type is 'location') ottimate_group_id: type: integer description: Location group ID (required when price_type is 'location_group') start_date: type: string format: date-time description: Price effective start date (ISO 8601) end_date: type: string format: date-time description: Price effective end date (ISO 8601) reference_id: type: string description: Unique key for this price record data: $ref: '#/components/schemas/CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItemsData' description: Additional custom properties for this price required: - price title: CatalogEntriesPostRequestBodyContentApplicationJsonSchemaPricesItems CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItemsTarget: type: string enum: - company - location_group - location description: 'Allowance target: company (default), location_group, or location' title: CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItemsTarget CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItemsData: type: object properties: {} description: Additional custom properties for this allowance title: CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItemsData CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItems: type: object properties: allowance_type: type: string description: Type of allowance (e.g., 'allowance', 'rebate') allowance: type: number format: double description: Allowance amount (required) unit_allowance: type: number format: double description: Allowance per individual unit target: $ref: '#/components/schemas/CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItemsTarget' description: 'Allowance target: company (default), location_group, or location' ottimate_location_id: type: integer description: Location ID (for location-level allowances) ottimate_group_id: type: integer description: Location group ID (for location_group-level allowances) start_date: type: string format: date-time description: Allowance effective start date (ISO 8601, required) end_date: type: string format: date-time description: Allowance effective end date (ISO 8601) reference_id: type: string description: Unique key for this allowance record data: $ref: '#/components/schemas/CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItemsData' description: Additional custom properties for this allowance required: - allowance - start_date title: CatalogEntriesPostRequestBodyContentApplicationJsonSchemaAllowancesItems CatalogEntryObjectDimensions: type: object properties: {} description: >- Resolved dimensions keyed by uppercase dimension type (e.g. DEPARTMENT, SUB_DEPARTMENT, CATEGORY, SUBCATEGORY, PROJECT, CLASS). Each value is the dimension name (or code if name is unavailable). title: CatalogEntryObjectDimensions CatalogEntryObjectPricesItemsPriceTypeDisplay: type: string enum: - company - location_group - location description: Human-readable price type title: CatalogEntryObjectPricesItemsPriceTypeDisplay CatalogEntryObjectPricesItems: type: object properties: id: type: string description: Price ID price: type: string description: Price amount (decimal string) unit_price: type: string description: Unit price (decimal string) price_type: type: integer description: Price type price_type_display: $ref: '#/components/schemas/CatalogEntryObjectPricesItemsPriceTypeDisplay' description: Human-readable price type ottimate_location_id: type: integer description: Location ID ottimate_group_id: type: integer description: Location group ID start_date: type: string format: date-time description: Price start date start_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of start_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". end_date: type: string format: date-time description: Price end date end_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of end_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". reference_id: type: string description: Unique key created_date: type: string format: date-time description: Record creation date created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time description: Record last modified date last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - price - price_type - start_date description: Catalog price object title: CatalogEntryObjectPricesItems CatalogEntryObjectAllowancesItemsAllowanceType: type: string enum: - allowance - discount - rebate description: Type of allowance title: CatalogEntryObjectAllowancesItemsAllowanceType CatalogEntryObjectAllowancesItemsTargetType: type: string enum: - company - location_group - location description: Human-readable target type title: CatalogEntryObjectAllowancesItemsTargetType CatalogEntryObjectAllowancesItems: type: object properties: id: type: string description: Allowance ID allowance_type: $ref: '#/components/schemas/CatalogEntryObjectAllowancesItemsAllowanceType' description: Type of allowance amount: type: string description: Allowance amount (decimal string) unit_allowance: type: string description: Unit allowance amount (decimal string) target: type: integer description: Target code (10=company, 15=location_group, 20=location) target_type: $ref: '#/components/schemas/CatalogEntryObjectAllowancesItemsTargetType' description: Human-readable target type ottimate_location_id: type: integer description: Location ID ottimate_group_id: type: integer description: Location group ID start_date: type: string format: date-time description: Allowance start date start_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of start_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". end_date: type: string format: date-time description: Allowance end date end_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of end_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". reference_id: type: string description: Unique key created_date: type: string format: date-time description: Record creation date created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time description: Record last modified date last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - allowance_type - amount - target - start_date description: Catalog allowance object nested in catalog entry title: CatalogEntryObjectAllowancesItems CatalogEntryObjectWarningsItems: type: object properties: message: type: string description: Warning message describing the missing field title: CatalogEntryObjectWarningsItems CatalogEntryObject: type: object properties: id: type: string description: Unique identifier (prefixed with cte_) ottimate_company_id: type: integer description: Company ID reference_id: type: string description: Unique key for the catalog entry item_name: type: string description: Item name for the catalog entry description: type: string description: 'Deprecated: use item_name instead. This field will be removed in a future API version.' sku: type: string description: SKU code upc: type: string description: UPC code buying_format: type: - string - 'null' description: >- Buying format distinguishing multiple purchasing formats for the same item (e.g., 'CASE', 'EACH'). Used as part of the composite unique key for integrations that differentiate catalog entries by buying format. Optional — null or omitted for integrations that do not use buying format. pack_size: type: string description: Pack size uom: type: string description: Unit of measure price: type: string description: Price (decimal string) unit_price: type: string description: Unit price (decimal string) last_purchased_price: type: string description: Last purchased price (decimal string) erp_vendor_id: type: string description: ERP Vendor id from ERP/accounting system ottimate_vendor_name: type: - string - 'null' description: >- Deprecated. Use `erp_vendor_name` instead. Same value, kept for backward compatibility; will be removed in a future API version. erp_vendor_name: type: - string - 'null' description: >- Human-readable vendor name attached to erp_vendor_id, sourced from the originating system. Nullable when not provided. is_split_case: type: boolean description: Split case indicator dimensions: oneOf: - $ref: '#/components/schemas/CatalogEntryObjectDimensions' - type: 'null' description: >- Resolved dimensions keyed by uppercase dimension type (e.g. DEPARTMENT, SUB_DEPARTMENT, CATEGORY, SUBCATEGORY, PROJECT, CLASS). Each value is the dimension name (or code if name is unavailable). display_name: type: string description: Display name for the item last_purchased_date: type: string description: Last purchased date last_purchased_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_purchased_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". created_date: type: string format: date-time description: Record creation date created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time description: Record last modified date last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". prices: type: array items: $ref: '#/components/schemas/CatalogEntryObjectPricesItems' description: List of catalog prices (only in retrieve or when expand=prices) allowances: type: array items: $ref: '#/components/schemas/CatalogEntryObjectAllowancesItems' description: List of catalog allowances (only in retrieve or when expand=allowances) warnings: type: array items: $ref: '#/components/schemas/CatalogEntryObjectWarningsItems' description: Soft-validation warnings. Present when the prices or allowances field was absent from the request. required: - id - ottimate_company_id - item_name description: Full catalog entry object returned for retrieve operations title: CatalogEntryObject CatalogEntriesIdPatchRequestBodyContentApplicationJsonSchema: type: object properties: {} description: Additional properties title: CatalogEntriesIdPatchRequestBodyContentApplicationJsonSchema CatalogAllowanceListResponseResultsItemsAllowanceType: type: string enum: - allowance - discount - rebate description: Type of allowance title: CatalogAllowanceListResponseResultsItemsAllowanceType CatalogAllowanceListResponseResultsItemsTargetType: type: string enum: - company - location_group - location description: Human-readable target type title: CatalogAllowanceListResponseResultsItemsTargetType CatalogAllowanceListResponseResultsItems: type: object properties: id: type: string description: Unique identifier catalog_entry_id: type: string description: Associated catalog entry ID (prefixed with cte_) ottimate_company_id: type: integer description: Company ID ottimate_location_id: type: integer description: Location ID allowance_type: $ref: '#/components/schemas/CatalogAllowanceListResponseResultsItemsAllowanceType' description: Type of allowance amount: type: string description: Allowance amount (decimal string) unit_allowance: type: string description: Unit allowance amount (decimal string) target: type: integer description: Target code (10=company, 15=location_group, 20=location) target_type: $ref: '#/components/schemas/CatalogAllowanceListResponseResultsItemsTargetType' description: Human-readable target type start_date: type: string description: Start date start_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of start_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". end_date: type: string description: End date end_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of end_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". reference_id: type: string description: Unique key created_date: type: string format: date-time description: Record creation date created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time description: Record last modified date last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - catalog_entry_id - ottimate_company_id - allowance_type - amount - target - start_date description: Catalog allowance object for standalone list endpoint title: CatalogAllowanceListResponseResultsItems CatalogAllowanceListResponse: type: object properties: count: type: integer results: type: array items: $ref: '#/components/schemas/CatalogAllowanceListResponseResultsItems' required: - count - results title: CatalogAllowanceListResponse CatalogAllowancesPostRequestBodyContentApplicationJsonSchemaAllowanceType: type: string enum: - allowance - discount - rebate description: 'Type of allowance (default: ''allowance'')' title: CatalogAllowancesPostRequestBodyContentApplicationJsonSchemaAllowanceType CatalogAllowancesPostRequestBodyContentApplicationJsonSchemaTarget: type: string enum: - company - location_group - location description: 'Allowance target: company (default), location_group, or location' title: CatalogAllowancesPostRequestBodyContentApplicationJsonSchemaTarget CatalogAllowanceObjectAllowanceType: type: string enum: - allowance - discount - rebate description: Type of allowance title: CatalogAllowanceObjectAllowanceType CatalogAllowanceObjectTargetType: type: string enum: - company - location_group - location description: Human-readable target type title: CatalogAllowanceObjectTargetType CatalogAllowanceObject: type: object properties: id: type: string description: Unique identifier catalog_entry_id: type: string description: Associated catalog entry ID (prefixed with cte_) ottimate_company_id: type: integer description: Company ID ottimate_location_id: type: integer description: Location ID allowance_type: $ref: '#/components/schemas/CatalogAllowanceObjectAllowanceType' description: Type of allowance amount: type: string description: Allowance amount (decimal string) unit_allowance: type: string description: Unit allowance amount (decimal string) target: type: integer description: Target code (10=company, 15=location_group, 20=location) target_type: $ref: '#/components/schemas/CatalogAllowanceObjectTargetType' description: Human-readable target type start_date: type: string format: date-time description: Start date start_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of start_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". end_date: type: string format: date-time description: End date end_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of end_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". reference_id: type: string description: Unique key created_date: type: string format: date-time description: Record creation date created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time description: Record last modified date last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - catalog_entry_id - ottimate_company_id - allowance_type - amount - target - start_date description: Catalog allowance object for standalone list endpoint title: CatalogAllowanceObject CatalogAllowancesIdPatchRequestBodyContentApplicationJsonSchemaAllowanceType: type: string enum: - allowance - discount - rebate description: Type of allowance title: CatalogAllowancesIdPatchRequestBodyContentApplicationJsonSchemaAllowanceType CatalogAllowancesIdPatchRequestBodyContentApplicationJsonSchemaTarget: type: string enum: - company - location_group - location description: 'Allowance target: company, location_group, or location' title: CatalogAllowancesIdPatchRequestBodyContentApplicationJsonSchemaTarget CatalogVariancesGetParametersExceptionType: type: string enum: - underbilling - overbilling title: CatalogVariancesGetParametersExceptionType VarianceListResponseResultsItemsLastInvoiceItem: type: object properties: id: type: integer price: type: number format: double invoice_date: type: string format: date price_variance: type: number format: double effective_price: type: number format: double required: - id - price - invoice_date title: VarianceListResponseResultsItemsLastInvoiceItem VarianceListResponseResultsItems: type: object properties: id: type: string description: Catalog entry ID item_name: type: string sku: type: string upc: type: string pack_size: type: string erp_vendor_id: type: string description: ERP Vendor id from ERP/accounting system last_invoice_item: $ref: '#/components/schemas/VarianceListResponseResultsItemsLastInvoiceItem' required: - id - item_name title: VarianceListResponseResultsItems VarianceListResponse: type: object properties: count: type: integer results: type: array items: $ref: '#/components/schemas/VarianceListResponseResultsItems' required: - count - results title: VarianceListResponse CatalogEntriesBulkAsyncResponseSummary: type: object properties: count: type: integer description: Number of entries submitted for processing description: Summary of the submitted request title: CatalogEntriesBulkAsyncResponseSummary CatalogEntriesBulkAsyncResponse: type: object properties: version: type: string description: API version of this response status: type: string description: Processing status batch_id: type: string description: Unique identifier for this batch job. Use to poll for progress. batch_url: type: string description: URL to poll for batch progress (GET) results_url: type: string description: URL to retrieve batch results once completed (GET) summary: $ref: '#/components/schemas/CatalogEntriesBulkAsyncResponseSummary' description: Summary of the submitted request required: - version - status - batch_id - batch_url - results_url - summary description: Response returned immediately when a bulk entries request is accepted for async processing. title: CatalogEntriesBulkAsyncResponse CatalogAllowancesBulkAsyncResponseSummary: type: object properties: count: type: integer description: Number of allowances submitted for processing description: Summary of the submitted request title: CatalogAllowancesBulkAsyncResponseSummary CatalogAllowancesBulkAsyncResponse: type: object properties: version: type: string description: API version of this response status: type: string description: Processing status batch_id: type: string description: Unique identifier for this batch job. Use to poll for progress. batch_url: type: string description: URL to poll for batch progress (GET) results_url: type: string description: URL to retrieve batch results once completed (GET) summary: $ref: '#/components/schemas/CatalogAllowancesBulkAsyncResponseSummary' description: Summary of the submitted request required: - version - status - batch_id - batch_url - results_url - summary description: Response returned immediately when a bulk allowances request is accepted for async processing. title: CatalogAllowancesBulkAsyncResponse CatalogPricesBulkAsyncResponseSummary: type: object properties: count: type: integer description: Number of prices submitted for processing description: Summary of the submitted request title: CatalogPricesBulkAsyncResponseSummary CatalogPricesBulkAsyncResponse: type: object properties: version: type: string description: API version of this response status: type: string description: Processing status batch_id: type: string description: Unique identifier for this batch job. Use to poll for progress. batch_url: type: string description: URL to poll for batch progress (GET) results_url: type: string description: URL to retrieve batch results once completed (GET) summary: $ref: '#/components/schemas/CatalogPricesBulkAsyncResponseSummary' description: Summary of the submitted request required: - version - status - batch_id - batch_url - results_url - summary description: Response returned immediately when a bulk prices request is accepted for async processing. title: CatalogPricesBulkAsyncResponse InvoiceItemVarianceListResponseResultsItems: type: object properties: id: type: integer invoice_id: type: integer item_name: type: string price: type: number format: double quantity: type: number format: double invoice_date: type: string format: date price_variance: type: number format: double effective_price: type: number format: double required: - id - invoice_id - item_name - price - quantity - invoice_date title: InvoiceItemVarianceListResponseResultsItems InvoiceItemVarianceListResponse: type: object properties: version: type: string description: API version count: type: integer description: Total number of invoice items page: type: integer description: Current page number limit: type: integer description: Items per page results: type: array items: $ref: '#/components/schemas/InvoiceItemVarianceListResponseResultsItems' required: - count - results description: Paginated list of invoice items with variance information title: InvoiceItemVarianceListResponse CatalogVarianceBatchObjectExportStatus: type: string enum: - exported description: Always 'exported' — non-exported batches are never returned by this API title: CatalogVarianceBatchObjectExportStatus CatalogItemPayload: type: object properties: {} description: Additional metadata from the catalog entry title: CatalogItemPayload CostBatchPayload: type: object properties: description: type: string description: Human-readable batch description, e.g. 'Catalog Batch 42' zone: type: string description: Geographical zone for this batch import_def_id: type: integer description: Pyxis import definition ID from the company token. Defaults to 0 if no Pyxis token is configured. external_batch_number: type: string description: String representation of the batch number start_datetime: type: string format: date-time description: Start date for this batch's price updates catalog_items: type: array items: $ref: '#/components/schemas/CatalogItemPayload' description: List of catalog items with updated costs description: Costbatch payload in the same shape as the Pyxis /costbatch endpoint. title: CostBatchPayload CatalogVarianceBatchObject: type: object properties: id: type: string description: Unique batch identifier (prefixed with ctb_) ottimate_company_id: type: integer description: Company ID this batch belongs to batch_number: type: integer description: Sequential batch number within the company export_status: $ref: '#/components/schemas/CatalogVarianceBatchObjectExportStatus' description: Always 'exported' — non-exported batches are never returned by this API exported_at: type: string format: date-time description: Timestamp when the batch was exported exported_at_utc: type: - string - 'null' format: date-time description: UTC equivalent of exported_at. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". costbatch_payload: $ref: '#/components/schemas/CostBatchPayload' required: - id - ottimate_company_id - batch_number - export_status - exported_at - costbatch_payload description: An exported Catalog Variance Manager batch. title: CatalogVarianceBatchObject CatalogVarianceBatchListResponse: type: object properties: count: type: integer description: Total number of results next: type: - string - 'null' description: URL to next page, or null previous: type: - string - 'null' description: URL to previous page, or null results: type: array items: $ref: '#/components/schemas/CatalogVarianceBatchObject' description: Paginated list of exported catalog variance batches. title: CatalogVarianceBatchListResponse CatalogPricesGetParametersPriceType: type: string enum: - company - location_group - location title: CatalogPricesGetParametersPriceType CatalogPriceItemPriceTypeDisplay: type: string enum: - company - location_group - location description: Human-readable price type title: CatalogPriceItemPriceTypeDisplay CatalogPriceItem: type: object properties: id: type: string description: Price ID catalog_entry_id: type: string description: Catalog entry ID ottimate_company_id: type: integer description: Company ID price: type: string description: Price amount (decimal string) unit_price: type: string description: Unit price (decimal string) price_type: type: integer description: Price type price_type_display: $ref: '#/components/schemas/CatalogPriceItemPriceTypeDisplay' description: Human-readable price type ottimate_location_id: type: integer description: Location ID ottimate_group_id: type: integer description: Location group ID start_date: type: string format: date-time description: Price start date end_date: type: string format: date-time description: Price end date reference_id: type: string description: Unique key created_date: type: string format: date-time description: Record creation date created_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of created_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". last_modified_date: type: string format: date-time description: Record last modified date last_modified_date_utc: type: - string - 'null' format: date-time description: UTC equivalent of last_modified_date. ISO 8601 with Z suffix, e.g. "2025-05-20T15:17:35.652584Z". required: - id - price - price_type - start_date description: Catalog price object title: CatalogPriceItem Catalog_get_catalog_prices_Response_200: type: object properties: count: type: integer page: type: integer per_page: type: integer results: type: array items: $ref: '#/components/schemas/CatalogPriceItem' required: - count - results description: Paginated list of catalog prices title: Catalog_get_catalog_prices_Response_200 CatalogPricesPostRequestBodyContentApplicationJsonSchemaPriceType: type: string enum: - company - location_group - location description: 'Price type: company (default), location_group, or location' title: CatalogPricesPostRequestBodyContentApplicationJsonSchemaPriceType BatchProgressResponseStatus: type: string enum: - processing - completed description: >- `processing` while tasks are running; `completed` when all tasks have finished (regardless of individual success/failure) title: BatchProgressResponseStatus BatchProgressResponse: type: object properties: version: type: string batch_id: type: string description: The batch identifier progress: type: number format: double description: Fraction of tasks completed (0.0 to 1.0). Value of 1.0 means all tasks have finished (success or failure). tasks_count: type: integer description: Total number of tasks in the batch tasks_completed: type: integer description: Number of tasks that completed successfully tasks_failed: type: integer description: Number of tasks that failed status: $ref: '#/components/schemas/BatchProgressResponseStatus' description: >- `processing` while tasks are running; `completed` when all tasks have finished (regardless of individual success/failure) results_url: type: - string - 'null' description: URL to fetch per-task results. Present only when `status` is `completed`. error: type: - string - 'null' description: Error message when all tasks in the batch failed. Null otherwise. required: - version - batch_id - progress - tasks_count - tasks_completed - tasks_failed - status title: BatchProgressResponse BatchResultsResponseResultsItems: type: object properties: task: type: integer description: Internal task ID result: description: The outcome of the task (e.g. the created/updated resource). Null if the task failed. message: type: string description: Error message if the task failed. Null on success. required: - task title: BatchResultsResponseResultsItems BatchResultsResponse: type: object properties: version: type: string batch_id: type: string description: The batch identifier results: type: array items: $ref: '#/components/schemas/BatchResultsResponseResultsItems' description: One entry per task in the batch required: - version - batch_id - results title: BatchResultsResponse BatchGetParametersStatus: type: string enum: - processing - completed title: BatchGetParametersStatus BatchGetResponsesContentApplicationJsonSchemaResultsItemsStatus: type: string enum: - processing - completed description: '`processing` while tasks are running; `completed` when all tasks have finished' title: BatchGetResponsesContentApplicationJsonSchemaResultsItemsStatus BatchGetResponsesContentApplicationJsonSchemaResultsItems: type: object properties: batch_id: type: string description: The batch identifier. Use this to poll `/batch/{id}/progress` or fetch `/batch/{id}/results`. status: $ref: '#/components/schemas/BatchGetResponsesContentApplicationJsonSchemaResultsItemsStatus' description: '`processing` while tasks are running; `completed` when all tasks have finished' progress: type: number format: double description: Fraction of tasks completed (0.0 to 1.0) tasks_count: type: integer description: Total number of tasks in the batch tasks_completed: type: integer description: Number of tasks that completed successfully tasks_failed: type: integer description: Number of tasks that failed modified_at: type: string description: Last time the batch was modified completed_at: type: - string - 'null' description: When the batch finished, or null if still processing required: - batch_id - status - progress - tasks_count - tasks_completed - tasks_failed - modified_at title: BatchGetResponsesContentApplicationJsonSchemaResultsItems Batch_get_batch_root_Response_200: type: object properties: count: type: integer description: Total number of batches matching the filter results: type: array items: $ref: '#/components/schemas/BatchGetResponsesContentApplicationJsonSchemaResultsItems' title: Batch_get_batch_root_Response_200 securitySchemes: OAuth2: type: http scheme: bearer description: OAuth2 authentication flows. Auth server URLs will vary by environment