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

# Crosscheck

> Resolves a company to a canonical entity, creating it if it is new, then runs the full CRM crosscheck pass on it. Returns immediately with an `id` — poll `GET /v1/crosscheck/{job_id}` until the status is `completed`. The pass covers duplicate detection, corporate hierarchy, operational status, regional-subsidiary classification, and the resulting recommended action.

Resolves a company to a canonical entity — creating it if it is new to your dataset — then runs the full CRM crosscheck pass on it in one request.

The result is split into two blocks: `crosscheck` carries the recommended action, duplicate grouping, and operational status; `parentage` carries the corporate hierarchy (immediate, ultimate, and top operating parent, plus regional-subsidiary classification) in the same shape as [`GET /v1/combined/{job_id}`](/api-reference/endpoint/get-combined#with-parentage).

The endpoint accepts the same inputs as [`POST /v1/entity-resolution`](/api-reference/endpoint/create-entity-resolution), except that `external_id` is required. It identifies the record in your CRM, which the pass needs because duplicates and hierarchy are evaluated relative to the rest of your dataset.

<Note>
  This is an async operation. Poll [`GET /v1/crosscheck/{job_id}`](/api-reference/endpoint/get-crosscheck) until `status` is `completed`, or provide a `webhook_url` to receive a callback.
</Note>

<Note>
  Crosscheck results are never cached. Each call re-runs the pass, because duplicates, hierarchy, and the recommended action change as your dataset changes.
</Note>

## Credit usage

| Outcome                                      | Cost      |
| -------------------------------------------- | --------- |
| Entity resolved and crosschecked             | 5 credits |
| Entity resolved, crosscheck pass did not run | 1 credit  |

The pass does not run when no entity is resolved, or when the `external_id` does not match an account in your Kernel dataset. In those cases the job still completes, `crosscheck` and `parentage` are both returned as `null`, and the crosscheck portion of the cost is refunded automatically.

## Examples

### Crosscheck a CRM record

```bash curl theme={null}
curl -X POST https://api.kernel.ai/rest/v1/crosscheck \
  -H "x-api-key: $KERNEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_id": "0014x00001LMZCDAA5", "legal_name": "Stripe, Inc.", "website": "stripe.com"}'
```

### Crosscheck and match LinkedIn

```bash curl theme={null}
curl -X POST https://api.kernel.ai/rest/v1/crosscheck \
  -H "x-api-key: $KERNEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_id": "0014x00001LMZCDAA5", "website": "stripe.com", "match_to_linkedin": true}'
```

Both requests return the same immediate response:

```json Response (202) theme={null}
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "processing"
}
```

## Request body

`external_id` is required — it selects which account in your dataset the crosscheck pass runs on. You must also provide at least one of `legal_name`, `trading_name`, `website`, or `kernel_id` so the entity can be resolved. Requests missing either are rejected with a `400`.

| Field                         | Type      | Required | Description                                                                                                                         |
| ----------------------------- | --------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `external_id`                 | `string`  | Yes      | Your CRM identifier for the record to clean. Echoed back on `record.external_id`.                                                   |
| `legal_name`                  | `string`  | No\*     | Registered legal name                                                                                                               |
| `trading_name`                | `string`  | No\*     | Brand or trading name                                                                                                               |
| `website`                     | `string`  | No\*     | Company website URL                                                                                                                 |
| `kernel_id`                   | `string`  | No\*     | Resolve against a known Kernel entity                                                                                               |
| `country`                     | `string`  | No       | Country name or ISO 3166-1 alpha-2 code                                                                                             |
| `city`                        | `string`  | No       | City                                                                                                                                |
| `state`                       | `string`  | No       | State or province                                                                                                                   |
| `postal_code`                 | `string`  | No       | ZIP or postal code                                                                                                                  |
| `address`                     | `string`  | No       | Street address                                                                                                                      |
| `email`                       | `string`  | No       | Email address. Only the domain portion is used for matching.                                                                        |
| `phone`                       | `string`  | No       | Contact phone                                                                                                                       |
| `company_registration_number` | `string`  | No       | Company registration number                                                                                                         |
| `match_to_linkedin`           | `boolean` | No       | When `true`, also match the resolved entity to a LinkedIn company profile. Result appears in `record.linkedin`. Defaults to `false` |
| `identity_bias`               | `string`  | No       | Bias the resolver toward name or URL matching when they conflict. One of `NAME_BIAS`, `URL_BIAS`. Defaults to `URL_BIAS`            |
| `webhook_url`                 | `string`  | No       | HTTPS URL to receive callbacks when the job completes or fails                                                                      |

\*At least one of `legal_name`, `trading_name`, `website`, or `kernel_id` is required.

## Polling for results

After receiving an `id`, poll [`GET /v1/crosscheck/{job_id}`](/api-reference/endpoint/get-crosscheck) with exponential backoff. A full crosscheck runs identity resolution and the complete crosscheck pass, so it typically takes longer than the single-purpose endpoints.

## Related endpoints

* [`GET /v1/crosscheck/{job_id}`](/api-reference/endpoint/get-crosscheck) — Poll for results
* [`POST /v1/entity-resolution`](/api-reference/endpoint/create-entity-resolution) — Resolve an entity only
* [`POST /v1/combined`](/api-reference/endpoint/combined) — Resolve an entity and enrich firmographics or parentage
* [`POST /v1/resolve-parent`](/api-reference/endpoint/resolve-parent) — Resolve parentage for an already-resolved entity


## OpenAPI

````yaml POST /v1/crosscheck
openapi: 3.1.0
info:
  title: Kernel API
  description: Resolve company identities to canonical entities with a simple async API
  version: 1.0.0
  contact:
    email: support@kernel.ai
  license:
    name: MIT
servers:
  - url: https://api.kernel.ai/rest
    description: Production
security:
  - apiKeyAuth: []
tags:
  - name: Entity Resolution
    description: Resolve a company to a canonical entity
  - name: Firmographics
    description: Retrieve and enrich firmographic data for resolved entities
  - name: Parentage
    description: Look up parent and top-parent entities in a corporate hierarchy
  - name: Combined
    description: Resolve an entity and run a follow-up enrichment in one call
  - name: Crosscheck
    description: Resolve an entity and run the full CRM crosscheck pass in one call
  - name: LinkedIn Lookup
    description: Provisional LinkedIn company match jobs (not Kernel-verified)
paths:
  /v1/crosscheck:
    post:
      tags:
        - Crosscheck
      summary: Crosscheck
      description: >-
        Resolves a company to a canonical entity, creating it if it is new, then
        runs the full CRM crosscheck pass on it. Returns immediately with an
        `id` — poll `GET /v1/crosscheck/{job_id}` until the status is
        `completed`. The pass covers duplicate detection, corporate hierarchy,
        operational status, regional-subsidiary classification, and the
        resulting recommended action.
      operationId: crosscheck
      requestBody:
        description: >-
          Company to resolve and crosscheck. `external_id` identifies the record
          in your CRM and is required.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CrosscheckRequest'
            examples:
              by_external_id:
                summary: Crosscheck a CRM record
                value:
                  external_id: 0014x00001LMZCDAA5
                  legal_name: Stripe, Inc.
                  website: stripe.com
              with_linkedin:
                summary: Crosscheck and match LinkedIn
                value:
                  external_id: 0014x00001LMZCDAA5
                  website: stripe.com
                  match_to_linkedin: true
        required: true
      responses:
        '202':
          description: Job created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/JobCreatedResponse'
              example:
                id: a1b2c3d4-e5f6-7890-abcd-ef1234567890
                status: processing
        '400':
          description: >-
            Invalid request — malformed JSON, missing `external_id`, or no
            identifying field provided
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: >-
                  At least one of legal_name, trading_name, website, or
                  kernel_id is required
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Rate limit exceeded. Retry after 60 seconds.
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: Internal server error
components:
  schemas:
    CrosscheckRequest:
      allOf:
        - $ref: '#/components/schemas/EntityResolutionRequest'
        - type: object
          required:
            - external_id
          properties:
            external_id:
              description: >-
                Your CRM identifier for the record to crosscheck. Required — it
                selects which account in your dataset the crosscheck pass runs
                on.
              type: string
              minLength: 1
              example: 0014x00001LMZCDAA5
    JobCreatedResponse:
      required:
        - id
        - status
      type: object
      properties:
        id:
          description: Unique identifier for the created job.
          type: string
          example: 550e8400-e29b-41d4-a716-446655440000
        status:
          description: Initial status of the job.
          type: string
          enum:
            - processing
    Error:
      required:
        - error
      type: object
      properties:
        error:
          description: Error description.
          type: string
          example: Entity not found
    EntityResolutionRequest:
      type: object
      properties:
        legal_name:
          description: Registered legal name of the company (e.g. "Stripe, Inc.")
          type: string
          minLength: 1
          example: Stripe, Inc.
        trading_name:
          description: Primary brand or trading name (e.g. "Stripe")
          type: string
          minLength: 1
          example: Stripe
        website:
          description: Company website URL.
          type: string
          minLength: 1
          example: https://stripe.com
        country:
          description: Country name or ISO 3166-1 alpha-2 code.
          type: string
          minLength: 1
          example: US
        city:
          description: City.
          type: string
          minLength: 1
          example: South San Francisco
        state:
          description: State or province.
          type: string
          minLength: 1
          example: CA
        postal_code:
          description: ZIP or postal code.
          type: string
          minLength: 1
          example: '94070'
        address:
          description: Street address.
          type: string
          minLength: 1
          example: 354 Oyster Point Blvd
        email:
          description: Email address. Only the domain portion is used for matching.
          type: string
          minLength: 1
          example: info@stripe.com
        phone:
          description: Phone number. Used as an additional signal for entity resolution.
          type: string
          minLength: 1
          example: +1 555-555-5555
        external_id:
          description: Your own identifier for this record.
          type: string
          minLength: 1
          example: stripe-001
        company_registration_number:
          description: >-
            Primary incorporation/registration number. The same number can exist
            in more than one country — pair it with company_registration_country
            when known.
          type: string
          minLength: 1
          example: '01234567'
        company_registration_country:
          description: >-
            Registry jurisdiction for company_registration_number (ISO 3166-1
            alpha-2 preferred). England, Scotland, Wales, and Northern Ireland
            map to GB. Falls back to country when omitted.
          type: string
          minLength: 1
          example: GB
        kernel_id:
          description: >-
            An existing Kernel ID. When provided, the resolver skips matching
            and returns the canonical record for this entity.
          type: string
          minLength: 1
          example: '6347422643'
        linkedin_url:
          description: >-
            LinkedIn URL for the company (e.g.
            "https://linkedin.com/company/stripe"). Used as an additional signal
            for entity resolution.
          type: string
          minLength: 1
          example: https://linkedin.com/company/stripe
        match_to_linkedin:
          description: >-
            When `true`, Kernel will attempt to match the resolved entity to a
            LinkedIn company profile. The result is returned in the `linkedin`
            field of the completed record. Defaults to `false`.
          type: boolean
          default: false
          example: true
        identity_bias:
          description: >-
            Bias the resolver toward name or URL matching when they conflict.
            One of: `NAME_BIAS`, `URL_BIAS`. Defaults to `URL_BIAS`.
          type: string
          enum:
            - NAME_BIAS
            - URL_BIAS
        webhook_url:
          description: >-
            HTTPS URL to receive webhook callbacks when the job completes or
            fails. Kernel will POST the job result to this URL with an
            X-Kernel-Signature header for verification.
          type: string
          format: uri
          pattern: ^https://
          example: https://example.com/webhooks/kernel
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: Include your API key in the x-api-key header.

````