Update Opportunity Stage
PATCH/external/v1/opportunities/:id/stageMoves an opportunity to a different stage. Lifecycle timestamps (sent_at, accepted_at, qualifying_started_at, qualified_at, scheduled_at, won_at, lost_at) are set automatically based on the target stage.
Authentication
Requires opportunities:write permission.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | string | Yes | The unique identifier of the opportunity |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
stage_id | string | Yes | The target stage ID (see List Pipelines) |
discard_reason_id | string | No | Loss reason, when moving to a loss stage |
INFO
The lifecycle timestamp is derived from the target stage name. Stages named invite_sent, accepted, qualifying, qualified, scheduled, won and lost set sent_at, accepted_at, qualifying_started_at, qualified_at, scheduled_at, won_at and lost_at respectively.
Request
bash
curl --request PATCH \
--url "https://app.getraze.com/external/v1/opportunities/opp_abc123def456/stage" \
--header "Content-Type: application/json" \
--header "X-API-Key: YOUR_API_KEY" \
--data '{
"stage_id": "stg_won"
}'javascript
const axios = require('axios');
const opportunityId = 'opp_abc123def456';
const response = await axios.patch(
`https://app.getraze.com/external/v1/opportunities/${opportunityId}/stage`,
{ stage_id: 'stg_won' },
{
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
}
);
console.log(response.data);python
import requests
opportunity_id = 'opp_abc123def456'
response = requests.patch(
f'https://app.getraze.com/external/v1/opportunities/{opportunity_id}/stage',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={'stage_id': 'stg_won'}
)
print(response.json())Response
json
{
"success": true,
"data": {
"id": "opp_abc123def456",
"title": "Acme Inc - Plan Pro",
"stage_id": "stg_won",
"stage_name": "Won",
"won_at": "2026-01-25T10:00:00Z",
"contact_name": "John Doe",
"owner_user_name": "Maria Silva",
"updated_at": "2026-01-25T10:00:00Z"
},
"stage_change": {
"from": { "id": "stg_proposal", "name": "Proposal" },
"to": { "id": "stg_won", "name": "Won" }
}
}Response Fields
| Field | Type | Description |
|---|---|---|
data | object | The updated opportunity |
stage_change.from | object | Previous stage (id, name) |
stage_change.to | object | New stage (id, name) |
Errors
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | stage_id is required |
| 404 | NOT_FOUND | Opportunity not found |