Colony

OpenAPI spec

OpenAPI spec

Last updated 5/24/2026

Colony API — OpenAPI 3.1 Specification

Endpoint Summary Table

IDMethodPathTagAuth Required
API-001POST/api/chatChat
API-002GET/api/chat/historyChat
API-003DELETE/api/chat/historyChat
API-004GET/api/prospectsProspects
API-005POST/api/prospectsProspects
API-006GET/api/prospects/{id}Prospects
API-007PATCH/api/prospects/{id}Prospects
API-008DELETE/api/prospects/{id}Prospects
API-009POST/api/prospects/{id}/qualifyProspects
API-010GET/api/prospects/candidatesProspects
API-011POST/api/prospects/candidates/{id}/approveProspects
API-012POST/api/prospects/candidates/{id}/rejectProspects
API-013POST/api/prospects/discoverProspects
API-014POST/api/prospects/import/csvProspects
API-015GET/api/outbound/sequencesOutbound
API-016POST/api/outbound/sequencesOutbound
API-017GET/api/outbound/sequences/{id}Outbound
API-018PATCH/api/outbound/sequences/{id}Outbound
API-019DELETE/api/outbound/sequences/{id}Outbound
API-020POST/api/outbound/sequences/{id}/enrollOutbound
API-021POST/api/outbound/sequences/{id}/pauseOutbound
API-022POST/api/outbound/sequences/{id}/resumeOutbound
API-023GET/api/outbound/messagesOutbound
API-024POST/api/outbound/messages/generateOutbound
API-025GET/api/outbound/messages/{id}Outbound
API-026PATCH/api/outbound/messages/{id}Outbound
API-027POST/api/outbound/messages/{id}/approveOutbound
API-028POST/api/outbound/messages/{id}/rejectOutbound
API-029POST/api/outbound/messages/{id}/sendOutbound
API-030GET/api/outbound/repliesOutbound
API-031POST/api/outbound/replies/{id}/respondOutbound
API-032GET/api/pipeline/dealsPipeline
API-033POST/api/pipeline/dealsPipeline
API-034GET/api/pipeline/deals/{id}Pipeline
API-035PATCH/api/pipeline/deals/{id}Pipeline
API-036DELETE/api/pipeline/deals/{id}Pipeline
API-037POST/api/pipeline/deals/{id}/stagePipeline
API-038POST/api/pipeline/deals/{id}/sync-pipedrivePipeline
API-039GET/api/pipeline/deals/{id}/timelinePipeline
API-040GET/api/recordingsRecordings
API-041POST/api/recordings/ingestRecordings
API-042GET/api/recordings/{id}Recordings
API-043GET/api/recordings/{id}/signalsRecordings
API-044POST/api/recordings/{id}/processRecordings
API-045GET/api/content/piecesContent
API-046POST/api/content/piecesContent
API-047GET/api/content/pieces/{id}Content
API-048PATCH/api/content/pieces/{id}Content
API-049DELETE/api/content/pieces/{id}Content
API-050POST/api/content/pieces/{id}/publishContent
API-051GET/api/content/attributionContent
API-052GET/api/onboarding/kitsOnboarding
API-053GET/api/onboarding/kits/{dealId}Onboarding
API-054POST/api/onboarding/kits/{dealId}/generateOnboarding
API-055GET/api/onboarding/kits/{dealId}/assets/{assetType}Onboarding
API-056GET/api/knowledgeKnowledge Core
API-057POST/api/knowledgeKnowledge Core
API-058GET/api/knowledge/{id}Knowledge Core
API-059PATCH/api/knowledge/{id}Knowledge Core
API-060DELETE/api/knowledge/{id}Knowledge Core
API-061POST/api/knowledge/searchKnowledge Core
API-062POST/api/knowledge/{id}/embedKnowledge Core
API-063GET/api/approvalsApprovals
API-064POST/api/approvals/{id}/approveApprovals
API-065POST/api/approvals/{id}/rejectApprovals
API-066GET/api/approvals/queueApprovals
API-067GET/api/circuit-breakersCircuit Breakers
API-068POST/api/circuit-breakers/{orgId}/resetCircuit Breakers
API-069PATCH/api/circuit-breakers/{orgId}/thresholdsCircuit Breakers
API-070GET/api/analytics/briefAnalytics
API-071GET/api/analytics/brief/historyAnalytics
API-072GET/api/analytics/pipelineAnalytics
API-073GET/api/analytics/outboundAnalytics
API-074GET/api/analytics/contentAnalytics
API-075GET/api/api-keysAPI Keys
API-076POST/api/api-keysAPI Keys
API-077DELETE/api/api-keys/{id}API Keys
API-078POST/api/api-keys/{id}/rotateAPI Keys
API-079POST/api/webhooks/clerkWebhooks
API-080POST/api/webhooks/inngestWebhooks
API-081POST/api/webhooks/pipedriveWebhooks
API-082GET/api/integrations/pipedrive/statusIntegrations
API-083POST/api/integrations/pipedrive/syncIntegrations
API-084GET/api/integrations/google/statusIntegrations
API-085POST/api/integrations/google/oauth/callbackIntegrations
API-086GET/api/integrations/unipile/statusIntegrations
API-087GET/api/contactsContacts
API-088POST/api/contactsContacts
API-089GET/api/contacts/{id}Contacts
API-090PATCH/api/contacts/{id}Contacts
API-091GET/api/contacts/{id}/org-detailContacts
API-092GET/api/mailboxesMailboxes
API-093POST/api/mailboxesMailboxes
API-094PATCH/api/mailboxes/{id}Mailboxes
API-095DELETE/api/mailboxes/{id}Mailboxes
API-096GET/api/contact-listsContact Lists
API-097POST/api/contact-listsContact Lists
API-098GET/api/contact-lists/{id}Contact Lists
API-099PATCH/api/contact-lists/{id}Contact Lists
API-100DELETE/api/contact-lists/{id}Contact Lists
API-101POST/api/contact-lists/{id}/membersContact Lists
API-102GET/api/healthSystem

