CRM opportunity pipelines & Kanban
How DripPulse models deal stages, the default org pipeline, the Opportunities UI, and the JSON API.
Concepts
- Pipeline — A set of stages your opportunities move through. Each organization gets an org default pipeline (shared) with standard stage names (Unassigned, Prospect, Qualification, Proposal, Negotiation, Won, Lost). Signed-in users can also create personal pipelines (copies they own) for their own view.
- Stage — One column in the pipeline. Stages have a
stage_typeofopen,won, orlost, which keeps opportunitystatusaligned for reporting. - Opportunity — Always linked to exactly one
pipeline_idandpipeline_stage_id. Optionalstage_positioncontrols card order within a Kanban column. - Default pipeline for you — The API returns
default_pipeline_id(from your user preference when set, otherwise the org default). The app opens the Kanban for that pipeline by default.
In the app
Open CRM → Opportunities from the sidebar.
- Switch between Kanban and Table.
- Use the Pipeline dropdown to pick the org default or a pipeline you created.
- Drag cards between columns to change stage (updates via the API).
- New opportunity creates a deal in the selected stage (open stages only in the form).
- Filter by name or
public_idwith Search + Apply.
HTTP API (overview)
Base path: /api/v1/crm/…. Same authentication as the rest of the API (Authorization: Bearer … JWT or API key). Tenant is always your organization; do not send an org id to impersonate another tenant.
Pipelines
GET /api/v1/crm/opportunity_pipelines
Returns pipelines (each with nested stages) and default_pipeline_id. Ensures the org default pipeline exists.
POST /api/v1/crm/opportunity_pipelines
Content-Type: application/json
{ "pipeline": { "name": "My pipeline" } }
Clones the org default stages into a user-owned pipeline (requires a user session, not API-key-only in typical setups). 201 Created with the full pipeline payload.
PATCH /api/v1/crm/opportunity_pipelines/:id
Update name or nested stages for a pipeline you created (user_id matches). Org default pipelines are not edited through this route for arbitrary rename; product rules may evolve.
DELETE /api/v1/crm/opportunity_pipelines/:id
Deletes a user-owned pipeline only if it has no opportunities.
POST /api/v1/crm/opportunity_pipelines/:id/set_default
Sets your preferred default pipeline for lists and Kanban.
Opportunities
GET /api/v1/crm/opportunities?pipeline_id=<uuid>&q=
List opportunities in that pipeline. Optional q filters by name or public_id (ILIKE).
POST /api/v1/crm/opportunities
{ "opportunity": { "name": "ACME expansion", "pipeline_stage_id": "…" } }
Creating without pipeline_stage_id still works: the server assigns the org default Unassigned stage. You may pass pipeline_id and pipeline_stage_id for explicit placement.
PATCH /api/v1/crm/opportunities/:public_id_or_uuid
{ "opportunity": { "pipeline_stage_id": "…" } }
Moves or updates a deal; server validates the stage belongs to your org.
POST /api/v1/crm/opportunities/reorder
Content-Type: application/json
{
"pipeline_stage_id": "<stage uuid>",
"ordered_ids": ["opp_abc123", "<uuid>", …]
}
Sets stage_position for opportunities already in that stage, in list order. IDs may be public_id or internal UUID.
Response fields
Each opportunity in JSON includes at least: public_id, name, pipeline_id, pipeline_stage_id, stage, stage_position, plus amount, currency, and other CRM fields. Full route tables: API reference → CRM.
Export & import
JSON bundles include pipeline_id and pipeline_stage_id on opportunities. See CRM data portability for bundle format and import order.
Implementation note (developers)
Multi-tenancy and schema notes are in the repo document docs/CRM_STARTER_RECORD_LAYER_MULTITENANCY.md (section on opportunity pipelines).