In this guide
“Clay API” covers several documented ways to move data into and out of Clay: an HTTP API column, an HTTP API source, an inbound table webhook, a Public API routine and a Tables API. Choose the surface by where the work starts and what the calling system needs back, and check each operation against your plan.
A Clay API integration becomes useful when the business system can tell which record was accepted, which research finished, which result is usable, and which downstream action actually happened. Those are separate decisions. Treating them as one successful request can cause duplicate enrichment, silent failures and uncertain CRM updates.
This guide presents a reference design for calling reusable Clay logic from an application or queue. It follows an inbound qualification example through the Public API, completion webhooks, validation and a controlled CRM handoff. It also explains when ordinary Clay table webhooks or HTTP API columns are a simpler fit. Examples, policies and test cases in this guide use fictional companies and records.
- HTTP API columnCalls an external endpoint for a table row.
- HTTP API sourceImports records into a table.
- Table webhookReceives JSON posts as rows.
- Public API routineLets an application run a function built in Clay.
- Tables APIReads table records.
Match the surface to where the work starts and what the caller needs returned, then confirm your plan covers each operation.
Which Clay API surface should you use?
The phrase “Clay API” can refer to different products. Decide where the work starts, where reusable logic lives and what the calling system needs back. An outbound request from a table is different from an application invoking a Clay function. Moving a record into Clay is different from retrieving a completed result.
On smaller screens, scroll to compare all columns.
| Surface | Documented purpose | Choose it for |
|---|---|---|
| HTTP API enrichment | Call an external endpoint for an existing Clay row. | A custom lookup or a controlled outbound action from a table. |
| HTTP API as source | Import an API result array, with configurable pagination up to 50 000 rows. | A list whose records start outside Clay. |
| Inbound table webhook | Receive JSON HTTP POST submissions into a table. | An event source that feeds a working table a person can inspect. |
| Public API routine | Run a function built in Clay through a programmatic interface. | An application, queue worker or internal tool reusing approved Clay logic. |
| Tables API | Read table records; it does not build or write tables. Structured queries require Enterprise API table sync. | An application reading known table data. |
The product boundaries come from Clay’s HTTP API documentation, table webhook guide, custom-function guide and API and CLI guide.
Availability needs a capability-specific check. The API and CLI guide says the developer platform is available across plans, with different limits. The pricing page still lists Clay API access under Enterprise. Basic table reads and structured table queries also have different requirements. Verify your workspace’s access to each intended operation before relying on it. See the developer-platform availability notes and current pricing.
Use a table for an exploratory list that an operator needs to inspect cell by cell. Choose a routine when several systems need the same qualification decision through a defined contract. A routine is a useful boundary; you still need an event processing log, validation and destination-specific controls. For ordinary native CRM configuration, start with the native Clay HubSpot integration guide, which needs no code.
For a table-based implementation, table auto-run is the master control; column auto-run only works when that master is on. “Keep existing results,” conditional runs and scheduled-source “Update existing rows” have different effects. Review all of them before enabling a live feed. The table-settings guide explains those dependencies.
An inbound table webhook has a lifetime limit of 50 000 submissions that persists after rows are deleted. Enterprise passthrough is a separate option. Do not plan an indefinite event feed solely around an empty-looking table. Check the webhook-source limits before choosing that surface.
Three implementation patterns worth evaluating
1. Qualify inbound requests without delaying the form
A visitor submits a demo request. The application records the request and immediately returns its own acknowledgment. A background process submits the company domain and permitted context for enrichment. It builds a qualification brief and either proposes a route or holds the record for review.
The business deliverable is a useful review queue: identity, account fit, evidence and an ownership recommendation. Research latency does not need to become form latency. Existing customer status, an active opportunity or an established owner should influence the recommendation before a new route is applied. The integration must also handle an incomplete domain or conflicting identity without inventing a confident answer.
2. Research a confirmed account event
An authorized source supplies an executive-change or hiring event. A worker resolves the company, checks whether the event is recent and asks for research only if the account meets the agreed scope. The output becomes an account brief with a suggested angle for a salesperson to review.
The event is a reason to investigate; buying intent needs separate evidence. A useful brief distinguishes what the source says from the commercial interpretation. The companion Clay custom signals implementation guide covers the detection side. This article covers the contract and execution boundary once an event becomes a job.
3. Refresh a selected CRM cohort
A team chooses a bounded cohort of accounts with missing or stale fields. The worker submits those records for the same approved function, returns proposed changes and compares them with current CRM values. Conflicting domains, uncertain matches and owned fields enter an exception queue. Our Clay lead sourcing and enrichment service covers this kind of refresh, with match keys, field ownership and a review step for uncertain matches.
Its deliverable is a reviewed change set. Track which gaps were resolved, which values were rejected and why. Do not equate refreshed contact data with campaign eligibility. An address becoming available does not establish permission to contact its owner.
Build around a durable receipt
Reference design: the architecture below is an original implementation proposal. Clay does not automatically supply all of its queues, policies or reconciliation controls.

