Blue Reacher
Opportunities29 / 46

Opportunities

Pipelines, their stages, and the opportunities (deals) moving through them.

Pipelines, their stages, and the opportunities (deals) moving through them.

Every route takes Authorization: Bearer <ACCESS_TOKEN> unless the auth line says otherwise. Ids are numbers. Errors use the shape on the errors page.

RouteScopeWhat it does
GET /v1/pipelinesopportunities.readA workspace's pipelines, each with its stages in order.
GET /v1/opportunitiesopportunities.readOpportunities in a workspace, filtered and paginated.
GET /v1/opportunities/{id}opportunities.readOne opportunity with its pipeline, stage and contact.
POST /v1/opportunitiesopportunities.writeCreate an opportunity for a contact.
PATCH /v1/opportunities/{id}opportunities.writeChange name, value, currency, source, owner, tags or custom fields.
PATCH /v1/opportunities/{id}/stageopportunities.writeMove an opportunity to another stage of its pipeline.
PATCH /v1/opportunities/{id}/statusopportunities.writeWin, lose, abandon or reopen an opportunity.
DELETE /v1/opportunities/{id}opportunities.writeDelete an opportunity.
GET /v1/opportunities/{id}/activitiesopportunities.readAn opportunity's history, newest first.

List pipelines

GET https://api.bluereacher.com/v1/pipelines

Auth: Bearer access token. Scope: opportunities.read.

A workspace's pipelines, each with its stages in order.

A workspace that has never opened its Pipeline gets the default pipeline created on the first call, as in the Blue Reacher dashboard.

Use a stage id from here for Create opportunity and Move stage. is_won / is_lost mark the closing stages.

Parameters

NameInTypeRequiredDescription
workspace_idquerynumberyesThe workspace.

Request

curl -X GET "https://api.bluereacher.com/v1/pipelines?workspace_id=7" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (OK):

{
  "success": true,
  "data": [
    {
      "id": 3,
      "name": "Sales",
      "is_default": true,
      "position": 0,
      "stages": [
        {
          "id": 8,
          "name": "New lead",
          "color": "#94a3b8",
          "position": 0,
          "is_won": false,
          "is_lost": false
        },
        {
          "id": 9,
          "name": "Qualified",
          "color": "#22c55e",
          "position": 1,
          "is_won": false,
          "is_lost": false
        },
        {
          "id": 10,
          "name": "Won",
          "color": "#16a34a",
          "position": 2,
          "is_won": true,
          "is_lost": false
        }
      ],
      "created_at": "2026-09-01T10:00:00.000Z",
      "updated_at": "2026-10-01T10:00:00.000Z"
    }
  ]
}
StatusWhenMessage
200OK
400workspace_id missingworkspace_id is required
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.read. This integration was granted: …
404workspace_id does not exist or is not owned by the installer (same response for both)Workspace not found or not accessible to this token

List opportunities

GET https://api.bluereacher.com/v1/opportunities

Auth: Bearer access token. Scope: opportunities.read.

Opportunities in a workspace, filtered and paginated.

Filters combine with AND. search matches the opportunity name or the linked contact's name or email.

Parameters

NameInTypeRequiredDescription
workspace_idquerynumberyesThe workspace.
pipeline_idquerynumbernoOnly this pipeline.
stage_idquerynumbernoOnly this stage.
statusqueryenumnoOnly this status.
contact_idquerynumbernoOnly this contact's opportunities.
owner_idquerynumbernoOnly this owner.
sourcequerystringnoSource contains this text.
searchquerystringnoName, or contact name / email.
sortqueryenumnoDefault created_at.
orderqueryenumnoDefault desc.
pagequerynumbernoDefault 1.
limitquerynumberno1–100, default 20. Anything else is a 400.

Request

curl -X GET "https://api.bluereacher.com/v1/opportunities?workspace_id=7&page=1&limit=20" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (OK):