openapi: 3.1.0

info:
  title: Colony API
  version: 1.0.0
  description: |
    The Colony API is the backend surface for the ZoomProp GTM Agentic Stack command
    interface. It exposes endpoints for the GTM Orchestrator chat interface, outbound
    sequence engine, pipeline management, recording intelligence, content pipeline,
    onboarding kit generation, knowledge core retrieval, approvals queue, circuit
    breakers, analytics/daily brief, and all integration bridges (Pipedrive, Unipile,
    Google Drive/Gmail/Calendar, Resend).

    All authenticated endpoints require a Clerk session token passed as a Bearer token
    in the `Authorization` header. Multi-tenancy is enforced at the database layer:
    every resource row carries an `org_id` sourced from the Clerk organization context
    and validated server-side.

    **API versions**: This document covers v1 (current). The base path `/api` maps to
    Next.js App Router route handlers under `src/app/api/`.

    **Streaming**: `POST /api/chat` returns a Server-Sent Events stream
    (`text/event-stream`) for real-time orchestrator tool call and artifact delivery.
    All other endpoints return JSON.

    **Rate limiting**: Per-org limits are enforced by the circuit breaker subsystem.
    Exceeding them returns HTTP 429 with a `Retry-After` header.
  contact:
    name: Colony Engineering
    url: https://github.com/midwestco/colony
  license:
    name: Proprietary
    url: https://github.com/midwestco/colony

servers:
  - url: https://colony.zoompropengage.com
    description: Production — Google Cloud Run (colony-39989 project)
  - url: https://colony-staging.zoompropengage.com
    description: Staging — Cloud Run staging revision
  - url: http://localhost:3000
    description: Local development — Next.js dev server

security:
  - ClerkBearer: []

