GTM Operations

HubSpot Data Enrichment: API and CSV Workflow Guide

The Enrichments TeamAugust 4, 202611 min read
Abstract editorial illustration for “HubSpot Data Enrichment: API and CSV Workflow Guide” — Enrichments

HubSpot data enrichment works best as a controlled data movement process, not a bulk append. Select records for a defined operational purpose, send only the identifiers needed for matching, review returned values, and write approved data back to governed properties.

Plan the HubSpot data enrichment workflow before exporting records

A useful HubSpot data enrichment workflow starts with one operational outcome and a defined update policy.

Choose an outcome that affects how someone works in the CRM. Common examples include:

  • Routing contacts based on seniority, department, or location.
  • Qualifying accounts using company profile context.
  • Reviewing territories using company domain and location.
  • Preparing a sales research queue with current title, employer, and LinkedIn URL.
  • Filling missing company properties needed for segmentation.

This scope determines which records you select and which fields you request. A routing workflow may need seniority, department, and location. An account qualification workflow may need company_domain and company_profile. A research workflow may need title, headline, and linkedin_url.

Start with the identifiers already present in your HubSpot contact enrichment or company process. Useful identifiers include:

  • A work email address.
  • A LinkedIn URL.
  • A company domain.
  • A person’s name plus employer.
  • A company name.

Do not assume every identifier has the same strength. A company domain generally identifies a company more cleanly than a free-text company name. A LinkedIn URL is a direct input for a person record. A name plus employer needs more care when names or employer names are ambiguous.

Before records leave HubSpot, assign an explicit destination property for every field you might return. This is the core CRM field mapping decision. For example:

  • title goes to a contact job title property.
  • seniority goes to a controlled contact seniority property.
  • department goes to a controlled contact department property.
  • company_domain goes to a company domain property or a staged review property.
  • linkedin_url goes to a dedicated profile URL property.
  • Company firmographics go to defined HubSpot company properties.

Also decide who owns each property. A field can be:

  • CRM-owned: maintained by users or another trusted process.
  • Enrichment-owned: safe for the enrichment workflow to update.
  • Review-owned: proposed by enrichment, then approved by a person.
  • Fill-only: populated only when blank.

Without this decision, enrichment tends to create conflicting values and unclear accountability. The technical run may succeed while the CRM becomes harder to trust.

Decide whether API or CSV is the right operating model

Use an API workflow for repeatable automated processing, and use a CSV workflow when people need to supervise the record set and mappings.

An API workflow fits when another system can do all of the following:

  1. Select eligible HubSpot records.
  2. Send stable identifiers to an enrichment service.
  3. Read results and item-level outcomes.
  4. Apply field ownership rules.
  5. Write approved values back to the intended HubSpot properties.
  6. Log exceptions for review.

This model is useful for lifecycle-based maintenance. For example, a process can select records when they enter a routing queue, enrich the required fields, and stage only the approved updates.

A CSV enrichment workflow fits a different kind of work:

  • A supervised backfill.
  • A one-off cleanup project.
  • A property migration.
  • A team review of existing contact or company data.
  • A workflow where the operator needs to inspect mappings and cost before processing.

With Enrichments, CSV upload lets you map input columns to the fields you want returned, preview cost before the run, and download the enriched file. That makes the CSV path suitable when the file itself is the review artifact.

Both operating models should use the same rules:

  • The same identifier preference.
  • The same approved enrichment fields.
  • The same validation policy.
  • The same contact property governance and company property governance.
  • The same conflict-handling process.

The transport should not change what your data model permits.

A CSV or API-based workflow is also different from assuming a native CRM integration exists. You still need a process that selects HubSpot records, maps fields, reconciles outputs, and imports or writes updates to the right properties. The enrichment run is one part of that process.

For REST workflows, small requests can return inline. A people search requesting ten results or fewer, or an enrichment with five rows or fewer, returns an HTTP 200 response with populated results and a terminal job.status. Larger requests are queued, as are requests for the email field and requests using async: true or Prefer: respond-async. Queued work should be polled through GET /api/v1/jobs/{id} until job.status is terminal.

Request the email field by name. It is not in the default set, and work email enrichment is billed only when an address is returned.

Export only the identifiers and records you need

Export a focused working set tied to the business process, not the entire CRM database.

