> ## Documentation Index
> Fetch the complete documentation index at: https://docs.loice.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Start an employee search

> Finds the current employees of ONE company, named by its website `domain` or its LinkedIn company URL, optionally filtered by title, seniority, department and location. Creates a **background run** like `POST /api/v1/lead-search` and returns immediately; poll and read it with `GET /api/v1/lead-search/runs/{runId}`. One active run per workspace at a time. Rate limited per workspace.

#### Billing

- once per search, when any source answered; released when every source was unavailable.
- per delivered employee, debited when the run finalizes; an empty run is free.

The current cost is shown in the app under Settings → Billing and in the live `GET /api/v1/openapi.json`. Calls that end in a system or provider error (HTTP 500) or are rate limited (HTTP 429) are not billed. The `charged` and `pointsCharged` fields of the response state what this call actually consumed.



## OpenAPI

````yaml /openapi.json post /api/v1/employee-search
openapi: 3.1.0
info:
  title: Loice API
  version: v1
  description: >-
    The Loice API finds and verifies professional contact data. Every capability
    is exposed here, key-authenticated and rate-limited; the web app is a client
    of the same platform.


    **Authentication** — pass your workspace API key on every request (except
    the API description) as `Authorization: Bearer loice_sk_…`. Keys are created
    under Settings → API Keys.


    **Billing** — operations are billed in points against your workspace
    balance. Each operation below states when the charge applies. The current
    cost of every operation is shown in the app under [Settings →
    Billing](https://app.loice.ai/settings/account?tab=billing) and in the live
    API description, `GET /api/v1/openapi.json`. Calls that fail because of a
    system or provider error (timeouts, upstream failures, our defects) are not
    billed, and rate-limited calls are rejected before any billable work. Check
    headroom with `GET /api/v1/points`. Where an operation documents an
    `Idempotency-Key` header, send one to retry safely: a repeated request
    returns the original outcome and is not charged again.


    **Errors** — every non-200 response has the shape `{ "error": { "message":
    "…" } }`. Operations whose error responses document an `error.code` also
    return that machine-readable code beside the message; branch on the code,
    not the text.
servers:
  - url: https://app.loice.ai
security: []
paths:
  /api/v1/employee-search:
    post:
      summary: Start an employee search
      description: >-
        Finds the current employees of ONE company, named by its website
        `domain` or its LinkedIn company URL, optionally filtered by title,
        seniority, department and location. Creates a **background run** like
        `POST /api/v1/lead-search` and returns immediately; poll and read it
        with `GET /api/v1/lead-search/runs/{runId}`. One active run per
        workspace at a time. Rate limited per workspace.


        #### Billing


        - once per search, when any source answered; released when every source
        was unavailable.

        - per delivered employee, debited when the run finalizes; an empty run
        is free.


        The current cost is shown in the app under Settings → Billing and in the
        live `GET /api/v1/openapi.json`. Calls that end in a system or provider
        error (HTTP 500) or are rate limited (HTTP 429) are not billed. The
        `charged` and `pointsCharged` fields of the response state what this
        call actually consumed.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                lookup:
                  type: object
                  properties:
                    mode:
                      type: string
                      enum:
                        - domain
                        - linkedin
                    value:
                      type: string
                      minLength: 1
                      maxLength: 512
                  required:
                    - mode
                    - value
                count:
                  type: integer
                  minimum: 1
                  maximum: 2500
                filters:
                  type: object
                  properties:
                    title:
                      type: array
                      items:
                        type: string
                        maxLength: 200
                      maxItems: 20
                    seniority:
                      type: array
                      items:
                        type: string
                        enum:
                          - In Training
                          - Entry Level
                          - Senior
                          - Strategic
                          - Entry Level Manager
                          - Experienced Manager
                          - Director
                          - Vice President
                          - CXO
                          - Owner / Partner
                      maxItems: 20
                    department:
                      type: array
                      items:
                        type: string
                        enum:
                          - Accounting
                          - Administrative
                          - Arts and Design
                          - Business Development
                          - Community & Social Services
                          - Consulting
                          - Customer Success and Support
                          - Education
                          - Engineering
                          - Entrepreneurship
                          - Finance
                          - Healthcare Services
                          - Human Resources
                          - Information Technology
                          - Legal
                          - Marketing
                          - Media and Communication
                          - Military and Protective Services
                          - Operations
                          - Product Management
                          - Program and Project Management
                          - Purchasing
                          - Quality Assurance
                          - Real Estate
                          - Research
                          - Sales
                      maxItems: 20
                    location:
                      type: array
                      items:
                        type: string
                        maxLength: 200
                      maxItems: 20
                  additionalProperties: false
              required:
                - lookup
                - count
            example:
              lookup:
                mode: domain
                value: acme.io
              count: 25
              filters:
                department:
                  - Sales
      responses:
        '200':
          description: >-
            Run created, or refused uncharged with a `reason` (e.g.
            `company-not-found`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      run:
                        type: object
                        properties:
                          id:
                            type: string
                            description: >-
                              Run id — poll it via `GET
                              /api/v1/lead-search/runs/{runId}`.
                          kind:
                            type: string
                            enum:
                              - criteria
                              - employees
                            description: >-
                              Always `criteria` on v1 (a criteria search).
                              Employee Finder runs are not part of the public
                              API and answer 404.
                          lookupMode:
                            type:
                              - string
                              - 'null'
                            enum:
                              - domain
                              - linkedin
                              - null
                            description: >-
                              Employee Finder runs only; null for a criteria
                              run.
                          lookupInput:
                            type:
                              - string
                              - 'null'
                            description: >-
                              Employee Finder runs only; null for a criteria
                              run.
                          status:
                            type: string
                            enum:
                              - queued
                              - processing
                              - cancelling
                              - completed
                              - cancelled
                              - failed
                            description: >-
                              Lifecycle state.
                              `queued`/`processing`/`cancelling` are active —
                              keep polling; `completed`/`cancelled`/`failed` are
                              terminal.
                          requestedCount:
                            type: integer
                            description: Leads requested for this run.
                          deliveredCount:
                            type: integer
                            description: >-
                              Distinct leads delivered so far — the only number
                              billed.
                          sourceTotalElements:
                            type:
                              - integer
                              - 'null'
                            description: >-
                              Total results the source reports for these
                              criteria (set from the first fetched page); the
                              browsable window is capped at 100 pages.
                          sourceTotalPages:
                            type:
                              - integer
                              - 'null'
                            description: >-
                              Source-reported page count (capped at 100 by the
                              source).
                          sourceExhausted:
                            type: boolean
                            description: >-
                              True when the source ran out of matches before
                              `requestedCount`.
                          sourcePages:
                            type: array
                            items:
                              type: object
                              properties:
                                page:
                                  type: integer
                                  description: Source page number.
                                sourceRows:
                                  type: integer
                                  description: Rows the source returned for this page.
                                delivered:
                                  type: integer
                                  description: Rows this run delivered from it (billed).
                                notAtCompany:
                                  type: integer
                                  description: >-
                                    Rows whose stated employer did not match the
                                    company filter.
                                titleNotStated:
                                  type: integer
                                  description: >-
                                    Searches with a job-title filter: rows with
                                    no current position that states that title
                                    (for an employee search, no position at the
                                    company that states it). The source matches
                                    titles loosely. 0 otherwise.
                                duplicates:
                                  type: integer
                                  description: >-
                                    Rows already delivered on this page or by
                                    any earlier run of the chain.
                                doNotContact:
                                  type: integer
                                  description: Rows on the workspace’s do-not-contact list.
                                beyondRequested:
                                  type: integer
                                  description: >-
                                    Rows left once the run had `requestedCount`
                                    leads.
                              required:
                                - page
                                - sourceRows
                                - delivered
                                - notAtCompany
                                - titleNotStated
                                - duplicates
                                - doNotContact
                                - beyondRequested
                            description: >-
                              Per source page this run fetched, counts only:
                              what the source returned and why rows were not
                              delivered. `sourceRows` is `delivered` plus the
                              five reasons. Empty for runs created before this
                              field existed.
                          continuedFromId:
                            type:
                              - string
                              - 'null'
                            description: >-
                              Id of the run this one continues, when it is a
                              continuation.
                          unitCost:
                            type: integer
                            description: Points per delivered lead.
                          maxCost:
                            type: integer
                            description: >-
                              Worst-case cost disclosed up front: `unitCost ×
                              requestedCount` (reserved at creation; the unused
                              remainder frees at finalize).
                          creditsCharged:
                            type:
                              - integer
                              - 'null'
                            description: >-
                              Points actually debited — set at finalize to
                              `deliveredCount × unitCost`, null while the run is
                              active. An empty run charges 0.
                          error:
                            type:
                              - string
                              - 'null'
                            description: >-
                              Failure reason key when `status` is `failed` (e.g.
                              `search-failed`).
                          criteria:
                            type: object
                            additionalProperties:
                              type: array
                              items:
                                type: string
                            description: >-
                              Echo of the normalized search criteria the run
                              executes.
                          createdAt:
                            type: string
                            description: ISO timestamp the run was created.
                          startedAt:
                            type:
                              - string
                              - 'null'
                            description: ISO timestamp processing began, null while queued.
                          finishedAt:
                            type:
                              - string
                              - 'null'
                            description: ISO timestamp the run reached a terminal state.
                        required:
                          - id
                          - kind
                          - lookupMode
                          - lookupInput
                          - status
                          - requestedCount
                          - deliveredCount
                          - sourceTotalElements
                          - sourceTotalPages
                          - sourceExhausted
                          - sourcePages
                          - continuedFromId
                          - unitCost
                          - maxCost
                          - creditsCharged
                          - error
                          - criteria
                          - createdAt
                          - startedAt
                          - finishedAt
                      company: {}
                      balance:
                        type:
                          - object
                          - 'null'
                        properties:
                          available:
                            type: integer
                          reserved:
                            type: integer
                          granted:
                            type: integer
                        required:
                          - available
                          - reserved
                          - granted
                      replay:
                        type: boolean
                required:
                  - data
              example:
                data:
                  replay: false
        '400':
          description: >-
            `validation_error`: the body does not match the schema. Never
            billed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - validation_error
                          - unauthenticated
                          - not_found
                          - forbidden
                          - method_not_allowed
                          - idempotency_conflict
                          - idempotency_in_progress
                          - rate_limited
                          - internal_error
                          - run_already_active
                          - run_already_continued
                          - search_unavailable
                          - invalid_continuation
                          - invalid_input
                          - insufficient_credits
                          - incomplete
                        description: >-
                          Machine-readable error code. Branch on this, not on
                          `message`.
                      message:
                        type: string
                        description: Human-readable explanation.
                      retryAfterSeconds:
                        type: integer
                        description: >-
                          Present on a 429 only: seconds until the workspace may
                          call again (same value as the `Retry-After` header).
                    required:
                      - code
                      - message
                required:
                  - error
        '401':
          description: >-
            API key missing (`Missing API key. Pass it as: Authorization: Bearer
            <key>`), invalid (`Invalid API key`), or expired (`This API key has
            expired`).
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                    required:
                      - message
                required:
                  - error
        '405':
          description: Method not allowed — see the `Allow` response header.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                    required:
                      - message
                required:
                  - error
        '409':
          description: >-
            `run_already_active`: a run is already active for this workspace.
            Never billed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - validation_error
                          - unauthenticated
                          - not_found
                          - forbidden
                          - method_not_allowed
                          - idempotency_conflict
                          - idempotency_in_progress
                          - rate_limited
                          - internal_error
                          - run_already_active
                          - run_already_continued
                          - search_unavailable
                          - invalid_continuation
                          - invalid_input
                          - insufficient_credits
                          - incomplete
                        description: >-
                          Machine-readable error code. Branch on this, not on
                          `message`.
                      message:
                        type: string
                        description: Human-readable explanation.
                      retryAfterSeconds:
                        type: integer
                        description: >-
                          Present on a 429 only: seconds until the workspace may
                          call again (same value as the `Retry-After` header).
                    required:
                      - code
                      - message
                required:
                  - error
        '429':
          description: >-
            Rate limit exceeded for this workspace. Retry after the number of
            seconds in the `Retry-After` header (60). Rate-limited calls are
            never billed.
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      message:
                        type: string
                    required:
                      - message
                required:
                  - error
        '500':
          description: '`internal_error`: failed on our side. Never billed.'
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: object
                    properties:
                      code:
                        type: string
                        enum:
                          - validation_error
                          - unauthenticated
                          - not_found
                          - forbidden
                          - method_not_allowed
                          - idempotency_conflict
                          - idempotency_in_progress
                          - rate_limited
                          - internal_error
                          - run_already_active
                          - run_already_continued
                          - search_unavailable
                          - invalid_continuation
                          - invalid_input
                          - insufficient_credits
                          - incomplete
                        description: >-
                          Machine-readable error code. Branch on this, not on
                          `message`.
                      message:
                        type: string
                        description: Human-readable explanation.
                      retryAfterSeconds:
                        type: integer
                        description: >-
                          Present on a 429 only: seconds until the workspace may
                          call again (same value as the `Retry-After` header).
                    required:
                      - code
                      - message
                required:
                  - error
      security:
        - workspaceApiKey: []
components:
  securitySchemes:
    workspaceApiKey:
      type: http
      scheme: bearer
      description: >-
        Workspace API key (`loice_sk_` + 48 hex characters), created under
        Settings → API Keys. Sent as `Authorization: Bearer loice_sk_…`.
        Invalid, missing, or expired keys are rejected with 401 before any
        billable work happens.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.