Vic.ai Companies API

The companies in the Vic system.

OpenAPI Specification

vicai-companies-api-openapi.yml Raw ↑
openapi: 3.1.0
info:
  version: v10.40.4
  contact: {}
  title: Vic.ai Accounts Companies API
  description: "## Introduction\n\nThe Vic.ai API provides a seamless connection between your Enterprise Resource\nPlanning (ERP) system and the Vic.ai product suite.\n\nThe API is designed to offer three main areas of functionality:\n\n- **Syncing master data:** This refers to the data in your ERP that Vic.ai\n  interacts with. You are required to supply and update this data in Vic.ai, and\n  you also have the option to verify the copy of the masterdata in Vic.ai.\n\n- **Syncing training data:** We need historical data to train your AI model. To\n  that end, the API provides endpoints to sync historical invoices into Vic.ai\n  and to confirm their presence.\n\n- **Subscribing to and receiving webhooks:** Webhooks enable users or automated\n  tasks to interact with your ERP through various actions in the Vic.ai product\n  suite, such as posting an invoice, payment or purchase order or requesting\n  synchronization. You will receive a notification via a webhook when these\n  actions occur.\n\n\nFor US-based integrations, please use the following base API URL:\n\n```\nhttps://api.us.vic.ai\n```\n\nFor integrations based in Norway, use the following base API URL:\n\n```\nhttps://api.no.vic.ai\n```\n\nAll paths mentioned in this documentation should use one of these URLs as the\nbase.\n\nExample:\n\n```bash\ncurl https://api.us.vic.ai/v0/healthCheck \\\n    -H \"Content-Type: application/json\" \\\n    -H \"Authorization: Bearer YOUR_ACCESS_TOKEN\"\n```\n\n## Getting Started\n\nTo begin interacting with the Vic.ai API, you will need the following\ncredentials:\n\n* A Vic.ai client ID\n* A Vic.ai client secret.\n\nThese can be provided to you securely by a Vic.ai representative\n[upon request](https://www.vic.ai/book-a-demo).\n\n**Please note:** These credentials are essentially the keys to your ERP\nintegration. If they fall into the wrong hands, unauthorized parties could\nimpersonate you, gain access to sensitive data, and potentially perform\nmalicious actions. Therefore, it's crucial to keep these credentials safe at all\ntimes to protect your application's integrity and your clients' data.\n\n### Limitations\n\nThe Vic.ai API has the following limitations:\n\n**Rate Limiting:** The API is rate-limited to 500 requests per 10-second time\nframe. If you exceed this limit, you will receive a `429 Too Many Requests`\nresponse. The limit is per Oauth client ID. If you continue to receive `429`s,\nplease contact support with a request id from the response headers.\n"
servers:
- url: https://api.no.stage.vic.ai
  description: staging server, NO
- url: https://api.us.vic.ai
  description: production server, US
- url: https://api.no.vic.ai
  description: production server, NO
security:
- BearerAuth: []
tags:
- name: Companies
  description: The companies in the Vic system.