Start with a saved view, list, or other controlled selection process in HubSpot. Define the selection in operational terms. For example, select contacts that need territory review, companies missing a governed firmographic property, or records entering a research queue.

Your export should include:

  • The internal HubSpot record identifier needed to reconcile updates on reimport.
  • The identifier used for enrichment, such as work email, LinkedIn URL, company domain, or name plus employer.
  • Any workflow control fields needed for review, such as owner, lifecycle stage, or a review status.
  • Existing values when reviewers need to compare a proposed update against the current CRM value.

Avoid exporting columns that are not needed for matching, review, or downstream operations. This reduces mapping mistakes and keeps the working file understandable. It also prevents a temporary enrichment file from becoming a loose copy of unrelated CRM data.

Use a controlled filename and versioning convention. Preserve the original export as a rollback reference. Then maintain separate files for:

  • The untouched source export.
  • The submitted enrichment input.
  • The returned output.
  • The approved import file.

Do not use the returned file as an automatic import file without review. The enrichment result may include rows that did not resolve, rows that need conflict review, and fields that are not approved for update.

For batch enrichment, the REST API accepts up to 100 rows per call and returns one output wrapper per input row in input order. That ordering helps, but internal record IDs should still remain in the reconciliation workflow. Position is useful for processing; a durable CRM record identifier is what protects the import.

Map enrichment fields to governed CRM properties

Map each returned field to a property with a clear meaning and a clear owner.

For people, a practical mapping can include:

  • title → contact job title.
  • seniority → controlled contact seniority.
  • department → controlled contact department.
  • location → contact location.
  • country → contact country.
  • linkedin_url → contact LinkedIn URL.
  • company → employer name or a staged employer update field.
  • company_domain → employer domain or a staged review field.

For companies, map the company identity fields deliberately:

  • company → company name.
  • company_domain → company domain.
  • linkedin_url → company LinkedIn URL.
  • location and country → company location properties.
  • headline → a short description property, if your model has one.

Published titles and normalized classifications should remain separate. title is the current title read from work history. It can contain organization-specific wording and may be useful to sales users exactly as published.

seniority is a normalized band derived from that title. Its possible values are founder, c_level, vp, director, manager, senior, and entry. department is also normalized from the title, with values including engineering, product, sales, marketing, finance, operations, people, data, it, and other.

That distinction matters for segmentation. Use title when a user needs the source wording. Use seniority and department when a workflow needs consistent filters.

Handle company profile context as a deliberate entity-level decision. The company_profile field returns the employer’s record nested under company, including industry, headcount, founded year, description, annual revenue, total funding, latest round, and monthly visits. It is one field because one company lookup returns the profile.

Do not create unmanaged HubSpot company properties for every possible firmographic value just because the data is available. Add a property only when it supports a defined process, such as qualification, routing, or account research. A smaller governed schema is easier to maintain than an ever-growing set of fields with unclear use.

Request a work email only when the workflow requires it. An address is sourced from public sources, probed, and returned with an email status: verified, probable, unverified, risky, undeliverable, or unknown. If your CRM design supports it, store the associated status alongside the address in a separate governed property. Do not treat every returned address as interchangeable for every downstream action.

Process and review results before importing them

Review enrichment output as a set of per-record outcomes, not as a flat list of automatically approved values.

API responses use an envelope with job, results, page, and estimatedCredits. When results are available, each item is a wrapper:

{
  "position": 0,
  "status": "succeeded",
  "data": {
    "title": "Director of Sales",
    "seniority": "director",
    "department": "sales"
  },
  "evidence": null,
  "error": null
}

The item status can be pending, running, succeeded, not_found, or failed. Your operational workflow should preserve those distinctions.

A succeeded item can still require a comparison with existing CRM data. Review conflicts such as:

  • A different employer than the current contact record.
  • A changed company domain.
  • A new title that contradicts a recently confirmed value.
  • An identity match that is not sufficiently clear for an overwrite.
  • A company profile that conflicts with a manually curated account record.

A not_found item is a valid outcome. Do not fill missing values with placeholders, inferred values, or guesses. A failed item is also not a reason to reuse the same weak input repeatedly. Record the exception and improve the identifier when possible.

Only fields actually resolved by enrichment should be introduced into the approved import file. This matters because an enrichment row is charged only when at least one requested field was resolved. It also keeps your import from rewriting CRM values with empty cells or unchanged identifiers.