{
  "success": true,
  "data": [
    {
      "id": 55,
      "workspace_id": 7,
      "name": "Website redesign",
      "value": 1200,
      "currency": "USD",
      "status": "open",
      "lost_reason": null,
      "pipeline_id": 3,
      "pipeline": {
        "id": 3,
        "name": "Sales"
      },
      "stage_id": 9,
      "stage": {
        "id": 9,
        "name": "Qualified",
        "color": "#22c55e",
        "position": 1,
        "is_won": false,
        "is_lost": false
      },
      "contact_id": 1234,
      "contact": {
        "id": 1234,
        "first_name": "Ann",
        "last_name": "Lee",
        "email": "ann@example.com",
        "phone_number": "+61412345678",
        "company_name": "Lee Studio"
      },
      "owner_id": null,
      "source": "website",
      "tags": [
        "web"
      ],
      "custom_fields": {},
      "closed_at": null,
      "stage_changed_at": "2026-10-27T09:00:00.000Z",
      "last_activity_at": "2026-10-27T09:00:00.000Z",
      "created_at": "2026-10-27T09:00:00.000Z",
      "updated_at": "2026-10-27T09:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "max_limit": 100,
    "total": 1,
    "total_pages": 1,
    "sort": "created_at",
    "order": "desc"
  }
}
StatusWhenMessage
200OK
400workspace_id missingworkspace_id is required
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.read. This integration was granted: …
404workspace_id does not exist or is not owned by the installer (same response for both)Workspace not found or not accessible to this token

Response fields

opportunity: Each item in data. Fields:

FieldTypeDescription
idnumberOpportunity id. Example: 55
workspace_idnumberThe workspace it belongs to. Example: 7
namestringOpportunity name. Example: Website redesign
valuenumberDeal value. Example: 1200
currencystringISO currency code. Example: USD
statusstring"open", "won", "lost" or "abandoned". Example: open
lost_reasonstring, nullableSet while status is "lost".
pipelineobjectid and name of its pipeline.
stageobjectid, name, color, position, is_won, is_lost of its stage.
contactobjectThe linked contact: id, first_name, last_name, email, phone_number, company_name.
owner_idnumber, nullableThe assigned user, when set.
sourcestring, nullableFree text: where the deal came from.
tagsarray<string>Opportunity tags.
custom_fieldsobjectOpportunity custom field values by key.
closed_atstring (ISO 8601), nullableWhen it was won / lost / abandoned; null while open.
stage_changed_atstring (ISO 8601)When it entered its current stage.
last_activity_atstring (ISO 8601)Last change of any kind.

Get opportunity

GET https://api.bluereacher.com/v1/opportunities/{id}

Auth: Bearer access token. Scope: opportunities.read.

One opportunity with its pipeline, stage and contact.

Parameters

NameInTypeRequiredDescription
idpathnumberyesOpportunity id.

Request

curl -X GET "https://api.bluereacher.com/v1/opportunities/55" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (OK):

{
  "success": true,
  "data": {
    "id": 55,
    "workspace_id": 7,
    "name": "Website redesign",
    "value": 1200,
    "currency": "USD",
    "status": "open",
    "lost_reason": null,
    "pipeline_id": 3,
    "pipeline": {
      "id": 3,
      "name": "Sales"
    },
    "stage_id": 9,
    "stage": {
      "id": 9,
      "name": "Qualified",
      "color": "#22c55e",
      "position": 1,
      "is_won": false,
      "is_lost": false
    },
    "contact_id": 1234,
    "contact": {
      "id": 1234,
      "first_name": "Ann",
      "last_name": "Lee",
      "email": "ann@example.com",
      "phone_number": "+61412345678",
      "company_name": "Lee Studio"
    },
    "owner_id": null,
    "source": "website",
    "tags": [
      "web"
    ],
    "custom_fields": {},
    "closed_at": null,
    "stage_changed_at": "2026-10-27T09:00:00.000Z",
    "last_activity_at": "2026-10-27T09:00:00.000Z",
    "created_at": "2026-10-27T09:00:00.000Z",
    "updated_at": "2026-10-27T09:00:00.000Z"
  }
}
StatusWhenMessage
200OK
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.read. This integration was granted: …
404Opportunity does not exist or is not owned by the installerOpportunity not found or not accessible to this token

Response fields

opportunity. Fields:

FieldTypeDescription
idnumberOpportunity id. Example: 55
workspace_idnumberThe workspace it belongs to. Example: 7
namestringOpportunity name. Example: Website redesign
valuenumberDeal value. Example: 1200
currencystringISO currency code. Example: USD
statusstring"open", "won", "lost" or "abandoned". Example: open
lost_reasonstring, nullableSet while status is "lost".
pipelineobjectid and name of its pipeline.
stageobjectid, name, color, position, is_won, is_lost of its stage.
contactobjectThe linked contact: id, first_name, last_name, email, phone_number, company_name.
owner_idnumber, nullableThe assigned user, when set.
sourcestring, nullableFree text: where the deal came from.
tagsarray<string>Opportunity tags.
custom_fieldsobjectOpportunity custom field values by key.
closed_atstring (ISO 8601), nullableWhen it was won / lost / abandoned; null while open.
stage_changed_atstring (ISO 8601)When it entered its current stage.
last_activity_atstring (ISO 8601)Last change of any kind.

Create opportunity

POST https://api.bluereacher.com/v1/opportunities

Auth: Bearer access token. Scope: opportunities.write.

Create an opportunity for a contact.

The contact must be in the workspace. Without pipeline_id the default pipeline is used; without stage_id the stage named in stage_name is used, else the pipeline's first stage.

Creating one runs any workflow that triggers on Opportunity created, as in the dashboard.

Parameters

NameInTypeRequiredDescription
workspace_idbodynumberyesThe workspace.
contact_idbodynumberyesA contact in that workspace.
namebodystringyesUp to 191 characters.
pipeline_idbodynumbernoDefault: the default pipeline.
stage_idbodynumbernoA stage of that pipeline.
stage_namebodystringnoOr the stage by name (case-insensitive).
valuebodynumbernoDefault 0.
currencybodystringnoDefault USD.
statusbodyenumnoDefault open.
sourcebodystringnoWhere it came from.
owner_idbodynumbernoThe assigned user.
tagsbodyarray<string>noOpportunity tags.
custom_fieldsbodyobjectnoOpportunity custom field values by key.

Request

curl -X POST "https://api.bluereacher.com/v1/opportunities" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
  "workspace_id": 7,
  "contact_id": 1234,
  "name": "Website redesign",
  "value": 1200,
  "stage_name": "Qualified",
  "source": "website"
}'

