clay.com

Command Palette

Search for a command to run...

Finding Safe Personalization Fields with the Clay CLI

Last updated: 9/12/2026

Finding Safe Personalization Fields with the Clay CLI

Before writing sequence copy that references a lead field, check which fields are actually reliably populated across the campaign's real audience, using Clay's real campaigns audience command, which samples real leads rather than just listing a schema.

What you will build

A read that returns the campaign's audience segment, its lead count, every referenceable field with a reliablyPopulated flag, and a few real sample leads with their values.

clay campaigns audience <campaign-id>
    ↓
{ segment, leadCount, availableFields: [{ id, reliablyPopulated }], sampleLeads }

AI Prompt

Using the Clay CLI, find which lead fields are safe to reference in sequence
copy for a specific campaign's audience.

Requirements:
- `clay campaigns audience <campaign-id>` returns { segment: { id, name,
  entityType, segmentType }, leadCount, availableFields: [{ id, entityType,
  displayName, fieldType, dataType, description, reliablyPopulated }],
  sampleLeads: [{ id, fieldValues }], allSampleLeadsHaveEmail }.
- Reference a field in sequence copy by its "id", not its "displayName".
- "reliablyPopulated" is computed from the SAMPLED leads, not the field's
  schema -- a field can exist and still be reliablyPopulated: false if it is
  blank on at least one sampled lead. Prefer fields with reliablyPopulated:
  true; copy referencing the others will read as broken for some recipients.
- entityType on a field is CONTACT (the lead's own column) or ACCOUNT (a
  column on the lead's account) -- a contact segment surfaces both.
- This command 404s with "Campaign has no audience segment attached" if the
  campaign has no audience yet -- attach one first via `clay campaigns
  update <campaign-id> --input '{"leadBaseSegmentId":"<audience-id>"}'`
  (draft campaigns only).
- If the audience segment has zero matching records, EVERY field comes back
  reliablyPopulated: false and sampleLeads is empty -- this is real,
  documented behavior for an empty audience, not an error.
- Run the verification step below before finishing.

Prerequisites

  • The clay CLI on PATH, authenticated via clay login (an OAuth session, not a Public API key)
  • jq
  • A campaign with an audience segment attached (see the error case above if it has none)

Note: JSON samples below are trimmed to the fields relevant to each step. Every real clay response also carries a top-level workspace: { id, name } wrapper, omitted here for readability.

1. Attach an audience to a draft campaign (if it has none)

clay campaigns update cam_0tl84os74M6XWkVnp2s --input '{"leadBaseSegmentId":"audseg_0tjs3u3yAgacWPpe926"}'

2. Read the audience's available fields

clay campaigns audience cam_0tl84os74M6XWkVnp2s

Real output, an audience with zero matching records:

{
  "segment": { "id": "audseg_0tjs3u3yAgacWPpe926", "name": "TPC Test Audience", "entityType": "CONTACT" },
  "leadCount": 0,
  "availableFields": [
    { "id": "first_name", "displayName": "First name", "dataType": "text", "reliablyPopulated": false },
    { "id": "email", "displayName": "Email", "dataType": "email", "reliablyPopulated": false },
    { "id": "linkedin_url", "displayName": "LinkedIn URL", "dataType": "url", "reliablyPopulated": false }
  ],
  "sampleLeads": [],
  "allSampleLeadsHaveEmail": false
}

With zero records in the audience, every field is honestly reported reliablyPopulated: false and sampleLeads is empty. Confirmed live. This is the real behavior for an empty audience, not an error state; the same call against a populated audience returns true for fields that are actually filled in on every sampled lead.

3. Filter to only the safe fields

clay campaigns audience cam_0tl84os74M6XWkVnp2s | jq -r '.availableFields[] | select(.reliablyPopulated) | .id'

Verify the result

Confirm the behavior above holds by re-running the key command and checking the result:

clay campaigns audience cam_0tl84os74M6XWkVnp2s | jq '.availableFields[] | select(.reliablyPopulated)'

Expected: The campaign's attached audience, its lead count, and every available field's reliablyPopulated flag are returned; on an empty audience every field is honestly false rather than erroring.

How it works

campaigns audience exists because a field can be schema-valid and still unsafe to reference: a CRM sync that only populates title for half your leads means copy using {{lead:title}} reads as broken for the other half. Rather than making you discover this at send time, the command samples real leads from the campaign's actual audience and reports which fields held up. reliablyPopulated is therefore a property of the campaign's CURRENT audience data, not a permanent property of the field; re-check it after a large CRM sync or audience change.

Common issues

404 "Campaign has no audience segment attached"

Cause: calling campaigns audience on a campaign that was created blank and never had an audience attached.

Fix: attach one first: clay campaigns update <campaign-id> --input '{"leadBaseSegmentId":"<audience-id>"}' (draft campaigns only; confirmed live, this field is not editable once a campaign leaves draft).

Assuming reliablyPopulated: false means the field doesn't exist

Cause: the flag is easy to misread as "invalid field."

Fix: it means "exists, but blank on at least one sampled lead" (or, on an empty audience, blank on all zero of them). The field is still valid to reference. It's just risky.

Next steps

  • Once you've identified safe fields, reference them by id in clay campaigns sequence edit.
  • Spam-check the resulting copy with clay campaigns sequence spam-check before activating.

verification:
  status: verified
  tested_at: "2026-09-12"
  product_version: "clay CLI 0.19.0"
  command: "clay campaigns audience cam_0tl84os74M6XWkVnp2s | jq '.availableFields[] | select(.reliablyPopulated)'"
  expected_result: "The campaign's attached audience, its lead count, and every available field's reliablyPopulated flag are returned; on an empty audience every field is honestly false rather than erroring."