KasarKasar Docs
API Reference

Pipelines

List pipelines, inspect their steps, and move records between stages.

Pipelines define the stages a record moves through in your workflow. Any object with a PIPELINE field can have one or more pipelines associated with it -- not just opportunities.

List all pipelines

GET /api/v1/pipelines

Returns every pipeline in your organization, including their ordered steps.

Response

{
  "pipelines": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Sales Pipeline",
      "objectName": "opportunities",
      "steps": [
        {
          "id": "step-001",
          "name": "Qualification",
          "order_index": 0
        },
        {
          "id": "step-002",
          "name": "Discovery",
          "order_index": 1
        },
        {
          "id": "step-003",
          "name": "Proposal",
          "order_index": 2
        },
        {
          "id": "step-004",
          "name": "Negotiation",
          "order_index": 3
        },
        {
          "id": "step-005",
          "name": "Closed Won",
          "order_index": 4
        }
      ]
    },
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "name": "Recruitment Pipeline",
      "objectName": "candidates",
      "steps": [
        {
          "id": "step-010",
          "name": "Applied",
          "order_index": 0
        },
        {
          "id": "step-011",
          "name": "Screening",
          "order_index": 1
        },
        {
          "id": "step-012",
          "name": "Interview",
          "order_index": 2
        },
        {
          "id": "step-013",
          "name": "Offer",
          "order_index": 3
        }
      ]
    }
  ]
}

Example

curl -X GET "https://kasar.app/api/v1/pipelines" \
  -H "Authorization: Bearer YOUR_API_TOKEN"

Move a record to a different step

PUT /api/v1/pipelines/{object}/{id}/move

Moves a record to a different pipeline step. Works with any object that has a PIPELINE field.

Path parameters

ParameterTypeDescription
objectstringThe object name (e.g., opportunities, candidates)
idstringThe record ID to move

Request body

FieldTypeRequiredDescription
pipeline_step_idstringYesThe target step ID
pipeline_idstringNoThe pipeline ID. Auto-inferred from the step if not provided.
{
  "pipeline_step_id": "step-003"
}

Behavior

  • The endpoint validates that the target step belongs to the specified (or inferred) pipeline.
  • If pipeline_id is omitted, Kasar looks up which pipeline owns the given step and uses it automatically.
  • If the step does not belong to the pipeline, the request is rejected with a validation error.
  • The endpoint runs the canonical pipeline transition flow (same code path as kanban drag-drop and the in-app table step picker):
    1. Required-field validation. If the source step has required_for_next_stage questions (forward transition) or the source/target steps have required_for_closure questions (closure to won/lost), the endpoint refuses the move when those linked fields are empty on the record. The response is MISSING_REQUIRED_FIELDS with the list of missing field names. Forced-value questions are exempt (the server fills them automatically).
    2. The step column on the record is updated.
    3. pipeline_step_entered_at is stamped (drives pipeline_step_duration).
    4. Forced and default values configured on the target step are applied to the record server-side. Forced values overwrite any existing value; default values fill empty fields.
    5. A witness row is recorded in pipeline_step_history so the step is tagged as visited. For a transition from the last ongoing step into a final (won/lost) step, two witness rows are recorded — one for the step left, one for the final step entered. Backward transitions (target step before current in the order) do not record a witness row and skip required-field validation.
  • GET /api/v1/pipelines returns each pipeline's ordered steps (id, name, order_index) but not the per-step required-field rules. If a move is rejected with MISSING_REQUIRED_FIELDS, the field_errors array names exactly which fields to fill before retrying.
  • A forward step change can also be done via PUT /api/v1/{object}/{id} by setting the step column directly — the same validation, side effects and witness-row recording apply.

Response

On success the endpoint returns a flat object (no data wrapper) confirming the move:

{
  "deal_id": "record-uuid",
  "pipeline_step_id": "step-003",
  "action": "moved"
}

deal_id echoes the path {id}. The endpoint does not return the full record — clients refetch it (e.g. GET /api/v1/{object}/{id}) if they need the post-move state.

Errors

Every handler error is returned with HTTP status 400 (the route does not vary the status by error code). A 401 is returned by the auth layer for a missing or invalid token. The error body is a flat object — { "code", "message" }, plus field_errors for MISSING_REQUIRED_FIELDS — with no error wrapper.

StatusCodeDescription
400MISSING_REQUIRED_FIELDpipeline_step_id is missing from the request body (the path {id} supplies deal_id)
400MISSING_REQUIRED_FIELDSThe transition is blocked because required_for_next_stage or required_for_closure fields are empty. The body includes field_errors: [{ field, message }] listing the fields to fill before retrying.
400INVALID_OBJECTThe object name in the path is unknown
400INVALID_OPERATIONThe object has no PIPELINE field, or the step belongs to a different pipeline than the one passed in pipeline_id
400PERMISSION_DENIEDThe caller cannot edit this record
400RECORD_NOT_FOUNDThe pipeline step does not exist for this object, or the record does not exist / is not visible to the caller
400INTERNAL_ERRORThe transition flow failed (server-side; see message)
401UNAUTHORIZEDMissing or invalid API token

Example: handling MISSING_REQUIRED_FIELDS

{
  "code": "MISSING_REQUIRED_FIELDS",
  "message": "MISSING_REQUIRED_FIELDS: cannot transition step — fill these fields first: budget, decision_maker",
  "field_errors": [
    { "field": "budget", "message": "Budget is required (required_for_next_stage)" },
    { "field": "decision_maker", "message": "Decision maker is required (required_for_next_stage)" }
  ]
}

Fill the listed fields on the record (PUT /api/v1/{object}/{id}) and retry the move.

Example

Move an opportunity to the "Proposal" step:

curl -X PUT "https://kasar.app/api/v1/pipelines/opportunities/record-uuid/move" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pipeline_step_id": "step-003"
  }'

Move a record and explicitly specify the pipeline:

curl -X PUT "https://kasar.app/api/v1/pipelines/candidates/record-uuid/move" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "pipeline_step_id": "step-011",
    "pipeline_id": "b2c3d4e5-f6a7-8901-bcde-f12345678901"
  }'

On this page