Responses

A 201 reply (Created):

{
  "success": true,
  "message": "Opportunity created",
  "data": {
    "id": 55,
    "workspace_id": 7,
    "name": "Website redesign",
    "value": 1200,
    "currency": "USD",
    "status": "open",
    "lost_reason": null,
    "pipeline_id": 3,
    "pipeline": {
      "id": 3,
      "name": "Sales"
    },
    "stage_id": 9,
    "stage": {
      "id": 9,
      "name": "Qualified",
      "color": "#22c55e",
      "position": 1,
      "is_won": false,
      "is_lost": false
    },
    "contact_id": 1234,
    "contact": {
      "id": 1234,
      "first_name": "Ann",
      "last_name": "Lee",
      "email": "ann@example.com",
      "phone_number": "+61412345678",
      "company_name": "Lee Studio"
    },
    "owner_id": null,
    "source": "website",
    "tags": [
      "web"
    ],
    "custom_fields": {},
    "closed_at": null,
    "stage_changed_at": "2026-10-27T09:00:00.000Z",
    "last_activity_at": "2026-10-27T09:00:00.000Z",
    "created_at": "2026-10-27T09:00:00.000Z",
    "updated_at": "2026-10-27T09:00:00.000Z"
  }
}
StatusWhenMessage
201Created
400Missing field, or a contact / pipeline / stage that does not fitContact not found in this workspace
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.write. This integration was granted: …
404workspace_id does not exist or is not owned by the installer (same response for both)Workspace not found or not accessible to this token

Response fields

opportunity. Fields:

FieldTypeDescription
idnumberOpportunity id. Example: 55
workspace_idnumberThe workspace it belongs to. Example: 7
namestringOpportunity name. Example: Website redesign
valuenumberDeal value. Example: 1200
currencystringISO currency code. Example: USD
statusstring"open", "won", "lost" or "abandoned". Example: open
lost_reasonstring, nullableSet while status is "lost".
pipelineobjectid and name of its pipeline.
stageobjectid, name, color, position, is_won, is_lost of its stage.
contactobjectThe linked contact: id, first_name, last_name, email, phone_number, company_name.
owner_idnumber, nullableThe assigned user, when set.
sourcestring, nullableFree text: where the deal came from.
tagsarray<string>Opportunity tags.
custom_fieldsobjectOpportunity custom field values by key.
closed_atstring (ISO 8601), nullableWhen it was won / lost / abandoned; null while open.
stage_changed_atstring (ISO 8601)When it entered its current stage.
last_activity_atstring (ISO 8601)Last change of any kind.

Update opportunity

PATCH https://api.bluereacher.com/v1/opportunities/{id}