Enrichment is live rather than a licensed static database. The same query can return different data on a later run. Treat the output as a current observation that follows your property policy, not as a permanent truth that overrides every existing value.

Import updates without damaging trusted CRM data

Use internal record identifiers to associate every approved update with the intended HubSpot contact or company record.

Do not rely on name matching during the import step when an internal record ID is available. Names change. Employers change. Domains can be shared or entered incorrectly. The internal record identifier is the reconciliation key between your source export and your approved update file.

Apply a field-level import policy. The policy should be explicit for each destination property:

  • Fill blank values for properties where existing CRM values are trusted.
  • Stage proposed updates in separate review properties when a conflict needs human approval.
  • Overwrite enrichment-owned fields only when your governance model permits it.
  • Do not import fields that are useful for review but not approved for CRM storage.

For example, title may be staged when a sales team actively maintains it. Department and seniority may be enrichment-owned if they support standardized routing. Company domain may require review if changing it would affect account association logic.

Test the import process with a small controlled group before broader operational use. Verify:

  • The internal identifiers point to the intended records.
  • Contact fields map to contact properties.
  • Company fields map to company properties.
  • Blank cells do not erase trusted values.
  • Review fields do not overwrite production fields.
  • Email status is associated with the intended work email field.

Maintain a rollback path. Keep the original export, the approved import file, and a record of which properties changed. If an import rule behaves unexpectedly, you need to know both the prior values and the file that introduced the change.

Operationalize maintenance and exception handling

Make re-enrichment event-driven and exception-aware rather than repeatedly running the same broad export.

Set practical triggers based on the processes that depend on current data. You might re-enrich when:

  • A contact enters an important lifecycle stage.
  • An account enters a qualification queue.
  • A record is assigned to a new owner.
  • A user flags title, employer, domain, or location as stale.
  • A company is being reviewed for territory or segmentation changes.

Keep the request narrow. Request only the fields needed by that trigger. If a routing process only needs normalized department and seniority, it does not need a full research-oriented field set.

Route unmatched and conflicting records to a review queue. Repeatedly retrying a weak identifier can create duplicate work without improving the outcome. Instead, capture why the item could not be processed and ask for a better identifier when the business case supports it.

For automated REST requests, use an Idempotency-Key header when retrying after a failure or timeout. A retry is free only when it carries the same Idempotency-Key as the original request. Without that header, the retry is a new request, creates a second job, takes a second hold, and can be charged.

Poll queued runs through the job endpoint and read job.status, not a top-level status field. Terminal states include succeeded, empty, failed, and cancelled. Polling itself does not cost credits. Results are cursor-paged through the opaque forward-only cursor in page, so preserve the cursor exactly as returned rather than constructing one.

Finally, review property usage regularly. Remove fields that no longer support routing, segmentation, or research. Revisit ownership when a property starts receiving updates from more than one process. A governed HubSpot data enrichment workflow stays useful because its field model remains connected to actual GTM operations, not because it accumulates more data.

Frequently asked questions

What is the best way to plan HubSpot data enrichment?
Start with one operational outcome, such as routing, qualification, research, or segmentation. Define the records, identifiers, returned fields, destination properties, and ownership rule before exporting data.
Should I use an API or CSV for HubSpot data enrichment?
Use an API for repeatable automated workflows that can select records, apply ownership rules, write approved values, and log exceptions. Use CSV for supervised backfills, cleanup, migrations, and review-led work where operators need to inspect mappings and cost before processing.
Which identifiers should I export from HubSpot for enrichment?
Export the internal HubSpot record identifier along with the identifier needed for matching, such as work email, LinkedIn URL, company domain, or name plus employer. Include only the control fields and existing values needed for review and reconciliation.
How should enrichment fields map to HubSpot properties?
Map each returned field to a property with a clear meaning and owner. Keep published title separate from normalized seniority and department, and use staged review properties where a proposed update could conflict with a trusted CRM value.
What should happen when an enrichment result is not found or conflicts with CRM data?
Treat not-found and failed items as review outcomes rather than reasons to guess or reuse weak inputs. Compare successful results with existing CRM values, stage conflicts for review, and improve the identifier when appropriate.

Keep reading

Put this into practice

Enrichments resolves people and companies from a REST API, an MCP server, the chat agent or a CSV upload, checks every email address it finds, and bills you only for the data that comes back.

Start enriching for free