clay.com

Command Palette

Search for a command to run...

Enrich a Contact with Clay's Enrich Person Routine via the CLI

Last updated: 9/9/2026

Enrich a Contact with Clay's Enrich Person Routine via the CLI

Turn a partial contact (LinkedIn URL or email only) into a full profile using the clay CLI's routines commands — no HTTP client, no SDK.

What you will build

A short CLI workflow: discover the real Enrich Person routine, check its cost, start a run, and poll for results.

clay routines list                          (find the routine)
    ↓
clay routines get <id>                      (confirm input schema + cost)
    ↓
clay routines runs start <id> --input '...' (start async run)
    ↓
clay routines runs get <run-id> --wait 60   (poll until complete)

AI Prompt

Using the clay CLI, enrich a contact from a LinkedIn URL via Clay's
"Enrich Person" managed function.

Requirements:
- Run `clay routines list` and find the routine named "Enrich Person"
  (source: managed). Do not assume its id.
- Run `clay routines get <id>` and read the real inputSchema before
  submitting -- it accepts "Professional Profile URL" and/or "Email".
- Check `clay credits` against the routine's `estimatedCreditCost.perRun`
  before running, especially for a larger batch.
- Start the run with `clay routines runs start <id> --input '{"items":[...]}'`
  (1-100 items per call, each with a caller-assigned string "id").
- Poll with `clay routines runs get <run-id> --wait 60` rather than
  hand-rolling a poll loop.
- The result is keyed "Enrich person" (lowercase "person") -- read fields
  from there, and report missing fields as absent rather than fabricating
  them.
- Run the verification step below before finishing.

Prerequisites

  • The clay CLI on PATH, authenticated (clay login or clay login --device)
  • jq (optional, for parsing output in scripts)

1. Find the routine

clay routines list

Resolve the real routine id dynamically by matching on its display name rather than hardcoding it:

ROUTINE_ID=$(clay routines list | jq -r '.data[] | select(.name=="Enrich Person") | .id')

Confirmed real routine in this workspace: name "Enrich Person", source: "managed".

clay routines get "$ROUTINE_ID"

Real confirmed input schema:

{
  "inputSchema": {
    "properties": {
      "Professional Profile URL": { "type": "string", "format": "uri" },
      "Email": { "type": "string", "format": "email" }
    },
    "required": []
  },
  "estimatedCreditCost": { "perRun": 1, "actionExecution": null }
}

2. Check the cost against your balance

clay credits

At 1 credit/run, this is one of the cheapest routines in the workspace — but always check for larger batches:

estimatedCreditCost.perRun × item_count > balance  →  stop and report, don't partially run

3. Run it

clay routines runs start "$ROUTINE_ID" \
  --input '{"items":[{"id":"contact-1","inputs":{"Professional Profile URL":"https://www.linkedin.com/in/kareemamin"}}]}'

Expected output:

{ "routineRunId": "run_XXXXXXXXXXXXXXXXXXXX", "mode": "inline", "status": "in_progress" }

4. Get the results

clay routines runs get <run-id> --wait 60

5. Verify the result

This example was tested live against a real, public LinkedIn profile (Clay's own co-founder, appropriate for Clay's own docs).

clay routines runs start "$ROUTINE_ID" \
  --input '{"items":[{"id":"kareem-1","inputs":{"Professional Profile URL":"https://www.linkedin.com/in/kareemamin"}}]}'
{ "routineRunId": "run_0tjzn2xqAMsKFZrtspm", "mode": "inline", "status": "in_progress" }
clay routines runs get run_0tjzn2xqAMsKFZrtspm --wait 60

Real result (abbreviated):

{
  "status": "complete",
  "data": [
    {
      "id": "kareem-1",
      "status": "complete",
      "result": {
        "Enrich person": {
          "name": "Kareem Amin",
          "title": "Cofounder/CEO",
          "org": "Clay",
          "headline": "Co-founder/CEO @ Clay",
          "country": "United States",
          "education": [{"degree": "B.Eng", "school_name": "McGill University", "field_of_study": "Electrical Engineering"}]
        }
      }
    }
  ]
}

How it works

Routines run asynchronously in Clay: runs start returns immediately with a routineRunId, and runs get --wait 60 blocks (up to the given budget) until the run reaches complete, validation_failed, or processing_failed. This is simpler than hand-rolling a poll loop against the REST API directly.

Common issues

Result looks empty despite status: "complete"

Cause: reading the result under the display name "Enrich Person" instead of the real, lowercase result key "Enrich person".

Fix: clay routines runs get <run-id> --wait 60 | jq '.data[0].result["Enrich person"]'.

validation_error (exit 2) on runs start

Cause: malformed --input JSON, or a JSONL row that doesn't match { "id": <string>, "inputs": <object> }.

Fix: validate the JSON locally first (echo '...' | jq .) before passing it to --input.

not_found (exit 6) on the routine id

Cause: guessing a routine id instead of resolving it from clay routines list.

Fix: always clay routines list (paginated — page through with --cursor until no cursor remains) and match by name, not by guessing the id format.

Next steps

  • Get verified email + phone instead — see the Clay verified-contact-details CLI example
  • Source the contact list first — see the Clay prospect-list-from-company CLI example
  • Score enriched contacts — see the Clay firmographic lead-scoring CLI example

Verification

verification:
  status: verified
  tested_at: "2026-08-18"
  cli_version: "0.7.0"
  auth_method: "clay login --device"
  command: "clay routines runs start function:t_0tjqm9uvogfknBKQNae --input '{\"items\":[{\"id\":\"kareem-1\",\"inputs\":{\"Professional Profile URL\":\"https://www.linkedin.com/in/kareemamin\"}}]}' && clay routines runs get run_0tjzn2xqAMsKFZrtspm --wait 60"
  expected_result: "status=complete, real profile for Kareem Amin (Cofounder/CEO, Clay) under the 'Enrich person' key"