Auth: Bearer access token. Scope: opportunities.write.

Change name, value, currency, source, owner, tags or custom fields.

To move it to another stage use Move stage; to win, lose or reopen it use Change status. Those run their own workflow triggers.

Parameters

NameInTypeRequiredDescription
idpathnumberyesOpportunity id.
namebodystringnoUp to 191 characters.
valuebodynumbernoDeal value.
currencybodystringnoISO currency code.
sourcebodystringnoWhere it came from.
owner_idbodynumbernoThe assigned user.
tagsbodyarray<string>noReplaces the tags.
custom_fieldsbodyobjectnoCustom field values by key.

Request

curl -X PATCH "https://api.bluereacher.com/v1/opportunities/55" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
  "value": 1500
}'

Responses

A 200 reply (OK):

{
  "success": true,
  "message": "Opportunity updated",
  "data": {
    "id": 55,
    "workspace_id": 7,
    "name": "Website redesign",
    "value": 1500,
    "currency": "USD",
    "status": "open",
    "lost_reason": null,
    "pipeline_id": 3,
    "pipeline": {
      "id": 3,
      "name": "Sales"
    },
    "stage_id": 9,
    "stage": {
      "id": 9,
      "name": "Qualified",
      "color": "#22c55e",
      "position": 1,
      "is_won": false,
      "is_lost": false
    },
    "contact_id": 1234,
    "contact": {
      "id": 1234,
      "first_name": "Ann",
      "last_name": "Lee",
      "email": "ann@example.com",
      "phone_number": "+61412345678",
      "company_name": "Lee Studio"
    },
    "owner_id": null,
    "source": "website",
    "tags": [
      "web"
    ],
    "custom_fields": {},
    "closed_at": null,
    "stage_changed_at": "2026-10-27T09:00:00.000Z",
    "last_activity_at": "2026-10-27T09:00:00.000Z",
    "created_at": "2026-10-27T09:00:00.000Z",
    "updated_at": "2026-10-27T09:00:00.000Z"
  }
}
StatusWhenMessage
200OK
400Nothing to updateNothing to update — send name, value, currency, source, owner_id, tags or custom_fields.
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.write. This integration was granted: …
404Opportunity does not exist or is not owned by the installerOpportunity not found or not accessible to this token

Move stage

PATCH https://api.bluereacher.com/v1/opportunities/{id}/stage

Auth: Bearer access token. Scope: opportunities.write.

Move an opportunity to another stage of its pipeline.

Runs any workflow that triggers on Opportunity stage changed. Moving it to the stage it is already in changes nothing.

Parameters

NameInTypeRequiredDescription
idpathnumberyesOpportunity id.
stage_idbodynumberyesA stage of the same pipeline (from List pipelines).

Request

curl -X PATCH "https://api.bluereacher.com/v1/opportunities/55/stage" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
  "stage_id": 10
}'

Responses

A 200 reply (OK):

{
  "success": true,
  "message": "Stage changed",
  "data": {
    "id": 55,
    "workspace_id": 7,
    "name": "Website redesign",
    "value": 1200,
    "currency": "USD",
    "status": "open",
    "lost_reason": null,
    "pipeline_id": 3,
    "pipeline": {
      "id": 3,
      "name": "Sales"
    },
    "stage_id": 10,
    "stage": {
      "id": 10,
      "name": "Won",
      "color": "#16a34a",
      "position": 2,
      "is_won": true,
      "is_lost": false
    },
    "contact_id": 1234,
    "contact": {
      "id": 1234,
      "first_name": "Ann",
      "last_name": "Lee",
      "email": "ann@example.com",
      "phone_number": "+61412345678",
      "company_name": "Lee Studio"
    },
    "owner_id": null,
    "source": "website",
    "tags": [
      "web"
    ],
    "custom_fields": {},
    "closed_at": null,
    "stage_changed_at": "2026-10-27T09:00:00.000Z",
    "last_activity_at": "2026-10-27T09:00:00.000Z",
    "created_at": "2026-10-27T09:00:00.000Z",
    "updated_at": "2026-10-27T09:00:00.000Z"
  }
}
StatusWhenMessage
200OK
400Missing or foreign stagestage_id is required
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.write. This integration was granted: …
404Opportunity does not exist or is not owned by the installerOpportunity not found or not accessible to this token

Change status

PATCH https://api.bluereacher.com/v1/opportunities/{id}/status