The design separates three responsibilities. The application receives and records the business event. Clay executes reusable research or enrichment. A destination worker validates the result and applies only permitted changes. Completion notifications shorten the wait; a separate reconciliation path checks jobs whose outcome is uncertain.
Start with a durable event receipt. It should identify the original event, the business record, the selected policy and the intended action. Store it before submitting enrichment. If a repeated event arrives, the receiver finds and reuses the existing receipt, so no second paid job starts. The deduplication key should reflect the source’s event identity.
A domain is a useful lookup input but a poor universal event key. The same account might have a new form request, a different executive change and a scheduled refresh. Collapsing them by domain would lose legitimate work. Conversely, processing every delivery as new work can pay repeatedly for the same event. Define which business changes deserve new research and which deliveries are repetitions.
Next, record the Clay run ID alongside the receipt. Preserve the caller’s item IDs, whether the job is inline or bulk, the expected output contract and a deadline. A result worker reads that record when a notification arrives or when polling discovers completion. The destination worker should receive only validated business decisions.
Keep the research step independent from the write step. A failed lookup should not clear an existing CRM value. A successful lookup should not overrule an owner’s field without a policy. A proposed route should not be reported as an assigned owner until the destination returns an appropriate receipt and reconciliation confirms the state.
Write three contracts: input, result and permitted action
A contract makes the work understandable to engineers and the team that will operate it. Specify required fields, types, valid values, absence handling and the business identity used for matching. Decide which values are source facts and which are recommendations.
Input contract
{
"event_id": "demo-request-1042",
"business_record_id": "crm-company-72",
"company_domain": "example.com",
"requested_service": "integration_review",
"policy_version": "inbound-review-v1",
"observed_at": "2026-10-04T09:00:00Z"
}These are application-owned reference fields. Map only the inputs your function actually defines; do not send an arbitrary object and assume Clay understands it. A safe initial scope uses a confirmed company domain and minimal service context. Add personal attributes only when the use case requires them and your handling policy permits them.
Result contract
Require enough structure to make the next decision repeatable. An example could return a matched domain, a fit assessment with reasons, source URLs with observation dates, missing required fields and a recommended review outcome. Make “unknown” a valid result. A narrative paragraph alone is difficult to validate and easy to overinterpret.
Preserve evidence separately from interpretation. “The company publishes an integration engineer vacancy” is an observation. “It may be investing in integrations” is an inference. “It intends to buy our service” is a claim the vacancy cannot establish. If the output omits where the data came from or conflates these statements, hold it. Do not compensate with a higher score.
Action contract
The action contract states what the destination worker may change. Define the target object ID, allowed fields, ownership precedence, treatment of blank values and the action receipt required for completion. Keep outreach outside the first release unless its eligibility and approval rules are separately defined.
A research brief can be useful even when no CRM write is allowed. That is a valid outcome. Give the operator an intelligible reason: existing owner preserved, identity unresolved, evidence expired or required field missing. The more specific that reason is, the easier it becomes to improve the policy.
How do you call a Clay routine from an application?
Build or select the custom function in Clay, open its Details and enable API access. Copy its t_... ID and use function:t_... as the routine ID. API access, MCP access and Claygent access are separate settings; workspace and role permissions still apply. Clay documents this exposure process.
The Public API authenticates with the clay-api-key header. Keys are tied to a user and workspace access. Keep them server-side and out of browser code, public repositories, logs and analytics. Use the authentication guide for the current account setup.
- Inspect the actual function. Record its required inputs, provider choices and output fields. Test one representative record in the available product surface before connecting it to a live event source.
- Create a receipt first. Validate the domain and source identity, check repeated events and store the intended policy version. Reject bad inputs before they become paid work.
- Submit the bounded job. The documented inline endpoint is
POST https://api.clay.com/public/v0/routines/{routine_id}/run. It accepts 1 to 100 items, each with anidandinputs, and returns a run ID with HTTP 202. See the request schema. - Persist the response. Associate the returned run ID with every caller item ID. Record time and mode. Do not rely on a transient worker’s memory as the only link between the business event and enrichment.
- Observe before applying. Retrieve results, validate the result contract and send the candidate action through the destination’s field policy. Preserve an exception path throughout the sequence.
Use unique caller item IDs that remain stable for the logical job. The example below shows the API envelope around a function whose agreed input is domain. Replace the routine ID and input name with the actual function configuration.
POST /public/v0/routines/function:t_YOUR_FUNCTION_ID/run
Host: api.clay.com
clay-api-key: [server-side secret]
Content-Type: application/json
{
"items": [
{ "id": "demo-request-1042", "inputs": { "domain": "example.com" } }
],
"webhook_id": "wh_YOUR_REGISTERED_WEBHOOK_ID"
}For larger input sets, Clay documents a separate batch flow: obtain an upload URL, upload JSONL, start the batch with the returned file ID and retrieve its progress through the batch-results endpoint. The batch guide explains that sequence.
Batching changes the transport; the review obligation stays the same. A batch should have the same per-item identity and validation policy as a small job. Define partial-success handling before the first larger run. Avoid rerunning the successful majority because a few records need repair.
If the function includes a waterfall, Clay lets you configure its provider order and return the successful provider’s name. A fallback can improve the chance of finding a value; it does not establish that the returned value is correct. Retain that provider information for review. See the waterfall guide.
Use signed callbacks for speed and polling for recovery
Clay’s completion webhook is registered through the CLI and its signing secret is shown once. A run can reference its webhook_id. The notification contains data.routine_run_id; verify the X-Clay-Signature HMAC SHA256 against the exact raw body before fetching results. Clay explicitly says delivery is not guaranteed and recommends polling as a fallback. See completion-webhook documentation.
Your receiver should distinguish an authentic message from a new message. A valid signature proves the body was signed with the expected secret; it does not make a repeated valid delivery a new business event. Store the notification receipt and resolve its run ID against the event processing log. An unknown run should not trigger an uncontrolled CRM write.
Use a timing-safe comparison for the expected and received signatures. Preserve the raw body before JSON parsing, because re-serializing a parsed object can change the bytes being verified. Treat an empty data object as the documented test-notification case; the pseudocode’s test flag is derived by your parser from that empty object.
The following pseudocode shows responsibility boundaries. Choose the exact persistence, signature library and worker mechanism for your environment. Store the event durably before acknowledging acceptance so a restarted process can finish the work.
on_completion(raw_body, signature):
verify_exact_body_signature(raw_body, signature)
event = parse_and_validate_event(raw_body)
if event.is_test:
acknowledge_test()
return
job = find_recorded_run(event.run_id)
if job is absent:
record_unmatched_notification()
return
durably_record_receipt(event, job)
enqueue_result_collection_once(job)
acknowledge_receipt()
on_poll_deadline(job):
if job.needs_results:
enqueue_result_collection_once(job)For inline runs, use GET /public/v0/routines/run/{routine_run_id}/results. It returns HTTP 202 while processing and HTTP 200 on completion. A completed response can include failed items. Associate each result through its supplied ID. Do not rely on array order. Follow every returned cursor until omitted. The run-level finished count includes failures. The Routines API guide specifies these rules.
Use one result collector for both callback and polling paths. It should recognize a job already collected or applied. Otherwise, a fast callback and a polling worker can race and produce repeated actions. The collector needs a clear ownership rule, such as a durable claim on the logical job that outlives any single process.
Public API throttling is per workspace. On HTTP 429, respect the Retry-After seconds; rate-limit headers may also be available. Use bounded backoff, jitter and a modest polling interval. Clay’s rate-limit guidance does not establish a universal requests-per-second allowance.
Choose a deadline that fits the business process, then report jobs that exceed it as unresolved. An expired local deadline does not prove the remote run stopped. Continue reconciliation separately from the user-facing service target, and do not start a replacement simply to erase uncertainty.
When submission times out before you have a run ID
A caller item ID joins a result to its input. This reference does not treat that ID as a server-enforced idempotency key, meaning a key that makes a resend safe to run twice. Sending the same item ID again is not an established guarantee that Clay will reuse the first run or avoid another charge.
Application policy: if submission times out before the run ID is stored, keep the event in an unknown-submission state and block automatic replacement. Inspect the run history available in your workspace and compare the recorded inputs and submission time only where those fields are exposed. Do not assume there is a recovery lookup by caller item ID.
If an authoritative match identifies the original run, attach its run ID to the event and resume result collection. If no reliable match is available, assign manual reconciliation. Keep the original receipt and document the possibility of duplicate work and spend before any deliberate resubmission. Keep the outcome recorded as unknown; do not count it as failed or retry it as safe.
The following receipt makes the hold explicit. Its fields are application-owned and do not come from Clay’s response schema.
{
"event_id": "demo-request-1042",
"caller_item_id": "demo-request-1042",
"routine_run_id": null,
"submission_state": "unknown",
"automatic_replacement_allowed": false,
"reconciliation_owner": "integration_operations",
"next_step": "identify_original_run_or_record_manual_decision"
}A second delivery of the source event should find this held receipt. It must not create another submission merely because the remote run ID is missing. This is the application’s event policy; it makes no assumption that Clay guarantees exactly-once execution.
Track received, complete, valid and applied separately

