Contents
On this page

Move Opportunity Stage - Plugixa CRM

PUT /plugixa-crm/v1/opportunities/{id}/stage

Move an opportunity to another stage of its pipeline, as dragging it on the board does. PATCH works the same way.

Any user with access to Plugixa CRM. With Plugixa CRM Pro roles, the user’s role must also allow editing this opportunity.

Note. Moving to the stage it is already in still records a history entry and resets probability and last_stage_change_at.

Request

PUT https://your-site.example/wp-json/plugixa-crm/v1/opportunities/24/stage

Path parameters

Name Type Description
id integer The opportunity’s id

Request body

Content type: application/json

Field Type Required Description
stage_id integer Yes A stage of the opportunity’s pipeline.
lost_reason string No Stored only when the stage is a lost stage.

The move sets status to the stage’s type, probability to the stage’s probability and last_stage_change_at to now. A won or lost stage stamps closed_at; an open stage clears it. Each move is added to history with the time spent in the previous stage.

{
  "stage_id": 6,
  "lost_reason": "Went with a competitor"
}

Responses

200 OK. data is the moved opportunity.

{
  "success": true,
  "data": {
    "id": 24,
    "name": "Northwind Traders: platform licence",
    "account_id": 12,
    "contact_id": 31,
    "lead_id": null,
    "pipeline_id": 1,
    "stage_id": 6,
    "amount": 12000,
    "currency": "EUR",
    "amount_base": 13020,
    "probability": 0,
    "close_date": "2026-12-15",
    "status": "lost",
    "lost_reason": "Went with a competitor",
    "source": "",
    "description": "",
    "last_stage_change_at": "2026-11-12 10:15:00",
    "closed_at": "2026-11-12 10:15:00",
    "assigned_user_id": "3",
    "created_by": "1",
    "modified_by": "1",
    "created_at": "2026-11-12 09:30:00",
    "modified_at": "2026-11-12 10:15:00",
    "deleted_at": null,
    "history": [
      {
        "id": 31,
        "opportunity_id": 24,
        "from_stage_id": null,
        "to_stage_id": 3,
        "from_status": null,
        "to_status": "open",
        "amount_at_change": 13020,
        "seconds_in_from_stage": null,
        "changed_by": "1",
        "changed_at": "2026-11-12 09:30:00",
        "to_stage_name": "Proposal",
        "from_stage_name": null
      },
      {
        "id": 37,
        "opportunity_id": 24,
        "from_stage_id": 3,
        "to_stage_id": 6,
        "from_status": "open",
        "to_status": "lost",
        "amount_at_change": 13020,
        "seconds_in_from_stage": 2700,
        "changed_by": "1",
        "changed_at": "2026-11-12 10:15:00",
        "to_stage_name": "Closed Lost",
        "from_stage_name": "Proposal"
      }
    ],
    "stage": {
      "id": 6,
      "pipeline_id": 1,
      "name": "Closed Lost",
      "slug": "closed-lost",
      "type": "lost",
      "probability": 0,
      "color": "#dc2626",
      "position": 5,
      "created_at": "2026-11-12 09:30:00"
    },
    "stages": [
      {
        "id": 1,
        "pipeline_id": 1,
        "name": "Qualification",
        "slug": "qualification",
        "type": "open",
        "probability": 10,
        "color": "#64748b",
        "position": 0,
        "created_at": "2026-11-12 09:30:00"
      },
      {
        "id": 2,
        "pipeline_id": 1,
        "name": "Needs Analysis",
        "slug": "needs-analysis",
        "type": "open",
        "probability": 25,
        "color": "#0ea5e9",
        "position": 1,
        "created_at": "2026-11-12 09:30:00"
      },
      {
        "id": 3,
        "pipeline_id": 1,
        "name": "Proposal",
        "slug": "proposal",
        "type": "open",
        "probability": 50,
        "color": "#6366f1",
        "position": 2,
        "created_at": "2026-11-12 09:30:00"
      },
      {
        "id": 4,
        "pipeline_id": 1,
        "name": "Negotiation",
        "slug": "negotiation",
        "type": "open",
        "probability": 75,
        "color": "#a855f7",
        "position": 3,
        "created_at": "2026-11-12 09:30:00"
      },
      {
        "id": 5,
        "pipeline_id": 1,
        "name": "Closed Won",
        "slug": "closed-won",
        "type": "won",
        "probability": 100,
        "color": "#16a34a",
        "position": 4,
        "created_at": "2026-11-12 09:30:00"
      },
      {
        "id": 6,
        "pipeline_id": 1,
        "name": "Closed Lost",
        "slug": "closed-lost",
        "type": "lost",
        "probability": 0,
        "color": "#dc2626",
        "position": 5,
        "created_at": "2026-11-12 09:30:00"
      }
    ]
  }
}
Field Type Meaning
data.stage_id integer The current stage
data.status string open, won or lost, taken from the stage’s type
data.probability integer 0 to 100
data.closed_at string|null UTC datetime it reached a won or lost stage
data.history array Every stage move, with from_stage_name, to_stage_name, amount_at_change, changed_at

Errors

Status Code When
404 plugixa_crm_not_found No opportunity with that id, or it is in the trash.
422 plugixa_crm_invalid_stage stage_id is missing or not an existing stage.
422 plugixa_crm_stage_pipeline_mismatch The stage belongs to another pipeline.

Plus the errors every endpoint can return.

Examples

curl -s -X PUT "https://your-site.example/wp-json/plugixa-crm/v1/opportunities/24/stage" \
  -u "admin:$WP_APP_PASSWORD" \
  -H "Content-Type: application/json" \
  -d '{"stage_id":6,"lost_reason":"Went with a competitor"}'
<?php
$ch = curl_init('https://your-site.example/wp-json/plugixa-crm/v1/opportunities/24/stage');
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST  => 'PUT',
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_USERPWD        => 'admin:' . getenv('WP_APP_PASSWORD'),
    CURLOPT_HTTPHEADER     => ['Content-Type: application/json'],
    CURLOPT_POSTFIELDS     => json_encode([
        'stage_id'    => 6,
        'lost_reason' => 'Went with a competitor',
    ]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
const auth = 'Basic ' + btoa(`admin:${process.env.WP_APP_PASSWORD}`);
const response = await fetch('https://your-site.example/wp-json/plugixa-crm/v1/opportunities/24/stage', {
  method: 'PUT',
  headers: {
    'Authorization': auth,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ stage_id: 6, lost_reason: 'Went with a competitor' }),
});
const { data } = await response.json();

Quick Links

Share