Skip to main content
Feature
Account credits per-top-up breakdown

GET /account/credits: per-top-up breakdown with credit_topups

Account credits responses now include a credit_topups array for accounts with live top-ups — one entry per top-up still holding credits, sorted soonest expiry first:
  • type: how the top-up entered your account — purchase (one-time purchase), auto_topup (automatic reload), or granted (added by Crustdata).
  • granted_credits / remaining_credits: what the top-up originally added and what’s still unspent.
  • granted_at / expires_at: when it was added and when its unspent credits expire (expires_at is null for top-ups without an expiry).
The key is absent for accounts without live top-ups, so existing responses are unchanged. Like wallets, the list is informational — keep gating spending decisions on account.credits. Available on GET /account/credits with x-api-version: 2025-11-01.
Feature
Company Search office-locations filter

Company Search: filter by any office location with locations.all_office_addresses

Company Search now accepts locations.all_office_addresses as a filter field, so you can match companies on any of their offices, not only the headquarters that the other locations.* filters target. The field was already returned in responses; it is now filterable too.
  • Substring match: office addresses are free-text strings (e.g. "HITEC City, Madhapur, Hyderabad, Telangana, 500081, IN"), so filter with a city or region substring using (.) / contains.
  • Combines with HQ filters: pair it with locations.country in an and group to express queries like headquartered in the USA with an office in Hyderabad: locations.country = "USA" and locations.all_office_addresses (.) "Hyderabad".
  • Not sortable: the field is filterable and returned, but not valid in sorts. See Locations in the search reference.
Available on POST /company/search with x-api-version: 2025-11-01.
Feature
Person Search null-check operators
Person Search now accepts the is_null and is_not_null filter operators, so you can match on field presence directly instead of fetching fields and checking for null in your own code.
  • is_null — matches profiles where the field has no value. On nested-array fields the check is element-based: an empty experience.employment_details.current array matches experience.employment_details.current.name is_null.
  • is_not_null — matches profiles where at least one non-null value is present for the field.
  • value is required — send a literal "value": null; omitting the value key returns 400.
Combine the two to find people who left a job and have not started a new one: experience.employment_details.current.name is_null and experience.employment_details.past.name is_not_null in one and group. See null checks for details.Available on POST /person/search with x-api-version: 2025-11-01. Company Search and Job Search already accept both operators.
Feature
X-Credits-Used response header

Every API response now reports what it cost: the X-Credits-Used header

Every response from the data APIs — search, enrich, identify, autocomplete, web, and batch — now carries an X-Credits-Used header with the exact decimal credits that request deducted, read from the same ledger that bills you. Log it per call to attribute spend by customer, agent, or workflow, sum it to keep an automation inside a budget, or reconcile it against invoices — without polling the balance endpoint.
  • Exact decimal0.03 for a one-result person search, 3 for a three-company enrich. Fractional costs report exactly.
  • Present on error responses too — errors report 0, so the header is there on every call you log.
  • 0 is meaningful — endpoints that consume no credits report 0, and so do asynchronous submissions (batch jobs and background-job searches), which are billed when the job runs rather than at submit time.
  • Readable from browsers — the header is exposed cross-origin, so dashboard-style apps can read it from JavaScript.
  • Declared in the specs — every response in the OpenAPI specs documents the header.
Responses generated before a request reaches the API, such as rate-limit 429s, carry no header. See Per-call usage on the Credits page for details and examples.Available on every data API endpoint.
Feature
Job Search company job-board postings

Job Search: company job-board postings, job_details.source, and job_details.employment_type

Job Search now includes postings published directly on company job boards — about 3 million postings joining the roughly 45 million existing listings. Two new job_details fields expose this:
  • job_details.source — the platform each posting comes from. Present on every job: professional_network for the existing listings, or one of the job-board platforms — workday, smartrecruiters, greenhouse, workable, lever, icims, ashby, rippling, yc. Filterable (=, in, …) and groupable via group_by; not sortable. See the Job details catalog.
  • job_details.employment_type — the employment type declared by the posting: full_time, part_time, contract, intern, or temporary. Currently populated for roughly 85% of job-board postings and null for now when source is professional_network. Filterable and groupable; not sortable.
  • Search-only — both fields are returned by POST /job/search only; Live Search does not include them.