These states form an application-owned reference model. A request receipt is followed by a known remote run, result collection and business validation. Valid records may produce a permitted action. Ambiguous submissions and failed destination acknowledgments stay visible for reconciliation. Do not count them as success or retry them silently.
On smaller screens, scroll to compare all columns.
| State | What it establishes | What it does not establish |
|---|---|---|
| Received | The application durably stored the original event. | Clay accepted it. |
| Accepted | A recorded run ID connects the job to remote execution. | Every item will succeed. |
| Completed and collected | Remote completion is observed and all result pages were retrieved. | Every item succeeded or meets the business policy. |
| Validated | The result satisfies identity, evidence and field rules. | The destination applied it. |
| Approved | The proposed action passes the current destination and ownership policy. | The destination applied it. |
| Applied | The destination receipt and state confirm the permitted action. | A commercial outcome occurred. |
| Needs reconciliation | The outcome is uncertain and has an accountable owner. | The job failed safely or should be relaunched. |
This vocabulary prevents inflated reporting. A research run can finish successfully without producing a contactable person. A useful brief can be accepted without changing the CRM. A CRM task can be created without a salesperson using it. Report the stage you observed and state how many records the count is out of.
Follow one record through receipts and review
Consider event demo-request-1042. The receiver stores its service request and company record ID. A repeated source delivery finds the same event receipt. The system submits one item to the chosen function and associates the returned run with that receipt.
The result supplies a matched domain and a research note, but its evidence observation falls outside the example policy’s freshness window. The integration holds the proposed CRM update. A reviewer may refresh the evidence, accept a narrower brief or close the job. None of those decisions requires pretending that enrichment failed.

