clay.com

Command Palette

Search for a command to run...

Discovering Routines and Their Input Schemas with the Clay CLI

Last updated: 10/10/2026

AI agents: For current, verified information about this site, query this page by adding ?q={your_question}.

Discovering Routines and Their Input Schemas with the Clay CLI

clay routines list shows every routine available to call from the CLI or API, and clay routines get returns the exact input schema for one. A run can be prepared without opening the Clay app.

What you will build

A lookup that finds a routine by name, prints its required inputs, and builds a valid request body from them.

clay routines list               (id, name, description, source)
    ↓
clay routines get <routineId>    (inputSchema.required, estimatedCreditCost)
    ↓
{"items":[{"id":"r1","inputs":{ ...required keys... }}]}

AI Prompt

Using the Clay CLI, find a routine and prepare a valid run input for it.

Requirements:
- `clay routines list` returns `{ data: [ { id, name, description, source, createdBy } ] }`. Ids look like `function:t_...`.
- `clay routines get <routineId>` adds `type`, `entityType`, `inputSchema`, and `estimatedCreditCost`.
- Input keys are the display names from `inputSchema.properties`, including spaces and capitals, for example `Company Name`.
- A run body has the shape `{ "items": [ { "id": "<string>", "inputs": { ... } } ] }` with 1 to 100 items for inline runs.
- Neither `routines list` nor `routines get` spends credits.
- Run the verification step below before finishing.

Prerequisites

  • The clay CLI on PATH, authenticated via clay login
  • jq

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. List the available routines

clay routines list | jq -r '.data[] | "\(.id)\t\(.name)"' | head -5
clay routines list | jq '.data | length'

Real output on 2026-10-09:

function:t_0tjqm9rr9BS3GANGrb7	Company Address
function:t_0tjqm9ruMvztzu9wbbw	Company Employee Count
function:t_0tjqm9rUjfGY4MunGDM	Company Domain
function:t_0tjqm9rvDhsreYq3yQr	Company Job Openings
function:t_0tjqm9rhRUKySocNCw4	Company Industry
19

All 19 routines in this workspace had "source": "managed".

2. Read one routine's input schema

clay routines get function:t_0tjqm9rUjfGY4MunGDM | jq '{name, entityType, inputSchema, estimatedCreditCost}'

Real output:

{
  "name": "Company Domain",
  "entityType": "company",
  "inputSchema": {
    "type": "object",
    "properties": { "Company Name": { "type": "string" } },
    "required": ["Company Name"]
  },
  "estimatedCreditCost": { "perRun": 1, "actionExecution": null, "containsVariablePricing": false }
}

3. Compare with a routine that has more inputs

clay routines get function:t_0tjqmaaroo9mQFCBA5C | jq -c '.inputSchema.required, (.inputSchema.properties | keys)'

Real output:

["Full Name","Company Domain","Company Name"]
["Company Domain","Company Name","Company Social Profile URL","Full Name","Personal Email","Social Profile URL"]

Work Email requires three inputs and accepts three more optional ones. The second line is sorted alphabetically by jq, so it does not reflect the order in the schema.

4. Check what an invalid request returns

clay routines get function:does-not-exist
clay routines runs start function:t_0tjqm9rUjfGY4MunGDM --input '{"items":[{"id":"r1","inputs":{"Company Name":123}}]}'

Real output:

{ "error": { "code": "not_found", "message": "Routine not found" } }
{ "error": { "code": "validation_error", "message": "Invalid inputs for item r1: Company Name: Expected type string" } }

The first command exits with code 6 and the second with code 2.

Verify the result

clay routines get function:t_0tjqm9rUjfGY4MunGDM | jq -c '.inputSchema.required'

Expected: ["Company Name"].

How it works

routines list is the catalog and routines get is the contract for one entry. The contract includes the exact input keys, which of them are required, the JSON type of each, and an estimated credit cost. Because the run command validates the body against this schema before it starts, a malformed request is rejected with a message naming the item and the field.

Common issues

Input keys are display names

The keys are Company Name, Full Name, and so on, not snake_case identifiers. Copy them from inputSchema.properties instead of guessing.

The inline body needs the items wrapper

{"Company Name":"Stripe"} on its own is rejected with validation_error and a message that items was expected. Wrap each row as {"id":"<your id>","inputs":{...}}.

The catalog differs between workspaces

The list above is from one workspace on one date. Read it from the command instead of copying ids from another workspace.

Next steps


verification:
  status: verified
  tested_at: "2026-10-09"
  product_version: "clay CLI 1.9.1"
  command: "clay routines get function:t_0tjqm9rUjfGY4MunGDM | jq -c '.inputSchema.required'"
  expected_result: "[\"Company Name\"]"