Create Opportunity
POST/external/v1/opportunitiesCreates a new opportunity/lead. A contact is created (or matched by email) and linked to the opportunity automatically. If no owner_user_id is provided, the opportunity is auto-assigned using your account's round-robin rules.
Retry-safe
Send an Idempotency-Key header to make retries safe — a repeated request with the same key replays the original response instead of creating a duplicate.
Authentication
Requires opportunities:write permission.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Lead's full name (also used as the opportunity title) |
title | string | No | Contact's job title/position |
company | string | No | Company name |
location | string | No | Location |
headline | string | No | Contact headline |
profile_url | string | No | LinkedIn/profile URL |
profile_picture | string | No | Profile picture URL |
email | string | No | Email address (used to match an existing contact) |
phone | string | No | Phone number |
score | number | No | Lead score (default: 0) |
notes | string | No | Additional notes |
campaign_id | string | No | Associate with a campaign |
owner_user_id | string | No | Assign to a specific seller |
sector_id | string | No | Assign to a sector/team |
pipeline_id | string | No | Target pipeline |
stage_id | string | No | Target stage |
source | string | No | Lead source: linkedin, google_maps, list, paid_traffic, other (default: other) |
Optional actions
These trigger side-effects after the opportunity is created. They are non-blocking — if one fails, the opportunity is still created and the failure is reported in the actions object of the response.
| Field | Type | Required | Description |
|---|---|---|---|
activate_agent_id | string | No | Activate a WhatsApp AI agent on the contact (starts a WhatsApp conversation and runs the agent's workflow). The contact must have a phone. Overrides the pipeline's configured entry agent (see note below). |
agent_channel_account_id | string | No | Which connected WhatsApp channel to send from. Only needed if the account has more than one WhatsApp channel. |
enroll_in_flow_id | string | No | Enroll the contact into an active email flow |
send_template_email_id | string | No | Send a one-off template email to the contact (the contact must have an email) |
email_sender_id | string | No | Sender to use for send_template_email_id (defaults to the account's default sender) |
Agent activation is WhatsApp-only
activate_agent_id currently supports WhatsApp agents only (agent_type = 'whatsapp'). Passing a LinkedIn/email/other agent returns activated: false with an explanatory error in actions.agent. LinkedIn agents run through campaigns (invite → accept), not direct activation.
Pipeline entry agent (default)
A pipeline can be configured with a default entry agent (Pipeline Settings → General). When set, that agent is activated automatically for every contact added to the pipeline — including via this endpoint, even if you don't pass activate_agent_id. Precedence is: explicit activate_agent_id > the pipeline's entry agent > none. So you only need to send activate_agent_id when you want to override the pipeline default.
The WhatsApp number the agent sends from is configured on the agent itself (each active agent is bound to its number). Channel precedence: explicit agent_channel_account_id > the agent's configured number > the account's single connected number (auto).
Request
curl --request POST \
--url "https://app.getraze.com/external/v1/opportunities" \
--header "Content-Type: application/json" \
--header "X-API-Key: YOUR_API_KEY" \
--data '{
"name": "Jane Smith",
"title": "CTO",
"company": "Tech Corp",
"email": "jane@company.com",
"source": "paid_traffic",
"score": 70,
"pipeline_id": "pipe_01",
"stage_id": "stg_new",
"notes": "Inbound from Google Ads"
}'const axios = require('axios');
const response = await axios.post(
'https://app.getraze.com/external/v1/opportunities',
{
name: 'Jane Smith',
title: 'CTO',
company: 'Tech Corp',
email: 'jane@company.com',
source: 'paid_traffic',
score: 70,
pipeline_id: 'pipe_01',
stage_id: 'stg_new',
notes: 'Inbound from Google Ads'
},
{
headers: {
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
}
}
);
console.log(response.data);import requests
response = requests.post(
'https://app.getraze.com/external/v1/opportunities',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
'name': 'Jane Smith',
'title': 'CTO',
'company': 'Tech Corp',
'email': 'jane@company.com',
'source': 'paid_traffic',
'score': 70,
'pipeline_id': 'pipe_01',
'stage_id': 'stg_new',
'notes': 'Inbound from Google Ads'
}
)
print(response.json())Response
{
"success": true,
"data": {
"id": "opp_xyz789abc123",
"title": "Jane Smith",
"score": 70,
"source": "paid_traffic",
"notes": "Inbound from Google Ads",
"pipeline_id": "pipe_01",
"stage_id": "stg_new",
"campaign_id": null,
"owner_user_id": "usr_123",
"contact_id": "cnt_new001",
"contact_name": "Jane Smith",
"contact_email": "jane@company.com",
"contact_phone": null,
"contact_company": "Tech Corp",
"contact_title": "CTO",
"campaign_name": null,
"owner_user_name": "Maria Silva",
"owner_user_email": "maria@acme.com",
"created_at": "2026-01-25T09:00:00Z",
"updated_at": "2026-01-25T09:00:00Z"
}
}With optional actions
When you pass activate_agent_id, enroll_in_flow_id and/or send_template_email_id, the response includes an actions object reporting the outcome of each (the opportunity is created regardless):
{
"success": true,
"data": { "id": "opp_xyz789abc123", "...": "..." },
"actions": {
"agent": { "activated": true, "conversation_id": "conv_55", "workflow_started": true },
"flow": { "enrolled": true, "enrollment_id": "enr_12", "status": "active" },
"email": { "sent": true, "email_id": "re_abc123" }
}
}On failure, each action reports its own error without failing the request, e.g.:
"actions": {
"agent": { "activated": false, "error": "Contact has no phone number for WhatsApp" }
}Errors
| Status | Code | Description |
|---|---|---|
| 400 | VALIDATION_ERROR | name is missing, or campaign_id does not belong to your account |
Optional actions never produce a top-level error — they report success/failure inside
actions.