tags:
  - name: Chat
    description: |
      GTM Orchestrator streaming chat interface. Accepts natural-language commands
      and streams multi-turn tool loops (prospect discovery → qualification →
      message generation → approval) as Server-Sent Events.
  - name: Prospects
    description: |
      Prospect discovery, qualification scoring, candidate approval queue,
      and CSV import. Backed by the prospect and qualification specialist agents.
  - name: Outbound
    description: |
      Outbound sequence engine: 5 angles (signal-, pain-, referral-,
      pattern-break-, insight-led), T1–T5 step sequences, message generation,
      per-message approval, and HOT reply queue.
  - name: Pipeline
    description: |
      9-stage deal pipeline tracker with bi-directional Pipedrive sync and
      ICP scoring. Deals transition through stages: Discovery → Qualified →
      Demo → Proposal → Negotiation → Closed-Won → Closed-Lost → Churned → Renewed.
  - name: Recordings
    description: |
      Recording intelligence: ingests Gemini Meet Notes from Google Drive,
      extracts signals, routes them to CRM fields and the Knowledge Core.
  - name: Content
    description: |
      Content pipeline across 6 pillars with pipeline-influence attribution.
      Content is generated by the content specialist agent and enters an
      approval flow before publication.
  - name: Onboarding
    description: |
      Deployment Kit generation: auto-creates 8 assets (pitch deck, one-pager,
      case-study shortlist, pricing reference, rollout calendar, stakeholder
      map, risk register, KPI dashboard) triggered on Closed-Won deal stage.
  - name: Knowledge Core
    description: |
      10-domain single source of truth with pgvector (1536-dim) retrieval.
      Supports semantic search, exemplar retrieval, and manual CRUD for
      knowledge entries.
  - name: Approvals
    description: |
      Unified approval queue spanning outbound messages, content pieces,
      and candidate prospects. Supports approve/reject with optional comments.
  - name: Circuit Breakers
    description: |
      Per-org circuit breakers that halt outbound or content operations when
      configurable thresholds (bounce rate, reply rate, daily send cap) are
      breached. Admin-only reset and threshold configuration.
  - name: Analytics
    description: |
      Daily brief generation and historical retrieval, plus pipeline, outbound,
      and content performance metrics surfaced by the analytics specialist agent.
  - name: API Keys
    description: |
      Colony Vault — per-org KMS-encrypted API key storage for Pipedrive,
      Unipile, Resend, Google, and other third-party credentials.
  - name: Webhooks
    description: |
      Inbound webhook receivers. These endpoints are unauthenticated but
      validate provider-specific HMAC signatures (Clerk via Svix,
      Pipedrive shared secret, Inngest signature).
  - name: Integrations
    description: |
      Status checks and manual sync triggers for external integration bridges:
      Pipedrive CRM, Google Workspace (Drive/Gmail/Calendar), and Unipile
      (LinkedIn/email multichannel).
  - name: Contacts
    description: |
      Contact and organization directory with Pipedrive reveal persistence
      and org-detail enrichment.
  - name: Mailboxes
    description: |
      Sender mailbox pool management for email deliverability rotation.
      Supports round-robin assignment and warmup tracking.
  - name: Contact Lists
    description: |
      Named contact list builder for campaign targeting. Lists are composed
      of contact IDs and can be used as sequence enrollment sources.
  - name: System
    description: Platform health and readiness endpoints.

