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

# Changelog

> Product updates and announcements for the Crustdata API.

<Update label="July 2026" description="Technographics: company technology stack" tags={["Feature"]}>
  ## Technographics: filter by and enrich a company's technology stack

  Crustdata now exposes the technologies detected for a company across
  [Company Enrich](/company-docs/enrichment/introduction),
  [Company Search](/company-docs/search/introduction), and
  [Company Autocomplete](/company-docs/autocomplete/introduction).

  * **`technographics` field group on Enrich** — request it explicitly via
    `fields` (it is never included by default) to get `total_technologies`,
    `top_technologies`, the full `technologies` list (each entry with `name`,
    `category`, and detection `sources`), and `updated_at`. See the
    [field reference](/company-docs/enrichment/reference#technographics-fields).
  * **Search filters** — filter on `technographics.total_technologies` (also
    sortable), `technographics.top_technologies`,
    `technographics.technologies.name`, and
    `technographics.technologies.category`. Technographics values are not
    returned in search responses — filter, then enrich. See
    [searchable fields](/company-docs/search/reference#technographics-filter-only).
  * **Autocomplete** — two new company-scope fields: `technology` (technology
    names) and `technology_category` (category values) for discovering valid
    filter values.
  * **Access and pricing** — `technographics` requires field-level permission on
    your account. It is a billed add-on: **+2 credits** per company that returns
    technographics data, on top of the base enrich cost; companies with no
    technographics data are not charged the add-on. The same add-on applies to
    [Batch Company Enrich](/company-docs/enrichment/batch).

  Available on `POST /company/enrich`, `POST /batch/company/enrich`,
  `POST /company/search`, and `POST /company/search/autocomplete` with
  `x-api-version: 2025-11-01`.
</Update>

<Update label="June 2026" description="Accurate company lookup by domain" tags={["Improvement"]}>
  ## Company lookup: more accurate domain matching for large organizations

  We improved domain matching in [Company Identify](/company-docs/identify/introduction)
  and [Company Enrich](/company-docs/enrichment/introduction), especially for large
  organizations and companies with subsidiaries. On these domains a lookup could
  sometimes surface a related record (a subsidiary, a regional arm, an acquired
  company, or a showcase page) instead of the parent company. Matching now favors
  the primary company, automatically.

  * **Better matches for large organizations** - a domain maps to the parent
    company rather than a subsidiary, an acquired company, or a showcase page. For
    example, `amazon.com` resolves to Amazon, `paypal.com` to PayPal, and
    `schwab.com` to Charles Schwab.
  * **Nothing to change** - same endpoints, same request shape, and same response
    shape. No new fields and no confidence score to handle; matches just get better
    automatically.
  * **Biggest gains on high-volume domains** - in testing across Fortune 500 US
    companies, top-1 accuracy by domain rose from 88% to 94%.

  No extra cost: [Company Identify](/company-docs/identify/introduction) stays free
  and [Company Enrich](/company-docs/enrichment/introduction) credits are unchanged.
  Available on `POST /company/identify` and `POST /company/enrich` with
  `x-api-version: 2025-11-01`. No changes to the legacy identity endpoints.
</Update>

<Update label="June 2026" description="Natural-language Person Search query (beta)" tags={["Feature"]}>
  ## Person Search: natural-language `search.query` (beta)

  [Person Search](/person-docs/search/introduction) adds `search.query`, a
  natural-language query that returns a ranked list of people instead of requiring
  you to hand-build every filter. Crustdata pulls the hard constraints out of the
  query and applies them as exact filters, semantically matches the rest against
  the full profile, and orders results by fit.

  * **`search.query`** - describe who you want in plain language; results are
    ranked by profile context (title, skills, company history, education,
    location, summary).
  * **`search.mode`** - `hybrid` (default, blends keyword and concept matching)
    and `semantic` (concepts). For exact keyword matching, see the keyword search
    changelog below.
  * **`mode`** - two recall modes: `managed` (default; the query may add
    constraints) and `exact` (your filters are hard constraints and the query only
    ranks within them).
  * **`fit`** - each profile returns a relevance tier (`strong` / `possible` /
    `weak`) alongside `total_count_relation`, so you can keep only high-confidence
    matches.
  * **Not included** - sorts; semantic results come back already rank-ordered by
    relevance.
  * **Pricing** - Person Search parity at **0.03 credits per result**, no premium
    for semantic ranking, and the same **30 requests/minute** rate limit.

  [Semantic Search Guide →](/guides/person-semantic-search)
</Update>

<Update label="June 2026" description="Keyword search with Boolean operators" tags={["Feature"]}>
  ## Person Search: keyword search with Boolean operators

  [Person Search](/person-docs/search/introduction) now lets you search for
  keywords across the full profile. Set `search.mode: "lexical"` to match on
  keywords, so exact terms, acronyms, names, and IDs are found wherever they
  appear in the profile (title, skills, company history, education, location,
  summary).

  * **`search.mode: "lexical"`** - keyword matching across the whole profile, for
    when you want exact terms to be found rather than concept ranking.
  * **`search.query_syntax: "boolean"`** - read the query as a Boolean expression
    instead of plain text: a space means **AND** (every term required), `|` means
    **OR**, and you can combine terms for precise keyword search. Honored only with
    `search.mode: "lexical"` and top-level `mode: "exact"`.

  [Boolean keyword operators →](/guides/person-semantic-search#boolean-keyword-operators)
</Update>

<Update label="June 2026" description="Multiple named API keys per account" tags={["Feature"]}>
  ## Multiple API keys on one account

  Every Crustdata account used to have a single API key. You can now create and
  manage several named keys on one account, so you can keep dev and prod apart,
  give each project or teammate its own key, and switch off a key without affecting
  the others. Works across the API and MCP. Every existing key was migrated
  automatically and named **Default**.

  * **Create and name keys** - add as many keys as you need at
    [app.crustdata.com/api-keys](https://app.crustdata.com/api-keys), rename them
    anytime, and copy the generated `cd_` key into any API or MCP request. See
    [Authentication](/general/introduction).
  * **Per-key status** - `ACTIVE` (usable across the API and MCP), `INACTIVE`
    (blocked instantly and reversible), and `DELETED` (permanently retired; the
    account's other keys keep working).
  * **Shared credits and rate limit** - all keys on an account draw from one
    credit pool and one rate-limit bucket today, so keys separate and organize work
    rather than cap spend or speed per key.
  * **Coming next** - credit balance and limits set at the individual API-key
    level.

  Available to all users on all plans, at no extra cost, across the API and MCP.
  Manage keys at [app.crustdata.com/api-keys](https://app.crustdata.com/api-keys).
</Update>

<Update label="June 2026" description="Person Contact Enrich endpoint" tags={["Feature"]}>
  ## Person Contact Enrich: business emails, personal emails, and phone numbers

  [Person Contact Enrich](/person-docs/contact/enrich) is a new
  endpoint that returns contact data for up to **25 people** in a single request.
  Supply `professional_network_profile_urls` or `business_emails` as input and
  get business emails, personal emails, and phone numbers back in the same
  response — no polling.

  * **Identifiers** — pass exactly one of `professional_network_profile_urls`
    (a profile URL) or `business_emails` to reverse-look-up
    a person, up to 25 values per request.
  * **`fields`** — select which contact data to return:
    `contact.business_emails`, `contact.personal_emails`, `contact.phone_numbers`,
    and `contact.websites` (or `contact` for all). Each email entry includes its
    deliverability `status`. See the
    [contact fields reference](/person-docs/contact/enrich#contact-fields).
  * **Response** — the same record shape as `/person/enrich`, restricted to the
    `person_data.contact` object. For higher fill rate on bulk lists, use the
    async [Batch Contact Enrich](/person-docs/contact/batch) job instead.

  Available on `POST /person/contact/enrich` with `x-api-version: 2025-11-01`.
</Update>

<Update label="June 2026" description="Person Search geo exclusion" tags={["Feature"]}>
  ## Person Search: `geo_exclude` filter operator

  [Person Search](/person-docs/search/introduction) adds a `geo_exclude` filter
  operator — the inverse of `geo_distance`. It excludes profiles **inside** a
  radius and keeps everyone else, so you can carve out a metro you already cover
  or target candidates outside a region.

  * **`geo_exclude`** takes the same value object as `geo_distance`: a centre
    given as `location` (geocoded server-side) or `lat_lng` (`[lat, lng]`, skips
    geocoding), a required `distance`, and an optional `unit` (`km`, `mi`,
    `miles`, `m`, `meters`, `ft`, `feet`; defaults to `km`). When both `location`
    and `lat_lng` are supplied, `lat_lng` wins. See the
    [operator reference](/person-docs/search/reference#geo_exclude--exclude-a-radius)
    and a [worked example](/person-docs/search/introduction#exclude-a-geographic-radius).

  Available on `POST /person/search` with `x-api-version: 2025-11-01`.
</Update>

<Update label="May 2026" description="Profile name and title fields" tags={["Feature"]}>
  ## Professional-network name and normalized title on Person profiles

  [Person Search](/person-docs/search/introduction) and
  [Person Enrich](/person-docs/enrichment/introduction) now return additional
  `basic_profile` identity fields.

  * **`basic_profile.professional_network_name`** — the display name on the
    person's professional-network profile, returned by both `/person/search` and
    `/person/enrich`. On search it is also a filterable field (not sortable). See
    the [search field reference](/person-docs/search/reference#searchable-fields)
    and the [enrich response reference](/person-docs/enrichment/reference#person_data-sections).
  * **`basic_profile.normalized_title`** — the normalized job-title object
    (`matched_title`, `department`, `sub_department`, `similarity`, `confident`)
    is now also returned by `/person/enrich`, matching the field already available
    on `/person/search`.

  Available on `POST /person/search` and `POST /person/enrich` with
  `x-api-version: 2025-11-01`.
</Update>

<Update label="May 2026" description="Richer Person Search profiles" tags={["Feature"]}>
  ## Normalized titles, education details, and logos on Person Search

  [Person Search](/person-docs/search/introduction) results now include a
  normalized job-title classification, richer education entries, and stable
  Crustdata-hosted logo permalinks for employers and schools.

  * **`basic_profile.normalized_title`** — an object with `matched_title`,
    `department`, `sub_department`, `similarity`, and `confident`. Filter on
    `basic_profile.normalized_title.matched_title`, `.department`, or
    `.sub_department` (filterable, not sortable). See the
    [field reference](/person-docs/search/reference#basic-profile).
  * **Education location and description** — each `education.schools[]` entry now
    returns a `location` object (`raw`, `city`, `state`, `country`, `continent`)
    and a `description`. The location sub-fields are filterable via
    `education.schools.location.*`. See the
    [education fields](/person-docs/search/reference#education).
  * **`education.schools[].institute_logo_permalink`** — a stable Crustdata-hosted
    school logo URL, returned for display.
  * **`experience.employment_details[].company_profile_picture_permalink`** — a
    stable Crustdata-hosted employer logo URL, so you can render company logos
    without resolving image URLs yourself. See the
    [profile-card example](/person-docs/search/introduction#build-a-profile-card-with-company-and-school-logos).

  Available on `POST /person/search` with `x-api-version: 2025-11-01`.
</Update>

<Update label="May 2026" description="Follower count on Person Search" tags={["Feature"]}>
  ## Follower count on Person Search profiles

  [Person Search](/person-docs/search/introduction) now exposes a `followers`
  field on each result's `professional_network` block, alongside the existing
  `connections` field.

  * **`professional_network.followers`** — integer follower count from the
    profile. Filterable and sortable: pass it in `filters.conditions[].field`
    or `sorts[].field`. See the
    [filter and sort field reference](/person-docs/search/reference).

  Available on `POST /person/search` with `x-api-version: 2025-11-01`.
</Update>

<Update label="May 2026" description="Person Search filters" tags={["Feature"]}>
  ## Person Search: new filter operators

  [Person Search](/person-docs/search/introduction) gains two new filter
  options for the `2025-11-01` API:

  * **`(!)` — fuzzy negation.** Excludes profiles whose value contains the
    given substring (case-insensitive). Multi-word values are matched as a
    literal phrase, so `(!) "New York"` excludes profiles literally
    containing `"New York"` but **not** `"New Yorker"`. To exclude on each
    word independently, send separate `(!)` conditions inside an `and`
    group. See the [operator reference](/person-docs/search/reference#-fuzzy-negation)
    and a [worked example](/person-docs/search/introduction#exclude-profiles-matching-a-substring).
  * **`geo_distance` accepts `lat_lng`.** Supply explicit coordinates as
    `[lat, lng]` to skip geocoding. When both `location` and `lat_lng` are
    provided, `lat_lng` wins. See the
    [`geo_distance` reference](/person-docs/search/reference#geo_distance--radius-around-a-point)
    and the [`lat_lng` example](/person-docs/search/introduction#search-by-explicit-coordinates).

  Both operators are available only on `POST /person/search` with
  `x-api-version: 2025-11-01`.
</Update>

<Update label="May 2026" description="API version 2025-11-01" tags={["Feature"]}>
  ## 🚀 New API version: `2025-11-01`

  We are launching a new, versioned API that replaces the legacy
  `/screener` and `/data_lab` endpoints. Every product — Company, Person,
  Job, Web, and Social Post — now lives under a consistent, purpose-built
  surface area.

  ### What's new

  * **Versioned endpoints.** Every call requires the
    `x-api-version: 2025-11-01` header, so future changes ship without
    breaking existing integrations.
  * **Bearer authentication.** `Authorization: Bearer <key>` replaces the
    legacy `Token` scheme across every endpoint.
  * **Structured error envelope.** A consistent `{ error: { type, message, metadata } }`
    shape across every endpoint.
  * **Cursor-based pagination.** Opaque `next_cursor` replaces numeric
    `offset` on search endpoints.
  * **Match-result envelope for enrich.** Enrich responses now return
    `matches[]` with a `confidence_score` per match.
  * **Nested, neutral response sections.** Flat top-level keys are grouped
    under sections like `basic_info`, `employee_reviews`, and `funding`.

  ### Migrating from the legacy API

  Every legacy `/screener` and `/data_lab` endpoint has a current
  replacement. The [Migration guides](/migrations/overview) map each
  legacy endpoint to its new equivalent and walk through request keys,
  field renames, type changes, and response-shape differences.
</Update>
