OpenAPI spec
OpenAPI spec
Last updated 5/24/2026
Colony API — OpenAPI 3.1 Specification
Endpoint Summary Table
| ID | Method | Path | Tag | Auth Required |
|---|---|---|---|---|
| API-001 | POST | /api/chat | Chat | ✓ |
| API-002 | GET | /api/chat/history | Chat | ✓ |
| API-003 | DELETE | /api/chat/history | Chat | ✓ |
| API-004 | GET | /api/prospects | Prospects | ✓ |
| API-005 | POST | /api/prospects | Prospects | ✓ |
| API-006 | GET | /api/prospects/{id} | Prospects | ✓ |
| API-007 | PATCH | /api/prospects/{id} | Prospects | ✓ |
| API-008 | DELETE | /api/prospects/{id} | Prospects | ✓ |
| API-009 | POST | /api/prospects/{id}/qualify | Prospects | ✓ |
| API-010 | GET | /api/prospects/candidates | Prospects | ✓ |
| API-011 | POST | /api/prospects/candidates/{id}/approve | Prospects | ✓ |
| API-012 | POST | /api/prospects/candidates/{id}/reject | Prospects | ✓ |
| API-013 | POST | /api/prospects/discover | Prospects | ✓ |
| API-014 | POST | /api/prospects/import/csv | Prospects | ✓ |
| API-015 | GET | /api/outbound/sequences | Outbound | ✓ |
| API-016 | POST | /api/outbound/sequences | Outbound | ✓ |
| API-017 | GET | /api/outbound/sequences/{id} | Outbound | ✓ |
| API-018 | PATCH | /api/outbound/sequences/{id} | Outbound | ✓ |
| API-019 | DELETE | /api/outbound/sequences/{id} | Outbound | ✓ |
| API-020 | POST | /api/outbound/sequences/{id}/enroll | Outbound | ✓ |
| API-021 | POST | /api/outbound/sequences/{id}/pause | Outbound | ✓ |
| API-022 | POST | /api/outbound/sequences/{id}/resume | Outbound | ✓ |
| API-023 | GET | /api/outbound/messages | Outbound | ✓ |
| API-024 | POST | /api/outbound/messages/generate | Outbound | ✓ |
| API-025 | GET | /api/outbound/messages/{id} | Outbound | ✓ |
| API-026 | PATCH | /api/outbound/messages/{id} | Outbound | ✓ |
| API-027 | POST | /api/outbound/messages/{id}/approve | Outbound | ✓ |
| API-028 | POST | /api/outbound/messages/{id}/reject | Outbound | ✓ |
| API-029 | POST | /api/outbound/messages/{id}/send | Outbound | ✓ |
| API-030 | GET | /api/outbound/replies | Outbound | ✓ |
| API-031 | POST | /api/outbound/replies/{id}/respond | Outbound | ✓ |
| API-032 | GET | /api/pipeline/deals | Pipeline | ✓ |
| API-033 | POST | /api/pipeline/deals | Pipeline | ✓ |
| API-034 | GET | /api/pipeline/deals/{id} | Pipeline | ✓ |
| API-035 | PATCH | /api/pipeline/deals/{id} | Pipeline | ✓ |
| API-036 | DELETE | /api/pipeline/deals/{id} | Pipeline | ✓ |
| API-037 | POST | /api/pipeline/deals/{id}/stage | Pipeline | ✓ |
| API-038 | POST | /api/pipeline/deals/{id}/sync-pipedrive | Pipeline | ✓ |
| API-039 | GET | /api/pipeline/deals/{id}/timeline | Pipeline | ✓ |
| API-040 | GET | /api/recordings | Recordings | ✓ |
| API-041 | POST | /api/recordings/ingest | Recordings | ✓ |
| API-042 | GET | /api/recordings/{id} | Recordings | ✓ |
| API-043 | GET | /api/recordings/{id}/signals | Recordings | ✓ |
| API-044 | POST | /api/recordings/{id}/process | Recordings | ✓ |
| API-045 | GET | /api/content/pieces | Content | ✓ |
| API-046 | POST | /api/content/pieces | Content | ✓ |
| API-047 | GET | /api/content/pieces/{id} | Content | ✓ |
| API-048 | PATCH | /api/content/pieces/{id} | Content | ✓ |
| API-049 | DELETE | /api/content/pieces/{id} | Content | ✓ |
| API-050 | POST | /api/content/pieces/{id}/publish | Content | ✓ |
| API-051 | GET | /api/content/attribution | Content | ✓ |
| API-052 | GET | /api/onboarding/kits | Onboarding | ✓ |
| API-053 | GET | /api/onboarding/kits/{dealId} | Onboarding | ✓ |
| API-054 | POST | /api/onboarding/kits/{dealId}/generate | Onboarding | ✓ |
| API-055 | GET | /api/onboarding/kits/{dealId}/assets/{assetType} | Onboarding | ✓ |
| API-056 | GET | /api/knowledge | Knowledge Core | ✓ |
| API-057 | POST | /api/knowledge | Knowledge Core | ✓ |
| API-058 | GET | /api/knowledge/{id} | Knowledge Core | ✓ |
| API-059 | PATCH | /api/knowledge/{id} | Knowledge Core | ✓ |
| API-060 | DELETE | /api/knowledge/{id} | Knowledge Core | ✓ |
| API-061 | POST | /api/knowledge/search | Knowledge Core | ✓ |
| API-062 | POST | /api/knowledge/{id}/embed | Knowledge Core | ✓ |
| API-063 | GET | /api/approvals | Approvals | ✓ |
| API-064 | POST | /api/approvals/{id}/approve | Approvals | ✓ |
| API-065 | POST | /api/approvals/{id}/reject | Approvals | ✓ |
| API-066 | GET | /api/approvals/queue | Approvals | ✓ |
| API-067 | GET | /api/circuit-breakers | Circuit Breakers | ✓ |
| API-068 | POST | /api/circuit-breakers/{orgId}/reset | Circuit Breakers | ✓ |
| API-069 | PATCH | /api/circuit-breakers/{orgId}/thresholds | Circuit Breakers | ✓ |
| API-070 | GET | /api/analytics/brief | Analytics | ✓ |
| API-071 | GET | /api/analytics/brief/history | Analytics | ✓ |
| API-072 | GET | /api/analytics/pipeline | Analytics | ✓ |
| API-073 | GET | /api/analytics/outbound | Analytics | ✓ |
| API-074 | GET | /api/analytics/content | Analytics | ✓ |
| API-075 | GET | /api/api-keys | API Keys | ✓ |
| API-076 | POST | /api/api-keys | API Keys | ✓ |
| API-077 | DELETE | /api/api-keys/{id} | API Keys | ✓ |
| API-078 | POST | /api/api-keys/{id}/rotate | API Keys | ✓ |
| API-079 | POST | /api/webhooks/clerk | Webhooks | ✗ |
| API-080 | POST | /api/webhooks/inngest | Webhooks | ✗ |
| API-081 | POST | /api/webhooks/pipedrive | Webhooks | ✗ |
| API-082 | GET | /api/integrations/pipedrive/status | Integrations | ✓ |
| API-083 | POST | /api/integrations/pipedrive/sync | Integrations | ✓ |
| API-084 | GET | /api/integrations/google/status | Integrations | ✓ |
| API-085 | POST | /api/integrations/google/oauth/callback | Integrations | ✓ |
| API-086 | GET | /api/integrations/unipile/status | Integrations | ✓ |
| API-087 | GET | /api/contacts | Contacts | ✓ |
| API-088 | POST | /api/contacts | Contacts | ✓ |
| API-089 | GET | /api/contacts/{id} | Contacts | ✓ |
| API-090 | PATCH | /api/contacts/{id} | Contacts | ✓ |
| API-091 | GET | /api/contacts/{id}/org-detail | Contacts | ✓ |
| API-092 | GET | /api/mailboxes | Mailboxes | ✓ |
| API-093 | POST | /api/mailboxes | Mailboxes | ✓ |
| API-094 | PATCH | /api/mailboxes/{id} | Mailboxes | ✓ |
| API-095 | DELETE | /api/mailboxes/{id} | Mailboxes | ✓ |
| API-096 | GET | /api/contact-lists | Contact Lists | ✓ |
| API-097 | POST | /api/contact-lists | Contact Lists | ✓ |
| API-098 | GET | /api/contact-lists/{id} | Contact Lists | ✓ |
| API-099 | PATCH | /api/contact-lists/{id} | Contact Lists | ✓ |
| API-100 | DELETE | /api/contact-lists/{id} | Contact Lists | ✓ |
| API-101 | POST | /api/contact-lists/{id}/members | Contact Lists | ✓ |
| API-102 | GET | /api/health | System | ✗ |
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