Skip to main content

ZeroPipeline API

CRM and sales pipeline management. Build deal pipelines, track customers, automate workflows, and get revenue analytics.

Base URL: https://pipeline.ainative.studio/api/v1 Interactive docs: https://pipeline.ainative.studio/api/v1/docs

Authentication

Authorization: Bearer YOUR_JWT_TOKEN

Or use an API key created via POST /api/v1/api-keys.


Health

MethodPathDescription
GET/health/liveLiveness probe
GET/health/readyReadiness probe — returns 503 if ZeroDB or Redis is unreachable
GET/api/v1/healthReadiness with dependency status
GET/api/v1/changelogAPI version metadata

Auth

Refresh token

POST /api/v1/auth/refresh
{ "refresh_token": "string" }

Response:

{ "access_token": "string", "refresh_token": "string" }

Revoke token

POST /api/v1/auth/revoke
{ "refresh_token": "string" }

Logout

POST /api/v1/auth/logout

Revokes the access token and all refresh tokens for the current user.

Password reset

POST /api/v1/auth/password-reset/request
{ "email": "user@example.com" }

Always returns 204 regardless of whether the email exists.

POST /api/v1/auth/password-reset/confirm
{ "token": "reset-token", "new_password": "newpass123" }

API Keys

Create API key

POST /api/v1/api-keys
{ "name": "My Integration" }

Response — plaintext key shown once only, store it immediately:

{
"id": "uuid",
"name": "My Integration",
"key": "zpk_live_xxxxxxxxxxxx",
"created_at": "2026-05-17T00:00:00Z"
}

List API keys

GET /api/v1/api-keys?include_revoked=false

Revoke API key

DELETE /api/v1/api-keys/{key_id}

Pipelines

Create pipeline

POST /api/v1/pipelines
{
"name": "Sales Pipeline",
"owner_id": "uuid",
"stages": [
{ "name": "Lead", "order_index": 0 },
{ "name": "Qualified", "order_index": 1 },
{ "name": "Closed Won", "order_index": 2 }
],
"meta": {}
}

List pipelines

GET /api/v1/pipelines?owner_id=uuid&limit=20&offset=0

Response:

{
"items": [...],
"limit": 20,
"offset": 0,
"total": 5
}

Get pipeline

GET /api/v1/pipelines/{pipeline_id}

Update pipeline

PATCH /api/v1/pipelines/{pipeline_id}

Supports optimistic locking via version.

{ "name": "New Name", "version": 3 }

Delete / restore pipeline

DELETE /api/v1/pipelines/{pipeline_id}
POST /api/v1/pipelines/{pipeline_id}/restore

Soft delete — restorable within 30 days.


Stages

Add stage

POST /api/v1/pipelines/{pipeline_id}/stages
{
"name": "Proposal",
"order_index": 2,
"rules": {
"required_fields": ["value", "expected_close_date"],
"disallow_skip": true,
"allowed_next_stage_ids": ["uuid"]
}
}

List stages

GET /api/v1/pipelines/{pipeline_id}/stages

Returns stages ordered by order_index.

Update stage

PATCH /api/v1/pipelines/{pipeline_id}/stages/{stage_id}

Reorder stages

POST /api/v1/pipelines/{pipeline_id}/stages/reorder
["uuid-stage-1", "uuid-stage-3", "uuid-stage-2"]

Delete stage

DELETE /api/v1/pipelines/{pipeline_id}/stages/{stage_id}

Deals

Deals are sales opportunities moving through pipeline stages.

Create deal

POST /api/v1/deals
{
"name": "Acme Corp - Enterprise",
"customer_id": "uuid",
"pipeline_id": "uuid",
"stage_id": "uuid",
"value": 25000.00,
"status": "open",
"expected_close_date": "2026-06-30",
"owner_id": "uuid"
}

Status values: open · won · lost

List deals

GET /api/v1/deals?pipeline_id=uuid&stage_id=uuid&status=open&q=acme&limit=20&offset=0

q requires at least 3 characters.

Get deal

GET /api/v1/deals/{deal_id}

Update deal

PATCH /api/v1/deals/{deal_id}
{ "stage_id": "uuid", "status": "won", "value": 30000.00 }

Deal health score

GET /api/v1/deals/{deal_id}/score

Returns an auto-calculated score from 0–100.

{ "score": 72 }

Add note to deal

POST /api/v1/deals/{deal_id}/notes
{ "text": "Called customer — moving forward with proposal." }

Creates an Activity record and returns it.

Create invoice from deal

POST /api/v1/deals/{deal_id}/invoice

Creates an invoice in the connected accounting system (QuickBooks or Xero). Deal must be in won status.

