Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/conduyt-com:conduyt-com-batch-operations-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: Conduyt Batch Operations API
version: 1.0.0
description: 'The Conduyt CRM API provides programmatic access to your CRM data including
contacts, companies, deals, pipelines, tasks, notes, automations, invoices,
email sequences, and more.
## Authentication
All authenticated endpoints require a Bearer token (API key) in the
`Authorization` header:
```
Authorization: Bearer cdy_
```
API keys are generated in **Settings > API Keys** within the Conduyt
dashboard. Keys use the `cdy_` prefix and are hashed with bcrypt on
creation — the full key is shown exactly once at creation time.
Session cookie authentication (`conduyt_session`) is also supported for
browser-based clients but is not recommended for integrations.
## Rate Limiting
API keys enforce a per-key rate limit. New keys default to 100 requests per
minute and can be configured at creation time or with PATCH `/api-keys/{id}`.
Some public and provider-facing endpoints also enforce stricter per-IP or
per-account limits. When exceeded, the API returns `429 Too Many Requests`
with a `Retry-After` header indicating seconds until the next allowed
request.
| Endpoint Group | Limit |
|---------------------|---------------------|
| API keys | Default 100 / min per key |
| Login/reset | 5 / min per IP |
| Registration | 3 / hour per IP |
| Contact/Deal create | 30 / min per IP |
| Inbound messages | 120 / min per account/IP |
## Pagination
List endpoints support cursor-based pagination via query parameters:
- `page` — Page number (default: 1)
- `per_page` — Items per page (default: 50, max: 200)
- `limit` — Accepted as an alias of `per_page` on `GET /contacts`; if both are
sent they must carry the same value.
A page size above the maximum, a non-integer, a value below 1, or a
pagination key repeated with different values is rejected with `400`
(the message names the parameter and the rule); nothing is silently
clamped or ignored.
Responses include a `meta` object: `{ page, per_page, total }`.
An operation that documents its own pagination rules follows those instead.
`GET /sms-providers/options` pages with an opaque `cursor` and a `limit`
that is capped at 50 rather than rejected; its responses carry
`meta: { nextCursor, truncated }`.
## Response Format
All successful responses wrap data in a `data` envelope:
```json
{ "data": { ... } }
```
Error responses use:
```json
{ "error": "Human-readable error message" }
```
## Multi-Tenancy
Conduyt is multi-tenant. All data is scoped to the authenticated user''s
current account. API keys are bound to a specific account at creation time.
## Webhook Events
Outbound webhooks fire on events including:
`contact.created`, `contact.updated`, `contact.deleted`,
`deal.created`, `deal.updated`, `deal.won`, `deal.lost`,
`task.created`, `task.completed`, `note.created`,
`appointment.created`, `appointment.updated`,
`form.submitted`, `invoice.paid`
Payloads are signed with HMAC-SHA256 using the webhook''s secret. Retry
schedule: 1m, 5m, 30m, 2h, 12h, 72h (7 total attempts including the initial delivery).'
contact:
name: Conduyt Support
url: https://conduyt.app
email: support@conduyt.app
license:
name: Proprietary
url: https://conduyt.app/terms
servers:
- url: https://conduyt.app/api/v1
description: Production
security:
- BearerAuth: []
tags:
- name: Batch Operations
paths:
/batch-operations/{id}/cancel:
post:
x-generated: true
operationId: postBatchOperationsIdCancel
summary: Create / invoke batch-operations id cancel
tags:
- Batch Operations
parameters:
- name: id
in: path
required: true
schema:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
id: {}
status: {}
processedCount: {}
totalContacts: {}
required:
- id
- status
- processedCount
- totalContacts
required:
- data
/batch-operations/{id}:
get:
x-generated: true
operationId: getBatchOperationsId
summary: Get batch-operations id
tags:
- Batch Operations
parameters:
- name: id
in: path
required: true
schema:
type: string
- name: itemStatus
in: query
required: false
description: Query parameter read by this route.
schema:
type: string
- name: limit
in: query
required: false
description: Query parameter read by this route.
schema:
type: integer
default: 20
minimum: 1
maximum: 50
x-default-provenance: handler_literal
- name: page
in: query
required: false
description: Query parameter read by this route.
schema:
type: integer
default: 1
minimum: 1
x-default-provenance: handler_literal
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
batch: {}
items: {}
itemTotal: {}
itemPage: {}
itemPageSize: {}
required:
- batch
- items
- itemTotal
- itemPage
- itemPageSize
required:
- data
/batch-operations:
get:
x-generated: true
operationId: getBatchOperations
summary: List batch-operations
tags:
- Batch Operations
parameters:
- name: createdBy
in: query
required: false
description: Query parameter read by this route.
schema:
type: string
- name: limit
in: query
required: false
description: Query parameter read by this route.
schema:
type: integer
default: 20
minimum: 1
maximum: 50
x-default-provenance: handler_literal
- name: page
in: query
required: false
description: Query parameter read by this route.
schema:
type: integer
default: 1
minimum: 1
x-default-provenance: handler_literal
- name: status
in: query
required: false
description: Query parameter read by this route.
schema:
type: string
responses:
'200':
description: Success
content:
application/json:
schema:
type: object
properties:
data:
type: array
items: {}
meta:
type: object
properties:
page:
type: integer
perPage:
type: integer
total:
type: integer
totalPages:
type: integer
required:
- page
- perPage
- total
- totalPages
required:
- data
- meta
post:
x-generated: true
operationId: postBatchOperations
summary: Create / invoke batch-operations
tags:
- Batch Operations
requestBody:
required: true
content:
application/json:
schema:
type: object
oneOf:
- properties:
operation:
const: enroll
params:
type: object
properties: {}
additionalProperties: false
description: 'For assign: exactly one of userId (one rep) or userIds (a round-robin pool), and userIds must not repeat a rep; otherwise a 400 naming the parameter.'
- properties:
operation:
const: delete
params:
type: object
properties: {}
additionalProperties: false
description: 'For assign: exactly one of userId (one rep) or userIds (a round-robin pool), and userIds must not repeat a rep; otherwise a 400 naming the parameter.'
required:
- operation
- properties:
operation:
const: add_tag
params:
type: object
properties:
tagId:
type: string
format: uuid
pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
required:
- tagId
additionalProperties: false
description: 'For assign: exactly one of userId (one rep) or userIds (a round-robin pool), and userIds must not repeat a rep; otherwise a 400 naming the parameter.'
required:
- operation
- params
- properties:
operation:
const: remove_tag
params:
type: object
properties:
tagId:
type: string
format: uuid
pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
required:
- tagId
additionalProperties: false
description: 'For assign: exactly one of userId (one rep) or userIds (a round-robin pool), and userIds must not repeat a rep; otherwise a 400 naming the parameter.'
required:
- operation
- params
- properties:
operation:
const: assign
params:
type: object
properties:
userId:
type: string
format: uuid
pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
userIds:
minItems: 2
maxItems: 50
type: array
items:
type: string
format: uuid
pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
additionalProperties: false
description: 'For assign: exactly one of userId (one rep) or userIds (a round-robin pool), and userIds must not repeat a rep; otherwise a 400 naming the parameter.'
required:
- operation
- params
- properties:
operation:
const: set_source
params:
type: object
properties:
source:
type: string
minLength: 1
maxLength: 120
description: Leading and trailing whitespace is trimmed before the length check, so a blank value is refused.
required:
- source
additionalProperties: false
description: 'For assign: exactly one of userId (one rep) or userIds (a round-robin pool), and userIds must not repeat a rep; otherwise a 400 naming the parameter.'
required:
- operation
- params
- properties:
operation:
const: set_status
params:
type: object
properties:
status:
type: string
minLength: 1
maxLength: 60
description: Leading and trailing whitespace is trimmed before the length check, so a blank value is refused.
required:
- status
additionalProperties: false
description: 'For assign: exactly one of userId (one rep) or userIds (a round-robin pool), and userIds must not repeat a rep; otherwise a 400 naming the parameter.'
required:
- operation
- params
required:
- name
properties:
name:
type: string
minLength: 1
maxLength: 256
operation:
default: enroll
type: string
enum:
- enroll
- delete
- add_tag
- remove_tag
- assign
- set_source
- set_status
automationId:
type: string
format: uuid
pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
params:
type: object
additionalProperties: {}
description: 'For assign: exactly one of userId (one rep) or userIds (a round-robin pool), and userIds must not repeat a rep; otherwise a 400 naming the parameter.'
comment:
type: string
maxLength: 2000
contactIds:
minItems: 1
maxItems: 50000
type: array
items:
type: string
format: uuid
pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
filterPayload:
minItems: 1
type: array
items:
type: object
additionalProperties: {}
anyOf:
- type: object
properties:
conjunction:
description: Read by the handler from the JSON body (the route declares no schema for its type).
field:
description: Read by the handler from the JSON body (the route declares no schema for its type).
operator:
description: Read by the handler from the JSON body (the route declares no schema for its type).
rules:
anyOf:
- type: array
items:
anyOf:
- type: object
properties:
field:
description: Read by the handler from the JSON body (the route declares no schema for its type).
operator:
description: Read by the handler from the JSON body (the route declares no schema for its type).
value:
description: Read by the handler from the JSON body (the route declares no schema for its type).
description: Read by the handler from the JSON body (the route declares no schema for its type).
- {}
description: Read by the handler from the JSON body (the route declares no schema for its type).
- {}
value:
description: Read by the handler from the JSON body (the route declares no schema for its type).
description: Read by the handler from the JSON body (the route declares no schema for its type).
- {}
filter:
type: object
additionalProperties: {}
description: The contacts-list filter (the same filter keys GET /contacts reads, including the compact cf, as strings or arrays of strings). A blank plain string of a key other than email is ignored; an empty array, or an array with any blank entry, under any non-email key (and an empty array under email) is 400 invalid_filter naming the key. Every supplied key must match its exact grammar (UUIDs, enums, ISO dates with a valid range, digits-only positive min_score, a non-empty valid JSON array for filters, one value for single-valued keys) or the request is 400 invalid_filter naming the key; a smart_view, smartListId or filters payload that names an audience with no conditions, or contains a negative clause on a closed account domain (tags by literal case-insensitive name, pipeline, pipeline stage, assignee, deal status, master status, appointment status) whose referent does not exist, or a rule or group with an unknown property, or an optedOutSms / optedOutEmail value other than exactly true or false, or a contains / equals / is clause on a case-insensitively compared field (email, phone, company, city, state, country, jobTitle) or a search / company value holding the wildcard characters % or _, or a rule the ordinary rule validators refuse, is 400 invalid_filter (the legacy filterPayload of POST /batch-operations follows the same strict contract); two keys naming the same custom field (cf[tier] and cf[ tier ], or the compact cf) are 400; the contacts list itself stays lenient; at least one non-blank value is required.
expectedTotal:
type: integer
exclusiveMinimum: 0
maximum: 9007199254740991
description: 'With filter: the count the list showed for it; a different count is refused and nothing is frozen.'
description: 'Conditional request requirements: Provide exactly one of contactIds, filterPayload or filter; automationId is required to enroll; automationId only applies to enroll; filter and expectedTotal go together; filterPayload is for enroll only; other tasks use filter + expectedTotal or contactIds. Flat requiredFields are intentionally omitted; read endpoint notes/description and validation errors for valid field combinations. Rules the route enforces: Provide exactly one of contactIds, filterPayload or filter automationId is required to enroll automationId only applies to enroll filter and expectedTotal go together filterPayload is for enroll only; other tasks use filter + expectedTotal or contactIds Exactly one of contactIds, filterPayload or filter is required; filter and expectedTotal go together; enroll (the default operation) requires automationId and every other operation refuses it; filterPayload is for enroll only.'
responses:
'201':
description: Created
content:
application/json:
schema:
type: object
properties:
data:
type: object
properties:
id: {}
name: {}
operation: {}
params: {}
comment: {}
status: {}
totalContacts: {}
required:
- id
- name
- operation
- params
- comment
- status
- totalContacts
required:
- data
components:
securitySchemes:
BearerAuth:
type: http
scheme: bearer
description: 'API key authentication. Generate keys in Settings > API Keys.
Keys use the `cdy_` prefix.
Example: `Authorization: Bearer cdy_a1b2c3d4e5f6...`
'
x-mcp:
transport:
- stdio
- http
orchestration: code
endpoint_tools: hidden