CONNECT APP
Build with Ironclad
Business Management
- OAuth
MCP
Give your agent Ironclad tools
Every Ironclad action is exposed as an MCP tool on Pipedream's remote server. Point a client at it with your end user's ID and Connect resolves that user's Ironclad account for each tool call — you store no tokens.
// accessToken: mint a short-lived token with the Connect SDK — see the MCP guide
const transport = new StreamableHTTPClientTransport(
new URL("https://remote.mcp.pipedream.net/v3"),
{
requestInit: {
headers: {
Authorization: `Bearer ${accessToken}`,
"x-pd-project-id": "{project_id}",
"x-pd-environment": "production",
"x-pd-external-user-id": "{external_user_id}", // any stable ID for this user in your system
"x-pd-app-slug": "ironclad",
},
},
},
)
const mcp = new Client({ name: "my-agent", version: "1.0.0" })
await mcp.connect(transport)
const { tools } = await mcp.listTools()
// e.g. run Create Record:
const result = await mcp.callTool({
name: "ironclad-create-record",
arguments: {
recordName: "Name",
recordType: "Type",
},
})# access_token: mint a short-lived token with the Connect SDK — see the MCP guide
headers = {
"Authorization": f"Bearer {access_token}",
"x-pd-project-id": "{project_id}",
"x-pd-environment": "production",
"x-pd-external-user-id": "{external_user_id}", # any stable ID for this user in your system
"x-pd-app-slug": "ironclad",
}
async with streamablehttp_client("https://remote.mcp.pipedream.net/v3", headers=headers) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
tools = await session.list_tools()
# e.g. run Create Record:
result = await session.call_tool("ironclad-create-record", {
"recordName": "Name",
"recordType": "Type",
})API PROXY
Call the Ironclad API directly
For an endpoint with no pre-built tool, the Connect proxy forwards your request to the Ironclad API with the connected user's credentials attached. You store no tokens and write no refresh logic.
const resp = await pd.proxy.get({
externalUserId: "{external_user_id}", // any stable ID for this user in your system
accountId: "apn_xxxxxxx",
url: "https://ironcladapp.com/public/api/v1/records",
})
// Any allowed Ironclad endpoint works here. Pipedream attaches the
// connected account's credentials to the outgoing request.# The path segment is the target URL, URL-safe base64 encoded:
# https://ironcladapp.com/public/api/v1/records
curl "https://api.pipedream.com/v1/connect/{project_id}/proxy/aHR0cHM6Ly9pcm9uY2xhZGFwcC5jb20vcHVibGljL2FwaS92MS9yZWNvcmRz?external_user_id={external_user_id}&account_id=apn_xxxxxxx" \
-H "Authorization: Bearer {access_token}" \
-H "x-pd-environment: production"SDK
Run Ironclad actions from your backend
Connect a user's Ironclad account once, then run Create Record on their behalf from your own code — TypeScript, Python, or plain HTTP.
import { PipedreamClient } from "@pipedream/sdk"
const pd = new PipedreamClient({
projectId: process.env.PIPEDREAM_PROJECT_ID!,
clientId: process.env.PIPEDREAM_CLIENT_ID!,
clientSecret: process.env.PIPEDREAM_CLIENT_SECRET!,
projectEnvironment: "production",
})
const result = await pd.actions.run({
id: "ironclad-create-record",
externalUserId: "{external_user_id}", // any stable ID for this user in your system
configuredProps: {
ironclad: { authProvisionId: "apn_xxxxxxx" },
recordName: "Name",
recordType: "Type",
},
})from pipedream import Pipedream
pd = Pipedream(
client_id="{oauth_client_id}",
client_secret="{oauth_client_secret}",
project_id="{project_id}",
project_environment="production",
)
result = pd.actions.run(
id="ironclad-create-record",
external_user_id="{external_user_id}", # any stable ID for this user in your system
configured_props={
"ironclad": {"authProvisionId": "apn_xxxxxxx"},
"recordName": "Name",
"recordType": "Type",
},
)curl -X POST https://api.pipedream.com/v1/connect/{project_id}/actions/run \
-H "Content-Type: application/json" \
-H "X-PD-Environment: production" \
-H "Authorization: Bearer {access_token}" \
-d '{
"external_user_id": "{external_user_id}",
"id": "ironclad-create-record",
"configured_props": {
"ironclad": { "authProvisionId": "apn_xxxxxxx" },
"recordName": "Name",
"recordType": "Type"
}
}'TOOLS
Ironclad actions
On-demand operations your product or agent can configure and run on behalf of a connected user.
-
Create Record
actionCreates a new record in Ironclad. Providepropertiesas a JSON object where each key maps to a{type, value}wrapper. Run Describe Workspace first to see all valid record types and property keys (with their requiredtype) in one call; List Type Options / List Properties Options exist only to resolve a single value for this action's props, not for general discovery. Property types are snake_case, e.g.string,number,monetary_amount,address,date,duration,boolean— not the camelCase types used by workflow attributes. Complex types use nested objects:monetary_amount{"currency": "USD", "amount": 25.37},address{"lines": ["325 5th Street", "Suite 200"], "locality": "San Francisco", "region": "California", "postcode": "94107", "country": "USA"}. Example: setrecordNameto"Acme NDA",recordTypeto"vendor_agreement", andpropertiesto{"counterpartyName": {"type": "string", "value": "Acme Corp"}, "contractValue": {"type": "monetary_amount", "value": {"currency": "USD", "amount": 50000}}}; returns{"id": "rec_abc123", "name": "Acme NDA"}. See the documentationWritev1.0.1 -
Delete Record
actionPermanently deletes an Ironclad record by ID. This cannot be undone. Run Search Records first to find therecordId— confirm it's the right record before deleting, since Ironclad has no undo. Example: setrecordIdto"rec_abc123"to delete that record; the action confirms deletion succeeded. See the documentationWritev0.0.2 -
Describe Workflow Template
actionRetrieves the fillable attribute schema for an Ironclad workflow template — the required call before Launch Workflow. Returns each field's type, display name, enum options, and whether it's required. Every field'sdescriptionalready includes a worked value-format example for complex types (address,monetaryAmount,date,duration,document/array) — use those examples verbatim, do not guess a shape. A field'srequiredmay be"conditional": when Ironclad's naming convention makes the trigger inferable (e.g. a field namedset1Question2triggered by a selector field set to"Set 1"), adependsOn: {field, value}hint is included; whenever you set the selector to that value, also include the dependent field. If a conditional field has nodependsOnhint, its trigger isn't inferable from naming — watch for aMISSING_PARAMerror naming it after you submit Launch Workflow, and retry with it included. Run Describe Workspace first to find a template ID. Example: settemplateIdto"tmpl_abc123"to retrieve a schema where each field looks like{"counterpartyName": {"type": "string", "displayName": "Counterparty Name", "required": "always", "description": "Value of Counterparty Name"}, "requiredAddress": {"type": "address", "displayName": "Required Address", "required": "always", "description": "Value of Required Address. Example: {\"lines\": [...], \"locality\": ..., \"region\": ..., \"postcode\": ..., \"country\": ...}"}}. See the documentationRead-onlyv0.0.2 -
Describe Workspace
actionOrients you to this Ironclad workspace: returns every configured record type and property (with its type), plus the first page of launchable workflow templates. This is the primary orienting call — run it first for any question about what record types, properties, or workflow templates exist in the workspace, before List Type Options / List Properties Options / List Template ID Options (those three exist only to resolve one value while configuring another tool's prop, not for general discovery — using them for discovery skips the bundled context this tool provides). Takes no parameters. IfworkflowTemplateslooks capped at a page boundary, run List Template ID Options with an incrementedpagefor the rest. Example return:{"recordTypes": {"vendor_agreement": "Vendor Agreement"}, "properties": {"contractValue": "monetary_amount", "counterpartyName": "string"}, "workflowTemplates": [{"id": "tmpl_abc123", "name": "NDA Template"}]}. See the documentationRead-onlyv0.0.2 -
Get Record
actionRetrieves a single Ironclad record by its ID, returning the record's name, type, properties, and metadata. Run Search Records first to find a valid record ID. Example: setrecordIdto"rec_abc123"to retrieve a record with fields such asid,name,type, andproperties. See the documentationRead-onlyv0.0.2 -
Get Workflow
actionRetrieves the full Ironclad workflow object, including its schema and current attribute keys and types. Use the returned schema to construct a validupdatespayload for Update Workflow Attributes. Run Search Workflows first to find a workflow ID. Example: setworkflowIdto"wf_xyz789"to retrieve a workflow with fields such asid,title,status,currentStep, andattributes(a map of attribute key → value). Use the optionalfieldsparam (e.g."id,title,status") to return only specific top-level keys. See the documentationRead-onlyv0.0.2 -
Launch Workflow
actionLaunches a new workflow in Ironclad. Run Describe Workspace to find a template ID, then run Describe Workflow Template to discover the field keys, types, and constraints (including conditional fields) needed to build theattributespayload. Example: settemplateIdto"tmpl_abc123"andattributesto{"counterpartyName": "Acme Corp", "paperSource": "Our paper", "startDate": "2026-09-01"}; returns{"id": "wf_xyz789", "status": "review"}. See the documentationWritev1.0.1 -
List Properties Options
actionReturns all Ironclad record property keys and their display names (including the requiredtypefor each) as{label, value}pairs. Call this before setting thepropertiesfield in Create Record to find valid property keys and their exact type — do not guess a property's type. Example return:[{"label": "Counterparty Name (type: string)", "value": "counterpartyName"}, {"label": "Contract Value (type: monetary_amount)", "value": "contractValue"}, ...]. See the documentationRead-onlyv0.0.3 -
List Record ID Options
actionReturns one page of Ironclad records as{label, value}pairs (wherevalueis the record ID). Call this before using thelinks,parent, orchildrenfields in Create Record to find valid record IDs. Search Records is the primary way to find a record by attribute values; use this action only to page through the full list or when resolving a record ID field directly. Results are 0-indexed by page; if the response contains the maximum number of items, incrementpageand call again to fetch more. Example return:[{"label": "Acme NDA", "value": "rec_abc123"}, ...]. See the documentationRead-onlyv0.0.3 -
List Selected Events Options
actionReturns all Ironclad webhook event type names as{label, value}pairs. Call this to discover valid event types before configuring an Ironclad event source. Example return:[{"label": "WORKFLOW LAUNCHED", "value": "workflow_launched"}, {"label": "WORKFLOW UPDATED", "value": "workflow_updated"}, ...]. See the documentationRead-onlyv0.0.3 -
List Template ID Options
actionReturns Ironclad workflow template IDs and their display names as{label, value}pairs. Call this before running Launch Workflow or Describe Workflow Template to find a validtemplateId. Results are 0-indexed by page; if the response contains the maximum number of items, incrementpageand call again to fetch more. Example return:[{"label": "NDA Template", "value": "tmpl_abc123"}, {"label": "Vendor Agreement", "value": "tmpl_xyz789"}, ...]. See the documentationRead-onlyv0.1.1 -
List Type Options
actionReturns all Ironclad record type keys and their display names as{label, value}pairs (wherevalueis the type key). Call this before setting thetypefield in Create Record to find valid type keys. Example return:[{"label": "Vendor Agreement", "value": "vendor_agreement"}, {"label": "NDA", "value": "nda"}, ...]. See the documentationRead-onlyv0.0.3 -
List Workflow ID Options
actionReturns one page of Ironclad workflows as{label, value}pairs (wherevalueis the workflow ID). Call this before running Get Workflow or Update Workflow Attributes to find a validworkflowId. Search Workflows is the primary way to find a workflow by attribute values; use this action only to page through the full list or when resolving theworkflowIdprop directly. Results are 0-indexed by page; if the response contains the maximum number of items, incrementpageand call again to fetch more. Example return:[{"label": "Acme NDA Review", "value": "wf_xyz789"}, ...]. See the documentationRead-onlyv0.0.3 -
Search Records
actionSearches Ironclad repository records using structured filters and/or Ironclad's native formula filter language. Use this to find a record's ID before Get Record, Update Record, or Delete Record. Thefilterformula operates on property keys in[brackets]— run Describe Workspace first to see valid property keys. Formula operators:Equals([prop], 'value'),NotEqual([prop], 'value'),Contains([prop], 'value'),IsEmpty([prop]),IsNotEmpty([prop]),LessThan([prop], value)/LessThanOrEqual([prop], value),GreaterThan([prop], value)/GreaterThanOrEqual([prop], value),Date(2026, 1, 1)(year, month, day),Today(),RelativeDate(Today(), -7, 'days')(anchor -Today()orDate(...)-, offset, unit; unit is one ofdays,weeks,months,years),And(cond1, cond2, ...),Or(cond1, cond2, ...). String values support both single and double quotes. Worked examples: find by nameContains([name], 'Hammond'); find records with an agreement date in the last 30 daysGreaterThan([agreementDate], RelativeDate(Today(), -30, 'days')); find records missing a contract valueIsEmpty([contractValue]). Record type is not a formula-filterable property — to find vendor agreements or NDAs, set thetypesprop tovendor_agreement,ndainstead of usingfilter. Example: setfiltertoContains([name], 'Hammond')to find a record by name; returns{"list": [{"id": "rec_abc123", "name": "Hammond Foundation NDA", "type": "nda"}], "count": 1}. See the documentationRead-onlyv0.0.2 -
Search Workflows
actionSearches Ironclad workflows using structured filters and/or Ironclad's native formula filter language. Use this to find a workflow's ID before Get Workflow or Update Workflow Attributes. Thefilterformula operates on attribute keys in[brackets]— run Describe Workspace first to see valid attribute keys. Formula operators:Equals([attr], 'value'),NotEqual([attr], 'value'),Contains([attr], 'value'),IsEmpty([attr]),IsNotEmpty([attr]),LessThan([attr], value)/LessThanOrEqual([attr], value),GreaterThan([attr], value)/GreaterThanOrEqual([attr], value),Date(2026, 1, 1)(year, month, day),Today(),RelativeDate(Today(), -7, 'days')(anchor -Today()orDate(...)-, offset, unit; unit is one ofdays,weeks,months,years),And(cond1, cond2, ...),Or(cond1, cond2, ...). String values support both single and double quotes. Worked examples: find by counterparty nameContains([counterpartyName], 'Acme'); find workflows with an agreement date in the last weekGreaterThan([agreementDate], RelativeDate(Today(), -7, 'days')); find workflows missing a signed copyIsEmpty([signedCopy]). Status and template are not formula-filterable properties — to find cancelled or completed workflows, set thestatusprop tocancelled,completed; to find workflows launched from a specific template, set thetemplateprop instead of usingfilter. Example: setstatusto"active"andpageSizeto5to retrieve the 5 most recently updated active workflows; returns{"list": [{"id": "wf_xyz789", "title": "Acme NDA", "status": "active"}], "count": 1}. See the documentationRead-onlyv0.0.2 -
Update Record
actionUpdates properties on an existing Ironclad record. Providepropertiesas a JSON object where each key maps to a{type, value}wrapper — the same shape as Create Record. Run Search Records first to find therecordId, and Describe Workspace to discover valid property keys and their exact requiredtype(record property types are snake_case, e.g.string,number,monetary_amount,address,date,duration,boolean— do not guess). Only the properties you include are changed; omitted properties are left as-is. Example: setrecordIdto"rec_abc123"andpropertiesto{"contractValue": {"type": "monetary_amount", "value": {"currency": "USD", "amount": 75000}}}; returns the updated record. See the documentationWritev0.0.2 -
Update Workflow Attributes
actionUpdates attribute values on an in-flight Ironclad workflow. The workflow must be in the Review step; document/file-type attributes are not supported. Provideupdatesas a flat JSON object of attribute key to new value — each pair is converted to Ironclad's internal{action: "set", path, value}update format automatically. Run Search Workflows or Get Workflow first to find theworkflowId, then run Get Workflow to see current attribute keys and values, or Describe Workflow Template for the attribute format reference (complex types likemonetaryAmount,address,date,duration). Example: setworkflowIdto"wf_xyz789"andupdatesto{"contractValue": {"currency": "USD", "amount": 75000}, "renewalDate": "2027-01-01"}; the action confirms the update was applied. See the documentationWritev1.0.1
EVENTS
Ironclad triggers
Event sources your backend can deploy for users and receive through a webhook.
-
New Approval Event Instant
triggerEmit new event when a fresh approval event is generated.Instantv0.0.2 -
New Workflow Document Event (Instant)
triggerEmit new event when a workflow document event is freshly established.Instantv0.0.2 -
New Workflow Event (Instant)
triggerEmit new event when a new workflow event is created.Instantv0.0.2
MULTI-APP
Use Ironclad with other popular apps
Most products don't stop at one integration. Pair Ironclad with the other apps your users rely on, and ship use cases that span both.
- App slug
- ironclad
- Authentication
- OAuth
- Categories
- Business Management
- Actions
- 17
- Triggers
- 3
- API proxy
- Available
OAuth scopes
These are the scopes Pipedream's managed Ironclad OAuth client requests when one of your users connects an account. Supply your own OAuth client to request a different set.
- scim.users.readUsers
- public.workflows.readWorkflows
- public.records.readSchemas
- public.records.readRecords
- public.records.createRecords
- public.workflows.createWorkflows
- public.workflows.updateWorkflows
- public.webhooks.createWebhooks
- public.webhooks.deleteWebhooks
- public.workflows.readSchemas
- public.records.deleteRecords
- public.records.updateRecords