Available on POST /job/search with x-api-version: 2025-11-01.
Feature
Company Search geographic radius filters

Company Search: geo_distance and geo_exclude on company headquarters

Company Search now filters companies by true geographic radius around their headquarters. Pick a point — either a place name like “Palo Alto, CA” or a pair of coordinates — and set a distance. geo_distance then returns every company whose headquarters falls within that distance of the point, instead of matching on location text and listing city names one at a time.
  • geo_distance — returns companies headquartered inside the radius.
  • geo_exclude — the inverse of geo_distance. It returns companies headquartered outside the radius and excludes the ones inside it, so you can skip a region you already cover. See the geographic radius filters reference.
  • Setting the point and the distance — the point is what the radius is measured from. Pass it as location (a place name, geocoded server-side) or as lat_lng ([lat, lng], which skips geocoding), then add a distance and a unit such as km or mi.
  • One field path — apply both operators to locations.headquarters, which targets the company’s geocoded headquarters point.
  • Normalized location facetslocations.state and locations.city are newly filterable and match normalized values derived from geocoding the headquarters address, with search responses returning the same normalized values. locations.country accepts both ISO-3 codes ("USA") and full country names ("United States") — either form matches the same companies, so existing filters keep working — and responses return the normalized full country name. See Locations.
Available on POST /company/search with x-api-version: 2025-11-01.
Feature
Auto top-up for credits

Auto top-up: refill credits automatically before the balance runs out

Save a card once, set a threshold and a reload amount, and Crustdata tops your balance up on its own. The balance is checked every time credits are spent, and the moment it drops below your threshold the saved card is charged for the reload package and the credits land immediately — instead of buying credits by hand each time the balance runs down. The feature is free on every plan and stays off until you turn it on.
  • Turn it on from the Credits page — save a card through a Stripe-hosted page and accept the auto-charge consent, then set two numbers: a threshold and a reload amount. Enabling requires a balance above the threshold you pick, so buy credits manually once if you are already below it. Turning it off is one click, any time.
  • What a top-up does — the saved card is charged at the price shown during setup, the live balance refreshes right away, and you get a receipt email plus a real Stripe invoice in the Invoices tab, identical to a manual purchase.
  • Monthly recharge limit — an optional cap on how many credits auto top-up can add per calendar month. It resets each calendar month.
  • Safety rails — at most 3 auto top-ups per day per account, and double-charge protection means one threshold breach can only ever produce one charge.
  • Failed charges — a declined or expired card gets an email with the reason and the fix, Crustdata retries after a cooldown, and after 3 consecutive failures auto top-up disables itself and says so. Cards nearing expiry get a warning email before they lapse.
  • Thresholds and reload size — the threshold is an absolute credit balance, and the minimum reload is 500 credits. The exact price is shown before you save.
  • Pricing — the feature is free, with no credit cost and no plan gate. Each top-up buys the selected credit package at the standard self-serve rate — the same volume-tiered pricing as a manual purchase.
  • Coming next — negotiated per-account rates applied to auto top-ups. Every top-up charges the standard self-serve rate today.
Manage auto top-up on the Credits page; setup steps are in Credits — Auto top-up. Available to all users on all plans.
Feature
Person Search cross-entry matching

Person Search: match conditions across different entries in a profile