paths:

  # ─────────────────────────────────────────────────────────────────
  # CHAT
  # ─────────────────────────────────────────────────────────────────

  /api/chat:
    post:
      operationId: API-001
      tags: [Chat]
      summary: Send a message to the GTM Orchestrator
      description: |
        Submits a user message to the GTM Orchestrator and returns a
        Server-Sent Events stream. Each SSE event is a JSON object with a
        `type` field: `tool_call` | `tool_result` | `artifact` | `message` | `done`.

        The orchestrator runs a multi-turn tool loop delegating to specialist agents
        (prospect, qualification, message-gen, content, recording, post-call,
        onboarding, analytics). Tool call approvals that require human review emit
        `approval_required` events and pause the loop until resolved via
        `POST /api/approvals/{id}/approve`.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChatMessageRequest'
      responses:
        '200':
          description: |
            SSE stream. `Content-Type: text/event-stream`. Each line is
            `data: <JSON>\n\n`. The final event has `type: done`.
          content:
            text/event-stream:
              schema:
                $ref: '#/components/schemas/ChatStreamEvent'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  /api/chat/history:
    get:
      operationId: API-002
      tags: [Chat]
      summary: List chat history for the current session or org
      description: |
        Returns paginated chat turns for the authenticated org. Each turn
        includes the user message, assistant reply, and any artifacts or
        tool call records attached to that turn.
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: session_id
          in: query
          required: false
          schema:
            type: string
            format: uuid
          description: Filter to a specific chat session UUID.
      responses:
        '200':
          description: Paginated chat turns.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChatHistoryResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

    delete:
      operationId: API-003
      tags: [Chat]
      summary: Clear chat history
      description: |
        Deletes all chat turns for the specified session. If `session_id`
        is omitted, clears the entire org chat history. Requires `admin`
        or `member` role; `viewer` role is denied.
      parameters:
        - name: session_id
          in: query
          required: false
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: History cleared successfully.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  # ─────────────────────────────────────────────────────────────────
  # PROSPECTS
  # ─────────────────────────────────────────────────────────────────

  /api/prospects:
    get:
      operationId: API-004
      tags: [Prospects]
      summary: List prospects
      description: |
        Returns a paginated list of prospects for the authenticated org.
        Supports filtering by ICP score range, stage, and assigned sequence.
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: stage
          in: query
          schema:
            type: string
            enum: [discovered, qualified, rejected, enrolled, replied, converted]
        - name: min_icp_score
          in: query
          schema:
            type: integer
            minimum: 0
            maximum: 100
        - name: sequence_id
          in: query
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Paginated prospect list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProspectListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

    post:
      operationId: API-005
      tags: [Prospects]
      summary: Create a prospect manually
      description: |
        Creates a new prospect record. For automated discovery, use
        `POST /api/prospects/discover`. This endpoint is for manual entry.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProspectCreateRequest'
      responses:
        '201':
          description: Prospect created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Prospect'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  /api/prospects/{id}:
    get:
      operationId: API-006
      tags: [Prospects]
      summary: Get a prospect by ID
      parameters:
        - $ref: '#/components/parameters/ResourceId'
      responses:
        '200':
          description: Prospect detail.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Prospect'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

    patch:
      operationId: API-007
      tags: [Prospects]
      summary: Update a prospect
      parameters:
        - $ref: '#/components/parameters/ResourceId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProspectUpdateRequest'
      responses:
        '200':
          description: Updated prospect.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Prospect'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

    delete:
      operationId: API-008
      tags: [Prospects]
      summary: Delete a prospect
      parameters:
        - $ref: '#/components/parameters/ResourceId'
      responses:
        '204':
          description: Prospect deleted.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  /api/prospects/{id}/qualify:
    post:
      operationId: API-009
      tags: [Prospects]
      summary: Trigger qualification scoring for a prospect
      description: |
        Invokes the qualification specialist agent via Inngest to score the
        prospect against the org's ICP definition. Returns the updated
        prospect record with `icp_score` and `qualification_notes` fields
        populated. This is an async operation; the response reflects the
        queued state immediately.
      parameters:
        - $ref: '#/components/parameters/ResourceId'
      responses:
        '202':
          description: Qualification job accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QualificationJobResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  /api/prospects/candidates:
    get:
      operationId: API-010
      tags: [Prospects]
      summary: List discovery candidates pending approval
      description: |
        Returns candidates surfaced by the discovery orchestrator that have
        not yet been approved or rejected. These are staged records from
        Pipedrive LeadBooster scraper, Google Places, SerpAPI, Unipile
        search, or Playwright runner outputs awaiting human review.
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: source
          in: query
          schema:
            type: string
            enum:
              [pipedrive_scraper, google_places, serpapi, unipile, playwright, csv]
      responses:
        '200':
          description: Paginated candidate list.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CandidateListResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  /api/prospects/candidates/{id}/approve:
    post:
      operationId: API-011
      tags: [Prospects]
      summary: Approve a discovery candidate
      description: |
        Promotes a candidate to a full prospect record and optionally
        enrolls it in a specified outbound sequence.
      parameters:
        - $ref: '#/components/parameters/ResourceId'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CandidateApproveRequest'
      responses:
        '200':
          description: Candidate approved and promoted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Prospect'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  /api/prospects/candidates/{id}/reject:
    post:
      operationId: API-012
      tags: [Prospects]
      summary: Reject a discovery candidate
      parameters:
        - $ref: '#/components/parameters/ResourceId'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CandidateRejectRequest'
      responses:
        '200':
          description: Candidate rejected.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationResult'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  /api/prospects/discover:
    post:
      operationId: API-013
      tags: [Prospects]
      summary: Trigger the discovery orchestrator
      description: |
        Dispatches an Inngest event to run the discovery orchestrator with
        the supplied search parameters. Orchestrator delegates to enabled
        adapters (Pipedrive scraper, Google Places, SerpAPI, Unipile search,
        Playwright runner) based on org configuration. Results land in the
        candidates queue (`GET /api/prospects/candidates`).
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DiscoverRequest'
      responses:
        '202':
          description: Discovery job accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DiscoveryJobResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  /api/prospects/import/csv:
    post:
      operationId: API-014
      tags: [Prospects]
      summary: Import prospects from a CSV file
      description: |
        Accepts a `multipart/form-data` upload with a CSV file containing
        prospect data. Rows are validated against the prospect schema and
        queued for qualification scoring. Returns a job ID for status polling.
        The file is stored transiently in `gs://colony-assets` and deleted
        after import completes.
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              type: object
              required: [file]
              properties:
                file:
                  type: string
                  format: binary
                  description: CSV file. Required columns — first_name, last_name, email, company.
                sequence_id:
                  type: string
                  format: uuid
                  description: Optionally enroll imported prospects into this sequence.
                auto_qualify:
                  type: boolean
                  default: false
                  description: Trigger qualification agent on all imported rows.
      responses:
        '202':
          description: Import job accepted.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImportJobResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
      security:
        - ClerkBearer: []

  # ─────────────────────────────────────────────────────────────────
  # OUTBOUND
  # ─────────────────────────────────────────────────────────────────

  /api/outbound/sequences:
    get:
      operationId: API-015
      tags: [Outbound]
      summary: List outbound sequences
      parameters:
        - $ref: '#/components/parameters/PageParam'
        - $ref: '#/components/parameters/LimitParam'
        - name: angle
          in: query
          schema:
            type: string
            enum: [signal, pain, referral, pattern_break, insight]
          description: Filter