Conduyt Pipelines API

Sales pipeline and stage management

Operations 14

GET /pipelines List pipelines with stages #
POST /pipelines Create a pipeline #
POST /pipelines/reorder Reorder the pipelines (board menu order), atomically #
GET /pipelines/{id} Get a pipeline by ID #
PATCH /pipelines/{id} Update a pipeline #
DELETE /pipelines/{id} Delete a pipeline #
GET /pipelines/{id}/stages List stages for a pipeline #
POST /pipelines/{id}/stages Add a stage to a pipeline #
POST /pipelines/{id}/stages/reorder Reorder a pipeline's stages (board columns), atomically #
POST /pipelines/{id}/archive Archive a pipeline, moving its open deals, in one transaction #
POST /pipelines/{id}/restore Restore an archived pipeline #
PATCH /pipelines/{id}/stages/{stageId} Update a pipeline stage #
DELETE /pipelines/{id}/stages/{stageId} Delete a pipeline stage #
GET /pipelines/{id}/stages/{stageId} Get pipelines id stages stageId #

Work with this as data

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-pipelines-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 Specification

conduyt-com-pipelines-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Conduyt Pipelines 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: Pipelines
  description: Sales pipeline and stage management
paths:
  /pipelines:
    get:
      operationId: listPipelines
      summary: List pipelines with stages
      tags:
      - Pipelines
      responses:
        '200':
          description: All pipelines with their stages
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
      parameters:
      - name: archived
        in: query
        required: false
        description: 'true (owner or admin): list the ARCHIVED pipelines instead, as { id, name (the name before archiving), archivedName, color, archivedAt, openDeals, stageCount }, newest first, at most 200'
        schema:
          type: boolean
      - name: page
        in: query
        required: false
        description: Page number
        schema:
          type: integer
          default: 1
          minimum: 1
        x-default-provenance: handler_literal
      - name: per_page
        in: query
        required: false
        description: Items per page (max 200)
        schema:
          type: integer
          default: 50
          minimum: 1
          maximum: 100
        x-default-provenance: handler_literal
    post:
      operationId: createPipeline
      summary: Create a pipeline
      description: Requires owner or admin role. Subject to plan limits.
      tags:
      - Pipelines
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - name
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 200
                  description: Must not start with "[Archived]" (archive with DELETE); otherwise a 400.
                description:
                  anyOf:
                  - type: string
                    maxLength: 2000
                  - type: 'null'
                isDefault:
                  type: boolean
                color:
                  type: string
                  description: 'The pipeline''s colour, the dot next to its name in the board''s pipeline menu (any case accepted, stored in this spelling). Omitted: the first palette colour no active pipeline of the account uses. One of the pipeline palette colours (matched case-insensitively); any other value is refused.'
                stages:
                  maxItems: 50
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                        minLength: 1
                        maxLength: 200
                      order:
                        type: integer
                        minimum: 0
                        maximum: 9007199254740991
                      color:
                        type: string
                        maxLength: 50
                      isWon:
                        type: boolean
                      isLost:
                        type: boolean
                      isSystem:
                        type: boolean
                    required:
                    - name
                    description: Stage names must be unique (trimmed, case-insensitive), and a system holding stage cannot be won or lost; otherwise a 400. A stage cannot be both won and lost (isWon and isLost both true is refused).
      responses:
        '201':
          description: Pipeline created with stages
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '402':
          description: Trial expired
        '403':
          description: Pipeline limit reached or insufficient role
      parameters:
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
  /pipelines/reorder:
    post:
      operationId: reorderPipelines
      summary: Reorder the pipelines (board menu order), atomically
      description: Writes every active pipeline's position in ONE transaction. order must list every active pipeline id exactly once; expectedRevision is the order the caller last read (the ids by position, comma-joined, as GET /pipelines returns them). Owner / admin.
      tags:
      - Pipelines
      parameters:
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - order
              - expectedRevision
              properties:
                order:
                  type: array
                  items:
                    type: string
                    format: uuid
                  description: Every active pipeline id, in the new order
                expectedRevision:
                  type: string
                  description: The current order as the caller read it (ids comma-joined); a mismatch is a 409
      responses:
        '200':
          description: 'The canonical order and its new revision: { order, revision }'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '400':
          description: order is not a complete permutation of the active pipelines
        '409':
          description: 'order_changed: the order moved since the caller read it (revision carries the current one); nothing written'
  /pipelines/{id}:
    get:
      operationId: getPipeline
      summary: Get a pipeline by ID
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      responses:
        '200':
          description: Pipeline with stages
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '404':
          $ref: '#/components/responses/NotFound'
    patch:
      operationId: updatePipeline
      summary: Update a pipeline
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                description:
                  type: string
                automationOnly:
                  type: boolean
                  description: 'Automation-only pipeline: cards in it are moved and edited only by automations, API keys and owners / admins; a member''s edit is refused with 403 pipeline_automation_only. Owner / admin only.'
                color:
                  type: string
                  enum:
                  - '#3845C9'
                  - '#43DFF6'
                  - '#2DD6B5'
                  - '#22C58B'
                  - '#9BD13B'
                  - '#F2B544'
                  - '#F07A2F'
                  - '#E6465A'
                  - '#FD88C0'
                  - '#956EFA'
                  description: The pipeline's colour, the dot next to its name in the board's pipeline menu (any case accepted, stored in this spelling); anything else is a 400.
                sortOrder:
                  type: integer
                  minimum: 0
                  description: The pipeline's position in the board's pipeline menu (ascending). Reorder by sending each moved pipeline its new position.
                isDefault:
                  description: Read by the handler from the JSON body (the route declares no schema for its type).
      responses:
        '200':
          description: Pipeline updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '404':
          $ref: '#/components/responses/NotFound'
    delete:
      operationId: deletePipeline
      summary: Delete a pipeline
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: force
        in: query
        required: false
        description: Query parameter read by this route.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      responses:
        '200':
          description: 'Pipeline deleted, or archived ({ id, archived: true }); a pipeline another request archived first answers { id, archived: true, alreadyArchived: true } untouched'
          content:
            application/json:
              schema:
                oneOf:
                - type: object
                  properties:
                    data:
                      type: object
                      properties:
                        id: {}
                        archived:
                          type: boolean
                        alreadyArchived:
                          type: boolean
                      required:
                      - id
                      - archived
                  required:
                  - data
                - type: object
                  properties:
                    data:
                      type: object
                      properties:
                        id: {}
                        deleted:
                          type: boolean
                      required:
                      - id
                      - deleted
                  required:
                  - data
        '404':
          $ref: '#/components/responses/NotFound'
        '409':
          description: 'Refused, nothing changed: active deals without force, a live unattended-lead sweep or the DPP feed on the pipeline, or intake_target (enabled intake creates deal cards in this pipeline)'
  /pipelines/{id}/stages:
    get:
      operationId: listPipelineStages
      summary: List stages for a pipeline
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      responses:
        '200':
          description: Ordered list of stages
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
    post:
      operationId: createPipelineStage
      summary: Add a stage to a pipeline
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - name
              properties:
                name:
                  type: string
                color:
                  type: string
                isWon:
                  type: boolean
                isLost:
                  type: boolean
                isSystem:
                  description: Read by the handler from the JSON body (the route declares no schema for its type).
      responses:
        '201':
          description: Stage created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '409':
          description: 'pipeline_archived: the pipeline was archived while this request waited ("This pipeline was archived meanwhile."); nothing created'
  /pipelines/{id}/stages/reorder:
    post:
      operationId: reorderPipelineStages
      summary: Reorder a pipeline's stages (board columns), atomically
      description: Writes every stage's position in ONE transaction under the pipeline-stage lock. order must list every stage id of the pipeline exactly once and may not put a system holding stage first unless it already is; expectedRevision is the order the caller last read (stage ids by position, comma-joined). Owner / admin.
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - order
              - expectedRevision
              properties:
                order:
                  type: array
                  items:
                    type: string
                    format: uuid
                expectedRevision:
                  type: string
      responses:
        '200':
          description: 'The canonical order and its new revision: { order, revision }'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '400':
          description: Not a complete permutation, or a system holding stage moved first
        '409':
          description: 'order_changed: the order moved since the caller read it; pipeline_archived: the pipeline was archived while this request waited. Nothing written'
  /pipelines/{id}/archive:
    post:
      operationId: archivePipeline
      summary: Archive a pipeline, moving its open deals, in one transaction
      description: 'Every open deal moves to the first rep-facing stage of moveOpenDealsTo through the normal transition path (stage-entry rules, automation-only lock, stage-change activities and events, status taxonomy); won / lost deals stay in the pipeline as history; the pipeline is archived (renamed), never deleted, so it can be restored. Any refusal aborts everything: nothing moves, nothing is archived. The default pipeline is refused. Owner / admin.'
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                moveOpenDealsTo:
                  type:
                  - string
                  - 'null'
                  format: uuid
                  description: The pipeline the open deals move to; null when the pipeline has none
                expectedSettingsRevision:
                  type: string
                  description: Optional account settings revision the caller read; a mismatch is a 409 stale_settings_revision
      responses:
        '200':
          description: '{ id, archived: true, movedOpenDeals, movedTo }; when another request archived the pipeline first (before or while this one ran): { id, archived: true, alreadyArchived: true, movedOpenDeals: 0, movedTo: null }, nothing moved'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '400':
          description: The target is missing, archived, the pipeline itself, or has no rep-facing stage
        '409':
          description: 'Refused, nothing changed: open_deals (no target given), target_not_open (the target''s first rep-facing stage is won or lost), stage_requirements (a deal the target stage refuses; the message names it), archive_too_large (more than 500 open deals: move or close them in batches first), dpp_post_close (the DPP feed''s Post-Close pipeline), target_archived (the destination pipeline was archived while this request waited: choose another), intake_target (enabled intake creates deal cards in this pipeline), default_pipeline, stale_settings_revision, archive_raced, or a live unattended-lead sweep on the pipeline'
  /pipelines/{id}/restore:
    post:
      operationId: restorePipeline
      summary: Restore an archived pipeline
      description: 'Owner or admin. One transaction under the account''s pipeline-order lock: the archived pipeline gets its name back, joins the end of the active order (positions renumbered dense) and is never the default; its stages and closed deals come back with it. Counts toward the plan''s pipeline limit.'
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      responses:
        '200':
          description: The restored pipeline with its stages
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '403':
          description: PLAN_LIMIT_REACHED, or not an owner / admin
        '404':
          description: No archived pipeline with this id in the account (an active id is a 404 too)
        '409':
          description: 'name_taken: an active pipeline already has its name (any case). Rename that one first.'
  /pipelines/{id}/stages/{stageId}:
    patch:
      operationId: updatePipelineStage
      summary: Update a pipeline stage
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: stageId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - name
              properties:
                name:
                  type: string
                color:
                  type: string
                sortOrder:
                  type: integer
                isWon:
                  type: boolean
                isLost:
                  type: boolean
                isSystem:
                  description: Read by the handler from the JSON body (the route declares no schema for its type).
      responses:
        '200':
          description: Stage updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '409':
          description: 'kind_change_blocked: isWon / isLost would change while open deals occupy the stage (openDeals carries the count); move them first. An empty stage changes freely. pipeline_archived: the pipeline was archived while this request waited; nothing changed'
    delete:
      operationId: deletePipelineStage
      summary: Delete a pipeline stage
      description: 'Soft delete: the stage row is kept (so deal history, activities, audit rows and reports keep its name) and the stage disappears from every pipeline and stage list and cannot be moved into; its name may be reused by a new stage. Deleting a stage with no CURRENT deals always works, even if deals once used it (deal history never blocks). Refused (409) only while deals are currently in the stage, unless move_to names another stage of the same pipeline: then the stage''s live deals move there and the stage is deleted in one transaction (the stage only: no status change). Also refused (409) while an active automation uses the stage (an action, trigger, condition or wait-until, or the N-day sweep), while the DPP status map selects it, or while enabled intake creates deal cards in it. Appointment-outcome mappings to the stage and its stage rule are removed, as is its status metadata. A run already parked or in flight before the delete is not tracked: at the step that targets the deleted stage it fails or is skipped with a clear reason in the execution log (recovering a failed run whose frozen graph uses a deleted stage is refused with 409). There is no restore in v1.'
      tags:
      - Pipelines
      parameters:
      - $ref: '#/components/parameters/IdParam'
      - name: stageId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: dry_run
        in: query
        required: false
        description: Validate the mutation without persisting changes.
        schema:
          type: boolean
      - name: expected_settings_revision
        in: query
        required: false
        description: Query parameter read by this route.
        schema:
          type: string
      - name: expectedSettingsRevision
        in: query
        required: false
        description: Query parameter read by this route.
        schema:
          type: string
      - name: move_to
        in: query
        required: false
        description: Move the stage's live deals to this stage (same pipeline, not a system holding stage, same won / lost setting) and delete the stage.
        schema:
          type: string
          format: uuid
      - name: sandbox
        in: query
        required: false
        description: Run the mutation in sandbox mode.
        schema:
          type: boolean
      responses:
        '200':
          description: 'Stage deleted (expected_settings_revision given): { id, deleted: true, settingsRevision }'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
        '204':
          description: Stage deleted
        '400':
          description: move_to is not a stage of the pipeline, is the stage itself or a system holding stage, or has another won / lost setting
        '409':
          description: Deals are currently in the stage (and no move_to was given), an active unattended-lead automation or the DPP status map selects it, intake_target (enabled intake creates deal cards in this stage), pipeline_archived (the pipeline was archived while this request waited; nothing moved or deleted), or stale_settings_revision
    get:
      x-generated: true
      operationId: getPipelinesIdStagesStageId
      summary: Get pipelines id stages stageId
      tags:
      - Pipelines
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: stageId
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataEnvelope'
components:
  schemas:
    DataEnvelope:
      type: object
      properties:
        data:
          description: Response payload (shape varies by endpoint)
    ErrorResponse:
      type: object
      required:
      - error
      properties:
        error:
          type: string
        code:
          type: string
          description: Machine-readable error code (e.g., TRIAL_EXPIRED, PLAN_LIMIT_REACHED)
  responses:
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  parameters:
    IdParam:
      name: id
      in: path
      required: true
      schema:
        type: string
        format: uuid
      description: Resource UUID
  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