Person Search adds all_of, a composite operator whose conditions are each matched by a different entry in a person’s history array. A person record holds arrays with many entries — one for every past job and every degree — so “Engineer at Company A and Manager at Company B” now returns people who held each title at each company, rather than one job carrying both titles. A plain and on the same array path keeps its existing same-entry meaning, so your current searches using this operator don’t change.
  • all_of — a composite operator whose conditions are each matched independently, by their own array entry. Use it for compound cross-entry queries, like a role at one company and a degree from another school, or a past job plus a current one. See the operator reference.
  • has_all — shorthand for one field with several values (“worked at both A and B”). It expands to one all_of block per value.
  • Works across person history — employment, education, certifications, and honors.
  • Combines with document-level filters — nest all_of inside a plain and to add profile-level conditions, so you can ask for a role at a company and a person based in a given country in one query.
  • One matching entry per condition — each condition is satisfied by at least one entry in the array. Conditions do not have to land on the same entry, and they do not have to cover every entry.
  • Backward compatible — a plain and on one array path still matches within a single entry, so existing queries return exactly what they returned before.
  • Pricing — included on all plans. These are new operators on an existing endpoint, so there is no new credit cost and the /person/search rate limit is unchanged.
Available on POST /person/search with x-api-version: 2025-11-01, for all users, at no extra cost.
Feature
Job Search geographic radius filters

Job Search: geo_distance and geo_exclude on job location

Job Search now filters postings by true geographic radius. Pick a point — either a place name like “San Francisco” or a pair of coordinates — and set a distance. geo_distance then returns every job posting whose location falls within that distance of the point, instead of matching on exact location text and listing city names one at a time.
  • geo_distance — returns job postings whose location falls inside the radius.
  • geo_exclude — the inverse of geo_distance. It returns job postings whose location falls outside the radius and excludes the ones inside it, so you can skip a region you already cover. See the geographic radius filters reference.
  • Setting the point and the distance — the point is what the radius is measured from. Pass it as location (a place name, geocoded server-side) or as lat_lng ([lat, lng], which skips geocoding), then add a distance and a unit such as km or mi.
  • Either field path — use location.raw or location; both target the same geo point.
  • Geocoded on ingest — each posting’s location text is turned into real coordinates when Crustdata adds the posting to the database, so the filter compares coordinates rather than matching location strings, and postings in towns you never thought to list still come back.
  • Pricing — no new credit cost. A radius query bills the same as any other /job/search call, and the endpoint’s rate limit is unchanged.
Available on POST /job/search with x-api-version: 2025-11-01, for all users, at no extra cost.
Feature
Teams: shared workspaces and roles

Teams: one workspace with shared credits, API keys, and roles

Bring your whole team into one Crustdata account. Invite teammates by email, give each one a role, and work from a shared credit pool and one set of API keys. Credits and keys now belong to the team, so everyone works from the same place instead of a separate login each. Free on every plan, and existing accounts were migrated automatically.
  • Every account became a team - your existing account is now a team named Personal with you as the owner. Nothing changes until you invite someone.
  • Invite by role - Owner (the creator; bypasses every permission check and cannot be reassigned), Admin (invites members, buys credits, manages payment methods, and creates and manages API keys, watchers, and integrations), and Member (runs playground searches and enrichments against team credits and views usage, keys, watchers, exports, and billing, but cannot purchase, manage keys, or change the team).
  • Shared credits and API keys - everyone on a team draws from one credit pool and one set of cd_ keys, gated by role. Rate limits are shared across the team.
  • Team switcher - one person can belong to and create several teams and switch between them from the sidebar. Credits never move between teams: each team buys and holds its own, which is a clean way to cap spend for a project, client, or department.
  • Per-team billing - each team has its own wallet, subscription, invoices, and saved cards. A new team starts at 0 credits and buys its own.
  • Default limits - up to 2 teams per user and 10 members per team. Reach out to sales to raise either limit.
Manage your team from the Team section of the sidebar at app.crustdata.com; teammates accept an invite from app.crustdata.com/account. Available to all users on all plans at no extra cost.
Feature
Per-API-key credit caps and endpoint access

Per-API-key limits: cap credits and restrict endpoints on one key