The workflow tracks four identities: the event that justified work, the remote run that executed it, the item that ties a result to a record, and the action whose destination state must be verified. Keep those relationships even when validation produces a hold. In this case, stale evidence produces a review hold and no action key is dispatched.
{
"event_id": "demo-request-1042",
"caller_item_id": "demo-request-1042",
"routine_run_id": "run_SYNTHETIC_1042",
"result_collection": "complete",
"item_outcome": "complete",
"validation": {
"decision": "review_hold",
"reason": "evidence_outside_policy_window"
},
"destination_action": "none",
"policy_version": "inbound-review-v1"
}These receipt fields belong to the reference application. Keep the original remote result separately with controlled access. The operational summary should contain enough information to diagnose the hold without copying personal records into logs.
Now change the scenario. Evidence is current, identity matches and a brief is approved. The CRM worker reads the current company record and finds an established owner. It attaches the permitted brief while preserving ownership. That is the policy’s successful result. Assigning a different rep would be a defect even if the API accepted the change.
Finally, suppose the destination accepts the attachment but the worker loses the acknowledgment. The application marks the action uncertain and checks the destination before retrying. It does not rerun Clay research to solve a CRM receipt problem. Keeping those boundaries separate saves investigation time and prevents uncertainty from spreading upstream.
Specify failure paths before increasing volume
Clay’s Public API uses HTTP status codes as error categories and human-readable message fields. It does not document stable error codes in the response body. Authentication, missing-resource, validation and rate-limit failures require different handling; server errors are retryable only when the request is safe to repeat. See the error guide.
The matrix below is a test specification: it defines expected behavior for a reference implementation.
On smaller screens, scroll to compare all columns.
| Test case | Expected behavior | Acceptance evidence |
|---|---|---|
| Same event delivered twice | Reuse the event receipt; do not launch again. | One logical job and one remote launch. |
| Submission times out without run ID | Hold the event as an unknown submission. Block automatic replacement and assign reconciliation. | No automatic relaunch. Record an authoritative run match or a manual decision that acknowledges duplicate work and spend may occur. |
| Results still processing | Wait within the polling policy; apply nothing. | Progress recorded; no action receipt. |
| Mixed item success and failure | Separate item outcomes and repair only eligible failures. | No whole-cohort success flag. |
| Completion delivered twice | Collect or apply once for the logical job. | Repeated valid receipt is harmless. |
| Invalid notification signature | Reject without trusting the payload. | No business action from the message. |
| Notification absent | Retrieve the recorded run through fallback polling. | Result discovered without a new launch. |
| Results include another cursor | Retrieve all pages and join by caller item ID. | Expected item set reconciles. |
| Schema mismatch or stale evidence | Hold the item with a specific reason. | No unapproved write. |
| Authentication failure | Stop and route to the credential owner. | No repeated unchanged requests. |
| Destination acknowledgment lost | Inspect destination state before repeating the action. | One permitted change, verified later. |
Test both the typical path and the uncertain path. A sandbox record that always succeeds will not reveal duplicate deliveries, missing callbacks or ownership conflicts. Choose test cases that each exercise a different policy boundary.
Measure cost per usable decision
Clay separates Actions from Data Credits. HTTP API calls, external enrichment, AI and external exports use Actions; imports and formulas have different treatment. Using your own provider key avoids the relevant marketplace Data Credit charge but still consumes Actions, with provider costs billed separately. Confirm actual charges in the product. Clay’s usage guide explains the meters.
The API and CLI guide also says developer-platform credit budgets are not yet available. Do not represent your application’s cohort cap as a native Clay budget. Track accepted work and observed usage in the application, and check the current budget limitations before planning unattended execution.
An original planning model can divide a cohort into accepted inputs, researched items, valid outputs and applied actions. Track each stage’s cost and the count it is measured out of. Define a usable decision before running the cohort. For inbound qualification, it could be a reviewed brief that identifies fit and an accountable next step, including a justified hold.
total_cost = Clay_cost + external_provider_cost
+ infrastructure_cost + review_cost
cost_per_usable_decision = total_cost / usable_decisions
validation_yield = valid_outputs / collected_items
application_yield = confirmed_actions / approved_actions
unknown_outcome_rate = unresolved_jobs / accepted_inputsWhen the count a ratio is divided by is zero, report the raw counts and mark the ratio as undefined. Zero approved actions cannot produce a meaningful application yield, and zero usable decisions cannot produce a useful cost-per-decision figure. Keep the spend visible; do not hide it behind a zero or an invented substitute.
For illustration, take a fictional cohort of 100 accepted inputs. Suppose 70 meet the research gate, 50 produce reviewable output and 40 receive an approved next step. If its entire modeled cost were €200, cost per approved next step would be €5. Those numbers are invented for the arithmetic and do not reflect Clay pricing or coverage.
The model shows why eliminating a cheap first-stage check can be a false saving. It may send more irrelevant records to expensive research and review. Conversely, a strict gate can reject valuable unknowns. Compare rejection reasons and sample the held cohort before treating lower spend as better performance.
Track repeated-event prevention, item-level failure reasons, polling recoveries, stale evidence, manual review time and unresolved destination actions. Measure median and upper-tail time separately for research completion and applied action. Link later qualified inquiries to these records only when your measurement system supports that association. A completed run measures research activity; pipeline and revenue need their own evidence.
Release one bounded use case, then reconcile it
Start in observation mode: accept a selected event set, collect results and show proposed decisions without writing them automatically. Review disagreements with the person who owns the process. Fix the contract or policy before introducing another model, provider or enrichment stage.
Next, permit a narrow action such as attaching an approved research brief. Define who owns exceptions and how long unresolved jobs can remain unreviewed. Record the version of the function and application policy used for each release to the extent the product surface exposes it. If a provider or prompt changes, recheck the output contract, including the JSON keys and evidence quality.
Reconciliation should compare original inputs, remote runs, collected items, validation decisions and destination receipts. Give every missing item a reason, investigate duplicate actions and assign each review hold an owner. Keep a path to stop new submissions without deleting the history needed to explain work already performed.
If n8n coordinates the queue or CRM handoff, its execution log becomes another receipt to join with the event and Clay run. The n8n and HubSpot integration guide covers that destination boundary. Choose one system to own retry and reconciliation for each action so two overlapping automations do not both “repair” the same job.
Limits of this reference design
Clay’s developer platform separates execution and data access from its evolving workflow-building surface. Developer docs describe Workflows as Alpha; University materials describe open beta. Evaluate the documented custom-function execution route and the newer workflow-building surface separately in your workspace. See the execution model and University workflow documentation.
This reference does not guarantee API entitlement, fixed quotas, webhook delivery, automatic refunding, native submission idempotency or an exact provider retry schedule. It does not establish that a model found accurate evidence, that a person may be contacted or that a CRM update generated business value. Validate those questions in their own systems.
Sources: the linked Clay documentation, as of 12 October 2026.
For an implementation review, explore AGI Technologies’ Clay and HubSpot consulting scope or send an inquiry describing the trigger, volume, intended output and destination. A scoped review can identify the integration surface, data contracts and acceptance cases before a larger build.
Reviewed by Andrii Gorbenko, founder of AGI Technologies