Errors:

  • 400 — deal is not won
  • 409 — invoice already exists
  • 422 — no accounting integration connected

Response:

{ "invoice_id": "inv_xxx", "external_id": "QBO-12345" }

Delete / restore deal

DELETE /api/v1/deals/{deal_id}
POST /api/v1/deals/{deal_id}/restore

Customers

Create customer

POST /api/v1/customers
{
"name": "Jane Smith",
"email": "jane@acme.com",
"phone": "+1-555-0100",
"company": "Acme Corp",
"title": "VP Engineering",
"status": "active"
}

List customers

GET /api/v1/customers?page=1&page_size=20&status=active&q=acme

Check for duplicates

POST /api/v1/customers/check-duplicates?email=jane@acme.com&phone=+15550100

Check before creating to avoid duplicate records.

Import from CSV

POST /api/v1/customers/import
Content-Type: multipart/form-data

Response:

{
"total_imported": 95,
"total_skipped": 3,
"errors": ["Row 12: invalid email format"]
}

Get customer

GET /api/v1/customers/{customer_id}

Customer timeline

GET /api/v1/customers/{customer_id}/timeline

Returns the full activity history for the customer.

Update customer

PATCH /api/v1/customers/{customer_id}

Delete / restore customer

DELETE /api/v1/customers/{customer_id}
POST /api/v1/customers/{customer_id}/restore

Products

Products are items or services attachable to deals.

Create product

POST /api/v1/products

Returns 409 if SKU already exists. SKU is auto-uppercased.

{
"name": "Enterprise Plan",
"sku": "ENT-2026",
"description": "Full-featured enterprise subscription",
"price": 999.00,
"cost": 150.00,
"is_active": true
}

List products

GET /api/v1/products?is_active=true&limit=20&offset=0

Search products

GET /api/v1/products/search?query=enterprise&min_price=100&max_price=2000&is_active=true

Full-text search across name, SKU, and description.

Get product by ID

GET /api/v1/products/{product_id}

Get product by SKU

GET /api/v1/products/sku/{sku}

Update product

PATCH /api/v1/products/{product_id}

Supports optimistic locking via version.

{ "price": 1099.00, "version": 2 }

Delete product

DELETE /api/v1/products/{product_id}

Tasks

Tasks are to-dos linked to any entity (deal, customer, etc.).

Create task

POST /api/v1/tasks
{
"title": "Follow up on proposal",
"description": "Send revised pricing by EOD Friday",
"status": "pending",
"priority": "high",
"assignee_id": "uuid",
"due_date": "2026-05-23",
"related_to_type": "deal",
"related_to_id": "uuid"
}

Status values: pending · in_progress · completed · cancelled
Priority values: low · medium · high · urgent

List tasks

GET /api/v1/tasks?status=pending&assignee_id=uuid&priority=high&limit=20&offset=0

Get / update / delete task

GET    /api/v1/tasks/{task_id}
PATCH /api/v1/tasks/{task_id}
DELETE /api/v1/tasks/{task_id}
POST /api/v1/tasks/{task_id}/restore

Activities

Activities are the immutable audit trail of events across all entities. They cannot be modified or deleted.

Log activity

POST /api/v1/activities
{
"activity_type": "deal.created",
"related_to_type": "deal",
"related_to_id": "uuid",
"description": "Deal created from inbound lead",
"meta": { "source": "web-form" }
}

List activities

GET /api/v1/activities?related_to_id=uuid&related_to_type=deal&activity_type=deal.created&from_date=2026-05-01&to_date=2026-05-31&limit=50&offset=0

Get activity types

GET /api/v1/activities/types

Returns all available activity type values with labels and categories.

Get activity feed for entity

GET /api/v1/activities/feed/{related_to_id}?limit=20&offset=0

Filter by type or actor

GET /api/v1/activities/by-type/{activity_type}
GET /api/v1/activities/by-actor/{actor_id}

Automations

Event-triggered workflows that fire actions automatically.

Create automation

POST /api/v1/automations
{
"name": "Send welcome email on deal won",
"trigger": {
"event": "deal.status_changed",
"conditions": { "status": "won" }
},
"actions": [
{
"type": "send_email",
"config": { "template_id": "welcome-won" }
}
],
"is_active": true
}

List automations

GET /api/v1/automations?limit=20&offset=0

Get / update / delete automation

GET    /api/v1/automations/{automation_id}
PUT /api/v1/automations/{automation_id}
DELETE /api/v1/automations/{automation_id}

Manually trigger event

POST /api/v1/automations/trigger
{
"event": "deal.status_changed",
"payload": { "deal_id": "uuid", "status": "won" }
}