A workspace admin can now attach two independent limits to an individual API key from the dashboard API Keys page, without affecting the rest of the account.
  • Monthly credit cap — cap how many account credits one key can spend per month; it resets on the 1st (UTC). Use it for a key you hand to a teammate, a customer, or an unattended job. When the cap is reached, that key returns 402 with error.type insufficient_credits. Setting the cap to 0 stops the key until an admin raises it. See Per-key monthly limit.
  • Endpoint access — restrict a key to a subset of the endpoints the account has enabled. A call to an endpoint outside that subset returns 403 with error.type permission_error. See Per-key endpoint access.
Both errors reuse the same status and error.type as their account-level equivalents, so clients that already handle account-level 402 and 403 need no new code — only the message differs, naming the key’s limit so you can tell which one was hit. Handling patterns are in Best practices.
Feature
Usage and logs filtered by API key

Usage and logs: see and filter activity by API key

Your dashboard now records which API key made each request, so you can tell your keys apart in usage and request logs instead of seeing one merged total.
  • Per-key attribution — every request is tagged with the key that made it, including requests from keys you have since deleted, so past activity stays attributed after a key is rotated out.
  • Filter by key — narrow the Usage and Logs views to one or more keys to see exactly what each key spends and calls. Together with per-key credit caps and endpoint access, you can set a key’s limits and then confirm what it actually did.
View it in the Usage and Logs sections of your dashboard. Available to all accounts.
Feature
Technographics: company technology stack

Technographics: filter by and enrich a company’s technology stack

Crustdata now exposes the technologies detected for a company across Company Enrich, Company Search, and Company Autocomplete.
  • 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, detection sources, posting_count, catalog categories, a description, and evidence), and updated_at. See the field reference.
  • Search filters — filter on technographics.total_technologies (also sortable), technographics.top_technologies, technographics.technologies.name, technographics.technologies.category, and technographics.technologies.super_category. Technographics values are not returned in search responses — filter, then enrich. See searchable fields.
  • Autocomplete — two new company-scope fields: technology (technology names) and technology_category (category slugs) for discovering valid filter values.
  • Access and pricingtechnographics 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.
Available on POST /company/enrich, POST /batch/company/enrich, POST /company/search, and POST /company/search/autocomplete with x-api-version: 2025-11-01.
Improvement
Accurate company lookup by domain

Company lookup: more accurate domain matching for large organizations

We improved domain matching in Company Identify and Company Enrich, 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 stays free and Company Enrich 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.
Feature
Natural-language Person Search query (beta)

Person Search: natural-language search.query (beta)

Person Search 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 →
Feature
Keyword search with Boolean operators

Person Search: keyword search with Boolean operators

Person Search 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 →
Feature
Multiple named API keys per account

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, rename them anytime, and copy the generated cd_ key into any API or MCP request. See Authentication.
  • 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.
Feature
Person Contact Enrich endpoint

Person Contact Enrich: business emails, personal emails, and phone numbers

Person 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.
  • 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 job instead.
Available on POST /person/contact/enrich with x-api-version: 2025-11-01.
Feature
Person Search geo exclusion

Person Search: geo_exclude filter operator

Person Search 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 and a worked example.
Available on POST /person/search with x-api-version: 2025-11-01.
Feature
Profile name and title fields

Professional-network name and normalized title on Person profiles

Person Search and Person Enrich 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 and the enrich response reference.
  • 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.
Feature
Richer Person Search profiles
Person Search 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.
  • 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.
  • 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.
Available on POST /person/search with x-api-version: 2025-11-01.
Feature
Follower count on Person Search

Follower count on Person Search profiles

Person Search 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.
Available on POST /person/search with x-api-version: 2025-11-01.
Feature
Person Search filters

Person Search: new filter operators

Person Search 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 and a worked example.
  • 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 and the lat_lng example.
Both operators are available only on POST /person/search with x-api-version: 2025-11-01.
Feature
API version 2025-11-01

🚀 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 map each legacy endpoint to its new equivalent and walk through request keys, field renames, type changes, and response-shape differences.