Enrich a Contact with Clay's Enrich Person Routine via the CLI
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
clayCLI on PATH, authenticated (clay loginorclay 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"