Analytics

Dashboard summary

GET /api/v1/analytics/dashboard

Top-level metrics: deal counts, revenue totals, task completion rates.

Revenue timeseries

GET /api/v1/analytics/revenue/timeseries?period=monthly&start=2026-01-01&end=2026-05-31&pipeline_id=uuid

Period values: weekly · monthly · quarterly

Deal analytics

GET /api/v1/analytics/deals?owner_id=uuid

Deal funnel: counts and values by stage and status.

Task analytics

GET /api/v1/analytics/tasks?assignee_id=uuid

Stale deals

GET /api/v1/analytics/stale-deals?days=14

Deals with no activity in the past N days. Max days = 365.

Pipeline analytics

GET /api/v1/analytics/pipeline/{pipeline_id}

Stage conversion rates, average deal age, velocity.

Customer analytics

GET /api/v1/analytics/customers

New customers over time, top customers by deal value.


Tags

GET /api/v1/tags?q=enter

List distinct tags across entities. q prefix-filters (min 1 char) — useful for autocomplete.


Billing

Create checkout session

POST /api/v1/payments/checkout
{ "plan_id": "pro_monthly" }

Response:

{ "session_id": "cs_xxx", "url": "https://checkout.stripe.com/..." }

Get subscription

GET /api/v1/payments/subscription

Response:

{
"status": "active",
"plan": "pro_monthly",
"current_period_start": "2026-05-01T00:00:00Z",
"current_period_end": "2026-06-01T00:00:00Z",
"cancel_at_period_end": false
}

Update subscription

POST /api/v1/payments/subscription
{ "plan_id": "enterprise_annual" }

Cancel subscription

POST /api/v1/payments/subscription/cancel
{ "reason": "switching tools" }

Billing portal

POST /api/v1/billing/portal-session
{ "return_url": "https://yourapp.com/settings" }

Response:

{ "url": "https://billing.stripe.com/session/..." }

Usage and history

GET /api/v1/payments/usage
GET /api/v1/payments/history?limit=20
GET /api/v1/me/billing-status

Usage response:

{
"current_usage": { "deals": 450, "pipelines": 3 },
"limits": { "deals": 1000, "pipelines": 10 },
"percentage": 45.0
}

Audit

Create / list / get audit logs

POST /api/v1/audit/logs
GET /api/v1/audit/logs?entity_type=deal&entity_id=uuid&action=stage_changed&page=1&page_size=50
GET /api/v1/audit/logs/{log_id}

GDPR export / delete

POST /api/v1/audit/gdpr/export
POST /api/v1/audit/gdpr/delete
{ "user_id": "uuid" }

Invitations

Invite user to org

POST /api/v1/orgs/{org_id}/invitations

Requires admin role. Sends email with a signed token link.

{ "email": "newuser@example.com", "role": "sales_rep" }

Role values: admin · sales_rep · viewer

List invitations

GET /api/v1/orgs/{org_id}/invitations?invitation_status=pending

Accept invitation

POST /api/v1/invitations/accept

Unauthenticated endpoint — secured by the signed token from email.

{ "token": "signed-token-from-email" }

Users

Get / update profile

GET   /api/v1/users/me
PATCH /api/v1/users/me
{ "first_name": "Jane", "last_name": "Dev" }

Avatar

GET    /api/v1/users/me/avatar
POST /api/v1/users/me/avatar ← multipart/form-data, JPEG/PNG, max 5 MB
DELETE /api/v1/users/me/avatar

Onboarding checklist

GET /api/v1/users/me/onboarding

Response:

{
"items": [
{ "key": "create_pipeline", "completed": true },
{ "key": "add_deal", "completed": false }
],
"completed_count": 1,
"total_count": 6
}

Account

Export account data (GDPR)

POST /api/v1/account/export

Returns 202 Accepted and emails a download link.

{ "email": "user@example.com" }

Download export

GET /api/v1/account/export/download?token=xxx

Unauthenticated — secured by token.

Delete account

DELETE /api/v1/account

Returns 202 Accepted. Soft-deletes immediately; hard-delete after grace period.

Response:

{
"soft_deleted_at": "2026-05-17T00:00:00Z",
"hard_delete_scheduled_at": "2026-06-17T00:00:00Z"
}

Error Responses

{
"error": "not_found",
"detail": "Pipeline not found",
"code": "PIPELINE_404"
}
StatusMeaning
400Bad request / validation error
401Missing or invalid token
403Insufficient role
404Resource not found
409Conflict (duplicate SKU, invoice already exists)
422Unprocessable (missing integration, etc.)
503ZeroDB or Redis unavailable