Skip to content

Integration  ·  Platform engineering

How to build customer field mapping

The customer's custom field isn't in the list, so they file a ticket, wait a week, and half of them never finish setup. How customers map their own fields inside your product, the prompts that build it, and how to turn it on without a first sync that floods their account.

Built with Tray Headless

  1. System Your product
  2. Step List their fields
  3. Step Customer maps
  4. Step Preview real records
  5. Step First sync, in batches
  6. System HubSpot

The customer picks from their own fields, a preview shows real records before anything is written, and the first sync runs in small batches.

The short answer

What is customer field mapping?

Customer field mapping has four parts: a list of the customer's own fields read live from their account, custom fields included, so they never have to type a field name; sensible default matches so most customers change nothing; a preview of a few real records before anything is written; and a first sync that runs in small batches, newest first, so it never hits the customer's API limit or floods their account. With Tray Embedded the mapping is a data mapping slot in the config wizard, or your own form for large mappings. Most teams skip the preview. Customers learn their mapping was wrong from the records it wrote.

Stage 4 of 7: Customers map their fields and go live. Part of Embedded integration, end to end : every stage, the systems it runs on and the guide that builds it.

What matters here

  • Read the customer's fields from their account. A fixed list never has their custom fields.
  • Default every match you can. Most customers should be able to accept the mapping as it is.
  • Show a preview of real records before anything is written. It catches wrong matches in seconds.
  • Run the first sync in batches, newest records first. A three-year backfill in one go hits the customer's API limit.
  • Let customers change the mapping later without starting again. Their fields change too.

Who this is for

You build the integration experience inside a software product. Customers need to match your product's fields to their own, and mapping questions are your biggest source of setup tickets.

How it works in practice

From a customer opening setup to their first records syncing.

  1. 1

    The customer's fields are read from their account

    Standard and custom, with their labels and types, straight after they connect.

  2. 2

    Default matches are filled in

    By name and type, so email maps to email and the customer reviews rather than builds.

  3. 3

    The customer adjusts and adds

    Picking from their own fields, with a type check so a date can't be mapped to a yes or no field.

  4. 4

    A preview shows real records

    Five records from your product, as they would appear in the customer's app, before anything is written.

  5. 5

    The instance is turned on

    After your own checks, since a new instance starts switched off.

  6. 6

    The first sync runs in batches

    Newest records first, paced to the customer's API limit, with progress shown in your product.

What customer field mapping is made of

Four parts. The third is the one that saves the support ticket.

A live field list

Read from the customer's account each time setup opens, so a custom field added yesterday is in the list today.

Default matches

Filled in by name and type, with required fields marked, so most customers accept the mapping and move on.

A preview

A handful of real records shown as they would land, so a wrong match is seen before it writes anything.

A paced first sync

Batches, newest first, within the customer's API limit, with progress and a clear finish.

The Tray Headless prompts

Paste these into Claude Code or Codex with the Tray Headless plugin installed. Each stage runs on its own. The systems named in them are the worked example rather than a requirement, and every prompt says so.

Once per project, run /tray-workflows:set-workspace to pick the workspace these build in. Point it at a sandbox first.

  1. 1

    Read the customer's fields from their account

    A fixed list never has their custom fields.

    Headless skills build-workflow

    Use build-workflow. The integration writes contacts and companies from
    our product to HubSpot, or whichever app we are integrating with.
    
    Build a small workflow that, given a customer's connection, lists the
    fields on each object we write to: name, label, type, whether it is
    required, and for pick lists, the allowed values.
    
    In Tray Embedded, use this list for the data mapping slot in the
    config wizard, so the customer picks from their own fields. If a
    customer will map more fields than fit on one screen, tell me, and
    we will use our own form with the same list instead.
  2. 2

    Fill in the defaults and check the types

    Most customers should accept the mapping as it is.

    For each of our fields, suggest a match from the customer's fields by
    name and type. Mark which of our fields must be mapped.
    
    Refuse a match whose types can't hold the value: a date into a yes or
    no field, free text into a pick list without a value rule. Say why in
    plain words next to the field.
    
    Store the mapping on the customer's instance, so they can change it
    later without setting the integration up again.
  3. 3

    Preview before anything is written

    A wrong match is seen in seconds, not in their records.

    Headless skills build-workflow tray-gotchas

    Use build-workflow and tray-gotchas. Before the customer finishes
    setup, take five recent records from our product, apply their mapping,
    and show the result as it would appear in their app, field by field.
    
    Write nothing to the customer's account during the preview. Flag any
    required field that would be empty, and any value that their app
    would refuse.
  4. 4

    Turn it on, then sync the history in batches

    A three-year backfill in one go hits their API limit.

    A new instance starts switched off. When setup finishes, run our own
    checks (connection works, required fields mapped), then turn it on.
    
    Run the first sync in batches, newest records first, paced to the
    customer's API limit for their plan. Match on email or the customer's
    own id so a record that already exists is updated, never duplicated.
    
    Show progress in our product and tell the customer when the history
    has finished. After that, only changes sync.

    Newest first means the records the customer cares about are there in minutes, even when the full history takes hours.

What it connects to

The fields are the customer's. The mapping belongs to their instance.

HubSpot

List the customer's fields, custom ones included, then write mapped records in paced batches.

Reads and writes

Salesforce

The same pattern for any app with custom fields: read the field list live, map, preview, sync.

Reads and writes

Slack

Tell your support team when a customer's first sync stops partway, with the record and the reason.

Writes

Same build, other stacks

The design does not change if you run something else in one of these seats. The same prompts build it against Microsoft Dynamics 365, Microsoft Teams, Marketo, Google Chat or Braze.

Connections in this build

Field mapping, templates and common problems for each pairing: HubSpot + Salesforce, HubSpot + Slack and Salesforce + Slack.

Named systems are the ones most teams run, not the only ones that work. Each is an authentication in your Tray workspace, referenced by name, so the workflow never holds a credential. Where we have a connector page, the name links to it.

Running it in production

This writes into your customer's system of record. Wrong data there is your product's fault in their eyes.

Nothing is written before the customer sees it

The preview reads and maps but never writes, so the first record in their account is one they have already seen.

The first sync can't flood their account

Batches, newest first, within their API limit, matching existing records rather than creating copies.

The mapping belongs to the customer

Stored on their instance and editable later, so a new custom field is a setting change, not a ticket.

Every write is traceable

Which run wrote which record with which mapping, so a customer's question about a field can be answered.

Questions people ask

How do customers map custom fields?

By picking them from a list read live from their account. They never type a field name, so a custom field added yesterday is there today.

What if a customer has hundreds of fields to map?

Build your own setup form and use the same live field list behind it. The config wizard suits most mappings, but very large ones are easier on a page you design.

How do you stop the first sync flooding the customer's account?

Run it in batches, newest records first, paced to their API limit, and match existing records so nothing is duplicated.

Can customers change their mapping later?

Yes. The mapping is stored on their instance, so they can open setup again and change it without reconnecting their account.

Last reviewed October 2026.