> ## 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.

# Alignment

> Links one CRM record to a Kernel entity, runs the full cleaning pass against the rest of your dataset, and returns entity resolution, firmographics, parentage and the alignment outcome. A record that already has a Kernel ID keeps it unless `settings.rematch_entity` is set. Returns immediately with an `id`; poll `GET /v1/alignment/{job_id}` until `status` is `completed`. Tracked-usage customers only; costs no credits.

Links one CRM record to a Kernel entity, runs the full cleaning pass against the rest of your dataset, and returns entity resolution, firmographics, parentage and the alignment outcome: a recommended action and the duplicate group.

Built for repeat calls. A record that already has a Kernel ID keeps it unless you set `settings.rematch_entity`, so duplicate groups and recommended actions stay stable across refreshes.

> [!NOTE]
>
> This is an async operation. Poll [`GET /v1/alignment/{job_id}`](https://dev.kernel.ai/api-reference/endpoint/get-alignment) until `status` is `completed`, or provide a `webhook_url` to receive a callback.

> [!NOTE]
>
> Available to tracked-usage customers at no credit cost. A new `external_id` consumes tracked-account capacity. Accounts without an active contract fail with `error_type: "not_enabled"`.

## Examples

### Align a CRM record for the first time

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

### Re-align a known record, keeping its Kernel ID

```bash curl theme={null}
curl -X POST https://api.kernel.ai/rest/v1/alignment \
  -H "x-api-key: $KERNEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_id": "stripe-001"}'
```

### Rematch the entity because the source data changed

```bash curl theme={null}
curl -X POST https://api.kernel.ai/rest/v1/alignment \
  -H "x-api-key: $KERNEL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"external_id": "stripe-001", "legal_name": "Stripe Payments Europe, Limited", "country": "IE", "settings": {"rematch_entity": true}}'
```

All 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. The first time Kernel sees an `external_id` it also needs `legal_name`, `trading_name` or `website`; otherwise the job fails with `error_type: "identity_inputs_missing"`. Later calls may send `external_id` alone.

| Field | Type | Required | Description |
| - | - | - | - |
| `external_id` | `string` | Yes | Your CRM identifier. 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 |
| `linkedin_url` | `string` | No | LinkedIn URL for the company |
| `country` | `string` | No | Country name or ISO 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 | Contact email |
| `phone` | `string` | No | Contact phone |
| `company_registration_number` | `string` | No | Company registration number. Used to resolve the entity; the response returns the stored registration, not this value. |
| `company_registration_country` | `string` | No | Registry jurisdiction for `company_registration_number` |
| `settings.rematch_entity` | `boolean` | No | Re-run identity resolution and move the link if it picks a different entity. Can change the Kernel ID, duplicate group, parent chain and recommended action. Defaults to `false` |
| `settings.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` |
| `settings.match_to_linkedin` | `boolean` | No | Also match the company's LinkedIn profile. Defaults to `false` |
| `settings.force_refresh` | `boolean` | No | Re-research firmographics and parentage instead of using Kernel's cache. Defaults to `false` |
| `webhook_url` | `string` | No | HTTPS URL for completion/failure callbacks |

## Sending the same record again

Fields you send are merged into the stored record: present fields overwrite, absent fields are kept.

* **Different input, default settings.** The Kernel ID is kept. The record is re-cleaned on the merged data, so its duplicate group or recommended action can change. `alignment.drifted_identity_inputs` lists the identity fields that have moved since the Kernel ID was resolved.
* **Identical payload.** Nothing is written. The record is still re-cleaned against your current dataset, reusing cached research unless `force_refresh` is set.
* **Two jobs for the same `external_id` at once.** The second fails with `error_type: "alignment_in_progress"`.

## Related endpoints

* [`GET /v1/alignment/{job_id}`](https://dev.kernel.ai/api-reference/endpoint/get-alignment) — Poll for results
* [`POST /v1/combined`](https://dev.kernel.ai/api-reference/endpoint/combined) — Resolve an entity and enrich firmographics or parentage, without cleaning


## OpenAPI

````yaml POST /v1/alignment
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: Alignment
    description: >-
      Link a CRM record to a Kernel entity and run the full cleaning pass in one
      call
  - name: LinkedIn Lookup
    description: Provisional LinkedIn company match jobs (not Kernel-verified)
  - name: Data feedback
    description: Open and manage data feedback tickets for CRM accounts
paths:
  /v1/alignment:
    post:
      tags:
        - Alignment
      summary: Alignment
      description: >-
        Links one CRM record to a Kernel entity, runs the full cleaning pass
        against the rest of your dataset, and returns entity resolution,
        firmographics, parentage and the alignment outcome. A record that
        already has a Kernel ID keeps it unless `settings.rematch_entity` is
        set. Returns immediately with an `id`; poll `GET /v1/alignment/{job_id}`
        until `status` is `completed`. Tracked-usage customers only; costs no
        credits.
      operationId: alignment
      requestBody:
        description: >-
          Record to align. `external_id` identifies it in your CRM and is
          required.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AlignmentRequest'
            examples:
              first_align:
                summary: Align a CRM record for the first time
                value:
                  external_id: stripe-001
                  legal_name: Stripe, Inc.
                  website: stripe.com
                  country: US
              re_align:
                summary: Re-align a known record, keeping its Kernel ID
                value:
                  external_id: stripe-001
              rematch:
                summary: Rematch the entity because the source data changed
                value:
                  external_id: stripe-001
                  legal_name: Stripe Payments Europe, Limited
                  country: IE
                  settings:
                    rematch_entity: 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 or missing `external_id`
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: external_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:
    AlignmentRequest:
      description: >-
        The record to align. `external_id` is required; the first time Kernel
        sees it, at least one of `legal_name`, `trading_name` or `website` is
        required too. Identity options live under `settings`.
      type: object
      required:
        - external_id
      properties:
        external_id:
          description: >-
            Your CRM identifier for the record to align. Echoed back on
            `record.external_id`.
          type: string
          minLength: 1
          example: stripe-001
        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
        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. Used to resolve the entity; the response returns the
            stored registration, not this value.
          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
        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
        settings:
          $ref: '#/components/schemas/AlignmentSettings'
        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
    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
    AlignmentSettings:
      type: object
      properties:
        rematch_entity:
          description: >-
            Re-run identity resolution and move the link if it picks a different
            entity. Can change the Kernel ID, duplicate group, parent chain and
            recommended action. Records that are not linked yet always resolve.
          type: boolean
          default: false
        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
        match_to_linkedin:
          description: >-
            Also match the company's LinkedIn profile. Result appears in
            `record.linkedin`.
          type: boolean
          default: false
        force_refresh:
          description: >-
            Re-research firmographics and parentage instead of using Kernel's
            cache.
          type: boolean
          default: false
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: Include your API key in the x-api-key header.

````

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