paths:
  /v2/organizations/{organization_id}/companies:
    post:
      description: 'Create a company under a specific organization, using partner

        authentication. The company is created under the organization named in

        the path — which must be one the authenticated partner client already

        has access to (e.g. one it created via `POST /v2/organizations`) — and

        any `organization_id` in the request body is ignored.


        The response includes the new company''s company-scoped OAuth client so

        the partner can bootstrap a company-level integration without a second

        round-trip; the `client_secret` is returned only at creation time and

        cannot be retrieved later.


        Use this to create the first company under a newly-created organization,

        where no company-scoped client exists yet to call `POST /v2/companies`.

        '
      summary: Create a company under an organization
      operationId: createOrganizationCompanyV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: organization_id
        description: The ID of the organization to create the company under.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        $ref: '#/components/requestBodies/CreateCompanyRequestV2'
      responses:
        '201':
          $ref: '#/components/responses/CreateCompanyResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies:
    get:
      description: Search and list companies accessible.
      summary: Search and list companies accessible
      operationId: listCompaniesV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: name_contains
        description: 'List companies with names containing the value provided. This is a

          case insensitive match.

          '
        in: query
        schema:
          type: string
      - name: remote_id
        description: 'Filter by a companies remote ID.

          '
        in: query
        schema:
          type: string
      - $ref: '#/components/parameters/PaginationV2'
      responses:
        '200':
          $ref: '#/components/responses/ListCompaniesResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
    post:
      description: 'Create a new company and automatically grant the authenticated OAuth

        client access to it. The company is created under the same organization

        as the OAuth client''s primary company, unless `organization_id` is

        provided (must be an organization the client already has access to).


        After creation, use `POST /v2/companies/{company_id}/subscriptions` to

        set up webhook subscriptions for the new company.

        '
      summary: Create a company
      operationId: createCompanyV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      requestBody:
        $ref: '#/components/requestBodies/CreateCompanyRequestV2'
      responses:
        '201':
          $ref: '#/components/responses/CreateCompanyResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}/tags:
    get:
      description: 'List the tags assigned to a company. Requires partner authentication;

        the company must belong to an organization the partner can access.

        '
      summary: List a company's tags
      operationId: listCompanyTagsV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID (UUID) of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The company's tags.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/CompanyTagV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
    post:
      description: 'Assign a tag to a company, using partner authentication. The company

        must belong to an organization the partner can access.


        Tags are how Vic expresses **company grouping**: mark the parent company

        of a group with the `group-leader` tag and a shared `group:<key>` tag,

        and mark each member company with the same `group:<key>` tag. Assigning

        a `group:`/`group-leader` tag also enables company groups on the

        organization. Re-assigning an existing tag is idempotent.

        '
      summary: Assign a tag to a company
      operationId: createCompanyTagV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID (UUID) of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCompanyTagV2'
      responses:
        '201':
          description: The assigned tag.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/CompanyTagV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}:
    get:
      description: Get a company.
      summary: Get a company
      operationId: getCompanyV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          $ref: '#/components/responses/GetCompanyResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}/users:
    get:
      description: List or search for users attached to the company
      summary: List or search for users attached to the company
      operationId: listCompanyUsersV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: name
        description: The name of the user. This is a case-insensitive match.
        in: query
        schema:
          type: string
      - name: name_contains
        description: 'The name of the user contains the value specified. This is a

          case-insensitive match.

          '
        in: query
        schema:
          type: string
      - name: email
        description: 'The user has the email address. This is a case-insensitive match.

          '
        in: query
        schema:
          type: string
      - name: email_contains
        description: 'The email of the user contains the value specified. This is a

          case-insensitive match.

          '
        in: query
        schema:
          type: string
      - $ref: '#/components/parameters/PaginationV2'
      responses:
        '200':
          $ref: '#/components/responses/ListCompanyUsersResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
    post:
      description: 'Create and attach a user to a company. If the user already exists, use

        the `attachUserToCompanyV2` (`POST /v2/companies/{company_id}/users/attach`)

        operation instead.

        '
      summary: Create and attach user to company
      operationId: createCompanyUserV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        $ref: '#/components/requestBodies/CreateCompanyUserRequestV2'
      responses:
        '201':
          $ref: '#/components/responses/CreateCompanyUserResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}/users/attach:
    post:
      description: 'Attaches an existing user to a company. You may provide the `user_id` or

        `email`. If the user does not exist, you will need to use the

        `createCompanyUserV2` operation.

        '
      summary: Attach an existing user to a company
      operationId: attachUserToCompanyV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        $ref: '#/components/requestBodies/AttachUserToCompanyRequestV2'
      responses:
        '201':
          $ref: '#/components/responses/CreateCompanyUserResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}/users/{user_id}:
    delete:
      description: 'Removes the user from the company. This does not remove them from the

        organization, even when the user is not attached to any companies within

        the organization.

        '
      summary: Remove user from company
      operationId: removeUserFromCompanyV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: user_id
        description: The ID of the user.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '204':
          $ref: '#/components/responses/RemoveUserFromCompanyResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}/users/{user_id}/roles:
    get:
      description: 'Returns the list of roles currently assigned to a user within a specific

        company. Roles are company-scoped and determine what actions the user can

        perform within that company.

        '
      summary: List a user's roles in a company
      operationId: listCompanyUserRolesV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: user_id
        description: The ID of the user.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          $ref: '#/components/responses/CompanyUserRolesResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
    post:
      description: 'Declaratively set the roles for a user within a company. The provided list

        of roles replaces the user''s current roles entirely — roles included in the

        list become active, and all others become inactive.


        This operation is idempotent: assigning roles that are already active has

        no effect on those roles.

        '
      summary: Update a user's roles in a company
      operationId: updateCompanyUserRolesV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: user_id
        description: The ID of the user.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        $ref: '#/components/requestBodies/UpdateCompanyUserRolesRequestV2'
      responses:
        '200':
          $ref: '#/components/responses/CompanyUserRolesResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}/fields/{field_label}/options:
    put:
      description: 'Replaces or adds company-specific options for a `select` custom field.

        When `replace` is `true`, the provided values become the full set of

        company-specific options for the field. When `replace` is `false`, the

        provided values are added to the existing company-specific options.


        The field label is the stable field identifier, such as

        `custom:department`. URL-encode the label when sending it as a path

        parameter, for example `custom%3Adepartment`.

        '
      summary: Manage company custom field options
      operationId: updateCompanyFieldOptionsV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: field_label
        description: The custom field label, URL-encoded as a path segment.
        in: path
        required: true
        schema:
          type: string
          example: custom%3Adepartment
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompanyFieldOptionsUpdateRequestV2'
      responses:
        '200':
          description: The resulting company-specific options for the field.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompanyFieldOptionsResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}/users/{user_id}/manager:
    patch:
      description: 'Set or clear the user''s manager. Provide `manager_id` to set the

        manager, or `null` to clear it. The manager must be a user within the

        same company.


        A user has a single manager that applies across every company they

        belong to. The company in the path scopes who may call this and which

        users are eligible to be the manager, but the resulting relationship is

        not company-specific: setting or clearing it here changes the user''s

        manager everywhere they are a member, which can affect approval routing

        in their other companies.


        A manager who is not a member of the company reads as `manager: null`

        in user responses. To protect that hidden assignment, passing

        `manager_id: null` is rejected when the user''s current manager is not a

        member of the company; assign a manager from within the company

        instead, or clear the manager through a company the current manager

        belongs to. An assignment to a deleted member of the company can

        always be cleared.


        A user cannot be their own manager, and two users cannot be each

        other''s manager; such requests are rejected.

        '
      summary: Set or clear a user's manager in a company
      operationId: updateCompanyUserManagerV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - name: company_id
        description: The ID of the company.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: user_id
        description: The ID of the user.
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        $ref: '#/components/requestBodies/UpdateCompanyUserManagerRequestV2'
      responses:
        '200':
          $ref: '#/components/responses/UpdateCompanyUserManagerResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
  /v2/companies/{company_id}/invoice_approval_flows:
    parameters:
    - $ref: '#/components/parameters/CompanyId'
    get:
      description: 'Lists invoice approval flows for a company. Returns a paginated list of

        approval flows with their selection rules and steps.

        '
      summary: List invoice approval flows
      operationId: listInvoiceApprovalFlowsV2
      tags:
      - Companies
      x-badges:
      - name: V2
        position: after
        color: blue
      parameters:
      - $ref: '#/components/parameters/PaginationV2'
      responses:
        '200':
          $ref: '#/components/responses/ListInvoiceApprovalFlowsResponseV2'
        4XX:
          $ref: '#/components/responses/ErrorResponseV2'
    post:
      description: "## Creating a Flow with Selection Rules\n\nWhen you create an approval flow (see the main invoice approval flow endpoint documentation for the request/response contract), you can define the selection rules that determine which invoices will be routed through that flow and its steps. The sections below describe the structure and semantics for those selection rules so you can include them in the `InvoiceApprovalFlowInputV2` payload.\n\n**Request Body:** `InvoiceApprovalFlowInputV2`\n\n**Response:** `201 Created` with the created flow data\n\n## Invoice Approval Flow Structure\n\nAn approval flow consists of:\n1. **Flow properties** - Label, description, ordering, and behavior settings\n2. **Selection rules** - Criteria that determine which invoices match this flow\n3. **Steps** - Sequential approval steps with their own selection and approver rules\n\n### Complete Flow Example\n\n```json\n{\n  \"label\": \"High Value Invoices\",\n  \"description\": \"Approval flow for invoices over $10,000\",\n  \"index\": 0,\n  \"auto_initiate\": true,\n  \"selection_rules\": [\n    {\n      \"type\": \"invoice_total_amount\",\n      \"comparator\": \"gte\",\n      \"values_type\": \"decimal\",\n      \"type_id\": null,\n      \"values\": [\n        {\n          \"value_type\": \"single\",\n          \"value\": \"10000.00\",\n          \"value_name\": \"10000.00\",\n          \"index\": 0\n        }\n      ]\n    }\n  ],\n  \"steps\": [\n    {\n      \"index\": 0,\n      \"approvers_required\": \"any\",\n      \"skip_if_no_approvers\": false,\n      \"selection_rules\": [],\n      \"approver_selection_rules\": [\n        {\n          \"type\": \"ROLE\",\n          \"values\": [\n            {\n              \"value\": \"Finance Manager\",\n              \"value_name\": \"Finance Manager\"\n            }\n          ]\n        }\n      ]\n    }\n  ]\n}\n```\n\n## Flow Properties\n\n### Required Fields\n\n- **`label`** (string, max 255 chars) - The label for the approval flow\n  - Example: `\"High Value Invoices\"`\n\n- **`description`** (string, max 255 chars) - A description of the approval flow\n  - Example: `\"Approval flow for invoices over $10,000\"`\n\n- **`index`** (integer, minimum 0) - The order index for this approval flow\n  - Flows are evaluated in order from lowest to highest index\n  - Example: `0`\n\n- **`auto_initiate`** (boolean) - Whether to automatically initiate this approval flow\n  - Example: `true`\n\n- **`selection_rules`** (array) - Selection rules that define when this flow applies\n  - See [Selection Rules](#selection-rules) section below\n\n### Optional Fields\n\n- **`steps`** (array) - The approval steps for this flow\n  - See [Approval Steps](#approval-steps) section below\n\n---\n\n## Selection Rules\n\nSelection rules determine which invoices match a particular flow or step based on various invoice attributes.\n\nSelection rules use the `InvoiceApprovalFlowSelectionRuleInputV2` schema with the following structure:\n\n```json\n{\n  \"type\": \"invoice_vendor_id\",\n  \"comparator\": \"eq\",\n  \"values_type\": \"list_of_values\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"12345\",\n      \"value_name\": \"Acme Corp\",\n      \"index\": 0\n    }\n  ]\n}\n```\n\n### Important Note on Display Names\n\n**Always populate `value_name`, `start_value_name`, and `end_value_name` fields.** These fields are used to display human-readable names in the user interface. While the `value` fields contain IDs or raw values for matching logic, the display name fields ensure users see meaningful text rather than cryptic IDs or numbers.\n\n### Selection Rule Types\n\nThe following selection rule types are available for matching invoices to flows and steps.\n\n#### 1. Invoice Vendor ID (`invoice_vendor_id`)\n\nMatches invoices from specific vendors.\n\n**Supported Comparators:** `eq`, `in`\n\n**Values Type:** `list_of_values`\n\n**Type ID:** Not used (set to `null`)\n\n**Values Structure:**\n- `value`: Vendor ID (as string)\n- `value_name`: Vendor name - **Always populate this for UI display**\n- `value_type`: Always `\"single\"`\n\n**Example - Single Vendor (eq):**\n```json\n{\n  \"type\": \"invoice_vendor_id\",\n  \"comparator\": \"eq\",\n  \"values_type\": \"list_of_values\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"12345\",\n      \"value_name\": \"Acme Corporation\",\n      \"index\": 0\n    }\n  ]\n}\n```\n\n**Example - Multiple Vendors (in):**\n```json\n{\n  \"type\": \"invoice_vendor_id\",\n  \"comparator\": \"in\",\n  \"values_type\": \"list_of_values\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"12345\",\n      \"value_name\": \"Acme Corporation\",\n      \"index\": 0\n    },\n    {\n      \"value_type\": \"single\",\n      \"value\": \"67890\",\n      \"value_name\": \"Beta Industries\",\n      \"index\": 1\n    }\n  ]\n}\n```\n\n---\n\n#### 2. Invoice Vendor Tags (`invoice_vendor_tags`)\n\nMatches invoices from vendors that have specific tags.\n\n**Supported Comparators:** `in`\n\n**Values Type:** `list_of_values`\n\n**Type ID:** Not used (set to `null`)\n\n**Values Structure:**\n- `value`: Tag ID (as string)\n- `value_name`: Tag value - **Always populate this for UI display**\n- `value_type`: Always `\"single\"`\n\n**Example:**\n```json\n{\n  \"type\": \"invoice_vendor_tags\",\n  \"comparator\": \"in\",\n  \"values_type\": \"list_of_values\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"100\",\n      \"value_name\": \"Preferred Vendor\",\n      \"index\": 0\n    },\n    {\n      \"value_type\": \"single\",\n      \"value\": \"101\",\n      \"value_name\": \"Critical Supplier\",\n      \"index\": 1\n    }\n  ]\n}\n```\n\n---\n\n#### 3. Invoice Total Amount (`invoice_total_amount`)\n\nMatches invoices based on the total amount of expense line items.\n\n**Supported Comparators:** `gt`, `gte`, `lt`, `lte`, `eq`\n\n**Values Type:** `decimal`\n\n**Type ID:** Not used (set to `null`)\n\n**Values Structure:**\n- `value`: Decimal amount (as string)\n- `value_name`: Amount formatted for display - **Should match `value` for consistency**\n- `value_type`: Always `\"single\"`\n- Only one value should be provided\n\n**Example - Greater Than or Equal:**\n```json\n{\n  \"type\": \"invoice_total_amount\",\n  \"comparator\": \"gte\",\n  \"values_type\": \"decimal\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"10000.00\",\n      \"value_name\": \"10000.00\",\n      \"index\": 0\n    }\n  ]\n}\n```\n\n**Example - Less Than:**\n```json\n{\n  \"type\": \"invoice_total_amount\",\n  \"comparator\": \"lt\",\n  \"values_type\": \"decimal\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"5000.00\",\n      \"value_name\": \"5000.00\",\n      \"index\": 0\n    }\n  ]\n}\n```\n\n---\n\n#### 4. Invoice PO Numbers (`invoice_po_numbers`)\n\nMatches invoices with purchase order numbers within numeric range(s).\n\n**Supported Comparators:** `between`\n\n**Values Type:** `positive_integer`\n\n**Type ID:** Not used (set to `null`)\n\n**Values Structure:**\n- `value_type`: Always `\"range\"`\n- `start_value`: Starting PO number (as string)\n- `start_value_name`: Starting PO number formatted for display - **Always populate for UI**\n- `end_value`: Ending PO number (as string)\n- `end_value_name`: Ending PO number formatted for display - **Always populate for UI**\n- Multiple ranges can be specified\n\n**Example - Single Range:**\n```json\n{\n  \"type\": \"invoice_po_numbers\",\n  \"comparator\": \"between\",\n  \"values_type\": \"positive_integer\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"range\",\n      \"start_value\": \"1000\",\n      \"start_value_name\": \"1000\",\n      \"end_value\": \"2000\",\n      \"end_value_name\": \"2000\",\n      \"index\": 0\n    }\n  ]\n}\n```\n\n**Example - Multiple Ranges:**\n```json\n{\n  \"type\": \"invoice_po_numbers\",\n  \"comparator\": \"between\",\n  \"values_type\": \"positive_integer\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"range\",\n      \"start_value\": \"1000\",\n      \"start_value_name\": \"1000\",\n      \"end_value\": \"2000\",\n      \"end_value_name\": \"2000\",\n      \"index\": 0\n    },\n    {\n      \"value_type\": \"range\",\n      \"start_value\": \"5000\",\n      \"start_value_name\": \"5000\",\n      \"end_value\": \"6000\",\n      \"end_value_name\": \"6000\",\n      \"index\": 1\n    }\n  ]\n}\n```\n\n---\n\n#### 5. Invoice Item Cost Account Number (`invoice_item_cost_account_number`)\n\nMatches invoices where any expense line item has a cost account matching the criteria.\n\n**Supported Comparators:** `eq`, `in`, `gt`, `gte`, `lt`, `lte`, `between`\n\n**Values Type:**\n- `list_of_values` for `eq`, `in`\n- `positive_integer` for `between`\n\n**Type ID:** Not used (set to `null`)\n\n**Values Structure for eq/in:**\n- `value`: Cost account number (as string)\n- `value_name`: Cost account display name - **Should include number and name** (e.g., \"1000 - Office Supplies\")\n- `value_type`: Always `\"single\"`\n\n**Example - Equals:**\n```json\n{\n  \"type\": \"invoice_item_cost_account_number\",\n  \"comparator\": \"eq\",\n  \"values_type\": \"list_of_values\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"5000\",\n      \"value_name\": \"5000 - Office Expenses\",\n      \"index\": 0\n    }\n  ]\n}\n```\n\n**Example - In List:**\n```json\n{\n  \"type\": \"invoice_item_cost_account_number\",\n  \"comparator\": \"in\",\n  \"values_type\": \"list_of_values\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"5000\",\n      \"value_name\": \"5000 - Office Expenses\",\n      \"index\": 0\n    },\n    {\n      \"value_type\": \"single\",\n      \"value\": \"6000\",\n      \"value_name\": \"6000 - Travel Expenses\",\n      \"index\": 1\n    }\n  ]\n}\n```\n\n**Example - Between Range:**\n```json\n{\n  \"type\": \"invoice_item_cost_account_number\",\n  \"comparator\": \"between\",\n  \"values_type\": \"positive_integer\",\n  \"type_id\": null,\n  \"values\": [\n    {\n      \"value_type\": \"range\",\n      \"start_value\": \"5000\",\n      \"start_value_name\": \"5000\",\n      \"end_value\": \"5999\",\n      \"end_value_name\": \"5999\",\n      \"index\": 0\n    }\n  ]\n}\n```\n\n---\n\n#### 6. Invoice Item Dimension Name (`invoice_item_dimension_name`)\n\nMatches invoices where any expense line item has a dimension of a specific type with matching values.\n\n**Supported Comparators:** `eq`, `in`\n\n**Values Type:** `list_of_values`\n\n**Type ID:** **REQUIRED** - Must contain the dimension type (from `dimension.type` field)\n- This is a lowercase string like `\"department\"`, `\"location\"`, `\"project\"`, etc.\n- The comparison is case-insensitive, so `dimension.type` can be `\"Department\"` or `\"DEPARTMENT\"` but `type_id` should be lowercase\n\n**Values Structure:**\n- `value`: **Dimension ID** (from `dimension.id`, as string)\n- `value_name`: **Dimension display name** (from `dimension.display_name`) - **Always populate for UI display**\n- `value_type`: Always `\"single\"`\n\n⚠️ **Important:**\n- The `value` field should contain the dimension **ID**, not the dimension name\n- The `value_name` field **must** contain the `display_name` for proper UI display\n- Never omit `value_name` - it's essential for users to understand what dimension they're selecting\n\n**Example - Equals Specific Department:**\n```json\n{\n  \"type\": \"invoice_item_dimension_name\",\n  \"comparator\": \"eq\",\n  \"values_type\": \"list_of_values\",\n  \"type_id\": \"department\",\n  \"values\": [\n    {\n      \"value_type\": \"single\",\n      \"value\": \"789\",\n      \"value_name\": \"Engineering\",\n      \"index\": 0\n    }\n  ]\n}\n```\n\n**Example - In Multiple Locations:**\n```json\n{\n  \"type\": \"invoice_item_dimension_name\",\n  \"comparator\": \"in\",\n  \"values_type\": \"list_of_values\",\n  \"type_id\": \"

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