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

# Submit Bulk Company Enrichment Job

> Submit up to 100,000 companies, by LinkedIn URL or website domain, for enrichment in one job. Returns a job ID at once; poll GET /v1/company-enrichment/bulk/{job_id} for progress.

Use this endpoint to enrich a list of companies asynchronously. Each row is an object with a `linkedin_url` or a `domain`:

```json theme={null}
{
  "input": [
    { "linkedin_url": "https://www.linkedin.com/company/kearney" },
    { "domain": "oliverwyman.com" }
  ]
}
```

Send the LinkedIn URL whenever you have it: it names the company directly, so it gives the best results. Use `domain` for rows where you only have the website. If a row fills both, the LinkedIn URL is used. Domains are read the same way as on [single enrichment](/docs/api-reference/company-enrichment#accepted-domains), and only return a company whose own website is on that domain.

The API accepts your list, charges your credit balance upfront, and returns a `job_id` immediately. Enrichment happens in the background. Poll [GET /v1/company-enrichment/bulk/\{job\_id}](/docs/api-reference/company-enrichment-bulk-status) to track progress, then fetch results via [GET /v1/company-enrichment/bulk/\{job\_id}/results](/docs/api-reference/company-enrichment-bulk-results) when the job is complete.

This endpoint is credit-metered and needs a pay-as-you-go API key.

## Your rows come back as you sent them

Results contain one row for every row you submitted, in the order you submitted them, with the LinkedIn URL or domain exactly as you sent it in `input`. You can join the results back to your own list by position or by `input`, without matching on our version of the URL.

## Duplicates and invalid rows

* **Duplicates are charged once.** Rows with the same input are charged once, even when they are written differently (for example `linkedin.com/company/kearney` and `https://www.linkedin.com/company/kearney/about/`, or `kearney.com` and `https://www.kearney.com/`). Each duplicate still gets its own row in the results, with the same data and `credits_consumed: 0`. A LinkedIn URL and a domain for the same company are two inputs, so each is charged.
* **Invalid rows are skipped, not rejected.** A row that isn't a usable LinkedIn company URL (a person's profile, a numeric company URL, a blank value, or a company name over 200 characters) or website domain (a LinkedIn URL in the `domain` field, or a value that isn't a domain) doesn't fail the job. It costs nothing, and it comes back in its place in the results as `result: invalid_url` with a one-line `reason`. `total_invalid` in the response counts these rows.

The whole request is rejected with `422`, and nothing is charged, only when no valid row is left, the list is empty, it has more than 100,000 rows, or a single value is longer than 2,048 characters.

## Pricing and refunds

Each unique input costs `1 credit`, charged once for the whole job when you submit it. `credits_consumed` in the response is the amount charged.

Every accepted row is charged, including rows that end as `not_found` or `error`. Refunds are issued only when OrbiSearch infrastructure cannot accept the submission itself. In that case the upfront charge is reversed and no job is created.

If your account has insufficient credits for the unique inputs in the list, the request fails with `403 Forbidden`.

## Limits

* Maximum `100,000` rows per submission. Larger lists must be split across multiple jobs.
* Each `linkedin_url` and `domain` is capped at 2,048 characters.

## Rate limits

This endpoint shares the `20` requests per second per API key limit with the rest of the `/v1/*` API. Exceeding it returns a `429 Too Many Requests` response. See [errors](/docs/api-reference/errors) for how to handle rate limit responses.


## OpenAPI

````yaml POST /v1/company-enrichment/bulk
openapi: 3.1.0
info:
  title: OrbiSearch Public API
  version: 1.0.0
  description: >-
    Email verification API for developers and agents. [Get your API key
    →](https://orbisearch.com/dashboard/api-keys)


    **Rate limiting:** requests are limited per API key (20 requests per second
    by default). Every response includes `X-RateLimit-Limit`,
    `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers describing the
    current per-key window so clients can self-throttle; `429` responses also
    include a `Retry-After` header with the suggested backoff in seconds.
  contact:
    name: Get API Key
    url: https://orbisearch.com/dashboard/api-keys
servers:
  - url: https://api.orbisearch.com
    description: OrbiSearch Public API
security:
  - ApiKeyAuth: []
paths:
  /v1/company-enrichment/bulk:
    post:
      tags:
        - Public API v1
      summary: Submit Company Enrichment Bulk
      description: >-
        Submit a list of LinkedIn company URLs for asynchronous bulk enrichment.

        Duplicate companies are charged once; every input row still comes back
        in

        results, in order. Credits are deducted upfront at 1 credit per unique

        row, once for the whole job.


        Returns a `job_id` immediately. Poll

        `GET /v1/company-enrichment/bulk/{job_id}` until `status` reaches

        `completed`, then fetch results via

        `GET /v1/company-enrichment/bulk/{job_id}/results`.


        Every accepted row is charged, including not_found and error rows.

        Duplicates and invalid rows cost nothing. Refunds are issued

        only when OrbiSearch infrastructure cannot accept or process the

        submission itself (the upfront charge is reversed in that case).
      operationId: submit_company_enrichment_bulk_v1_company_enrichment_bulk_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompanyBulkSubmitRequest'
        required: true
      responses:
        '202':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompanyBulkSubmitResponse'
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 20
            X-RateLimit-Remaining:
              description: Requests remaining in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 13
            X-RateLimit-Reset:
              description: Unix timestamp (seconds) at which the current window resets.
              schema:
                type: integer
                examples:
                  - 1751700000
        '401':
          description: Invalid or missing API key
          content:
            application/json:
              example:
                detail: API key required in X-API-Key header
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '403':
          description: Insufficient credits
          content:
            application/json:
              example:
                detail: Insufficient credits. You have 0.15 credits but need 0.2.
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 20
            X-RateLimit-Remaining:
              description: Requests remaining in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 13
            X-RateLimit-Reset:
              description: Unix timestamp (seconds) at which the current window resets.
              schema:
                type: integer
                examples:
                  - 1751700000
        '422':
          description: Invalid request parameters
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                detail: >-
                  Invalid request body field '0': Input should be a valid
                  string.
                errors:
                  - loc: body.0
                    msg: >-
                      Invalid request body field '0': Input should be a valid
                      string.
                    type: string_type
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 20
            X-RateLimit-Remaining:
              description: Requests remaining in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 13
            X-RateLimit-Reset:
              description: Unix timestamp (seconds) at which the current window resets.
              schema:
                type: integer
                examples:
                  - 1751700000
        '429':
          description: Rate limit exceeded
          headers:
            Retry-After:
              description: >-
                Seconds the client should wait before retrying. Computed from
                the remaining rate-limit window (typically 1 for the per-second
                limit, longer when the limit is exceeded by 3x or more); for
                endpoints with a daily quota, seconds until the quota resets.
              schema:
                type: integer
                examples:
                  - 1
            X-RateLimit-Limit:
              description: Maximum requests allowed in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 20
            X-RateLimit-Remaining:
              description: Requests remaining in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 13
            X-RateLimit-Reset:
              description: Unix timestamp (seconds) at which the current window resets.
              schema:
                type: integer
                examples:
                  - 1751700000
          content:
            application/json:
              example:
                detail: >-
                  Rate limit exceeded. Maximum 20 requests per second per API
                  key. Contact us to discuss higher limits.
                code: rate_limited
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '503':
          description: Service temporarily unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
              example:
                detail: Bulk company enrichment is not available in this environment
          headers:
            X-RateLimit-Limit:
              description: Maximum requests allowed in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 20
            X-RateLimit-Remaining:
              description: Requests remaining in the current per-API-key window.
              schema:
                type: integer
                examples:
                  - 13
            X-RateLimit-Reset:
              description: Unix timestamp (seconds) at which the current window resets.
              schema:
                type: integer
                examples:
                  - 1751700000
      security:
        - ApiKeyAuth: []
components:
  schemas:
    CompanyBulkSubmitRequest:
      properties:
        input:
          items:
            $ref: '#/components/schemas/CompanyBulkInputRow'
          type: array
          maxItems: 100000
          minItems: 1
          title: Input
          description: >-
            Companies to enrich, one row each: a LinkedIn company/showcase URL
            (preferred) or a website domain. Repeats of the same input are
            charged once but each comes back as its own result row, in order.
            Maximum 100,000 rows per submission.
      type: object
      required:
        - input
      title: CompanyBulkSubmitRequest
      description: Submission payload for POST /v1/company-enrichment/bulk.
      example:
        input:
          - linkedin_url: https://www.linkedin.com/company/kearney
          - linkedin_url: https://www.linkedin.com/company/maple-inc
    CompanyBulkSubmitResponse:
      properties:
        job_id:
          type: string
          format: uuid
          title: Job Id
          description: >-
            Unique job identifier. Pass this to GET
            /v1/company-enrichment/bulk/{job_id} to poll status.
        status:
          type: string
          enum:
            - submitted
          const: submitted
          title: Status
          description: Submission acknowledgement status.
          examples:
            - submitted
        total_rows:
          type: integer
          title: Total Rows
          description: Number of rows submitted, duplicates and invalid rows included.
          examples:
            - 500
        total_invalid:
          type: integer
          title: Total Invalid
          description: >-
            Input rows that were skipped at submit (a numeric-ID or malformed
            URL, a name over 200 characters, a domain cell that is not a website
            domain, or a blank row), repeats included. They cost nothing and
            appear in results as invalid_url.
          examples:
            - 10
        credits_consumed:
          type: number
          title: Credits Consumed
          description: >-
            Credits deducted for this submission: 1 credit per distinct input (a
            LinkedIn URL and a domain for the same company are two inputs),
            charged once per job. Repeats of the same input and invalid rows are
            not charged.
          examples:
            - 490
      type: object
      required:
        - job_id
        - status
        - total_rows
        - total_invalid
        - credits_consumed
      title: CompanyBulkSubmitResponse
      description: Response when submitting a bulk company-enrichment job.
      example:
        job_id: 123e4567-e89b-12d3-a456-426614174000
        status: submitted
        total_rows: 500
        total_invalid: 10
        credits_consumed: 490
    ApiErrorResponse:
      properties:
        detail:
          type: string
          title: Detail
          description: Human-readable description of what went wrong.
          examples:
            - API key required in X-API-Key header
        code:
          anyOf:
            - type: string
            - type: 'null'
          title: Code
          description: >-
            Stable machine-readable error code, present on conditions a client
            may want to branch on (for example `rate_limited` for the per-second
            limit versus `daily_quota_exceeded` for the daily cap). Absent on
            errors that need no further disambiguation.
          examples:
            - daily_quota_exceeded
        errors:
          anyOf:
            - items:
                $ref: '#/components/schemas/ValidationErrorDetail'
              type: array
            - type: 'null'
          title: Errors
          description: >-
            Individual validation failures, one entry per invalid parameter or
            field. Present only on 422 responses; when the request has a single
            problem, `detail` carries the same message. Absent on all other
            error codes.
      type: object
      required:
        - detail
      title: ApiErrorResponse
      description: Error response body.
    CompanyBulkInputRow:
      properties:
        linkedin_url:
          anyOf:
            - type: string
              maxLength: 2048
            - type: 'null'
          title: Linkedin Url
          description: >-
            A LinkedIn company or showcase URL. Preferred: when a row fills both
            fields, this one is used. A malformed URL, a numeric-ID URL, a blank
            cell or a name over 200 characters is skipped (see
            result=invalid_url), not rejected.
          examples:
            - https://www.linkedin.com/company/kearney
        domain:
          anyOf:
            - type: string
              maxLength: 2048
            - type: 'null'
          title: Domain
          description: >-
            The company's website domain, or a full URL reduced to its domain.
            Used when linkedin_url is absent or blank. A value that is not a
            website domain is skipped (see result=invalid_url), not rejected.
          examples:
            - kearney.com
      type: object
      title: CompanyBulkInputRow
      description: |-
        One company submitted for bulk enrichment: its LinkedIn company URL
        (preferred) or its website domain.
      example:
        linkedin_url: https://www.linkedin.com/company/kearney
    ValidationErrorDetail:
      properties:
        loc:
          type: string
          title: Loc
          description: >-
            Where in the request the problem is, as a dot-separated path (e.g.
            `query.email`, `body.0`).
          examples:
            - query.email
        msg:
          type: string
          title: Msg
          description: Human-readable description of this validation error.
          examples:
            - 'Missing required query parameter: email.'
        type:
          type: string
          title: Type
          description: >-
            Machine-readable error category (e.g. `missing`, `less_than_equal`,
            `string_too_long`).
          examples:
            - missing
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationErrorDetail
      description: One request-validation failure.
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      description: API key for authentication
      in: header
      name: X-API-Key

````

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