Auth: Bearer access token. Scope: opportunities.write.

Win, lose, abandon or reopen an opportunity.

Runs any workflow that triggers on Opportunity status changed. lost_reason is kept only while the status is "lost"; reopening clears it.

Parameters

NameInTypeRequiredDescription
idpathnumberyesOpportunity id.
statusbodyenumyesThe new status.
lost_reasonbodystringnoUp to 255 characters, for "lost".

Request

curl -X PATCH "https://api.bluereacher.com/v1/opportunities/55/status" \
  -H "Authorization: Bearer <ACCESS_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "lost",
  "lost_reason": "Went with another agency"
}'

Responses

A 200 reply (OK):

{
  "success": true,
  "message": "Status changed",
  "data": {
    "id": 55,
    "workspace_id": 7,
    "name": "Website redesign",
    "value": 1200,
    "currency": "USD",
    "status": "lost",
    "lost_reason": "Went with another agency",
    "pipeline_id": 3,
    "pipeline": {
      "id": 3,
      "name": "Sales"
    },
    "stage_id": 9,
    "stage": {
      "id": 9,
      "name": "Qualified",
      "color": "#22c55e",
      "position": 1,
      "is_won": false,
      "is_lost": false
    },
    "contact_id": 1234,
    "contact": {
      "id": 1234,
      "first_name": "Ann",
      "last_name": "Lee",
      "email": "ann@example.com",
      "phone_number": "+61412345678",
      "company_name": "Lee Studio"
    },
    "owner_id": null,
    "source": "website",
    "tags": [
      "web"
    ],
    "custom_fields": {},
    "closed_at": "2026-10-28T11:00:00.000Z",
    "stage_changed_at": "2026-10-27T09:00:00.000Z",
    "last_activity_at": "2026-10-27T09:00:00.000Z",
    "created_at": "2026-10-27T09:00:00.000Z",
    "updated_at": "2026-10-27T09:00:00.000Z"
  }
}
StatusWhenMessage
200OK
400Unknown statusstatus must be one of: open, won, lost, abandoned
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.write. This integration was granted: …
404Opportunity does not exist or is not owned by the installerOpportunity not found or not accessible to this token

Delete opportunity

DELETE https://api.bluereacher.com/v1/opportunities/{id}

Auth: Bearer access token. Scope: opportunities.write.

Delete an opportunity.

Parameters

NameInTypeRequiredDescription
idpathnumberyesOpportunity id.

Request

curl -X DELETE "https://api.bluereacher.com/v1/opportunities/55" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (OK):

{
  "success": true,
  "message": "Opportunity deleted"
}
StatusWhenMessage
200OK
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.write. This integration was granted: …
404Opportunity does not exist or is not owned by the installerOpportunity not found or not accessible to this token

List activities

GET https://api.bluereacher.com/v1/opportunities/{id}/activities

Auth: Bearer access token. Scope: opportunities.read.

An opportunity's history, newest first.

One row per change: created, stage changed, status changed, value changed and so on. details carries what changed.

Parameters

NameInTypeRequiredDescription
idpathnumberyesOpportunity id.
pagequerynumbernoDefault 1.
limitquerynumberno1–100, default 20. Anything else is a 400.

Request

curl -X GET "https://api.bluereacher.com/v1/opportunities/55/activities" \
  -H "Authorization: Bearer <ACCESS_TOKEN>"

Responses

A 200 reply (OK):

{
  "success": true,
  "data": [
    {
      "id": 2,
      "type": "stage_changed",
      "from_stage": {
        "id": 8,
        "name": "New lead"
      },
      "to_stage": {
        "id": 9,
        "name": "Qualified"
      },
      "from_status": null,
      "to_status": null,
      "details": null,
      "created_at": "2026-10-27T10:00:00.000Z"
    },
    {
      "id": 1,
      "type": "created",
      "from_stage": null,
      "to_stage": {
        "id": 8,
        "name": "New lead"
      },
      "from_status": null,
      "to_status": "open",
      "details": {
        "to_value": 1200
      },
      "created_at": "2026-10-27T09:00:00.000Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "max_limit": 100,
    "total": 2,
    "total_pages": 1
  }
}
StatusWhenMessage
200OK
401Missing or invalid tokenInvalid or expired access token.
403Missing scopeMissing scope(s): opportunities.read. This integration was granted: …
404Opportunity does not exist or is not owned by the installerOpportunity not found or not accessible to this token

On this page