Skip to main content

Opportunities API

The Opportunities API allows you to retrieve and manage opportunities (sales pipeline projects) within your Drum account. Opportunities represent potential projects in the sales stage (as opposed to projects, which are accessed through the Projects API).

Ben Walker avatar
Written by Ben Walker
Updated this week

Authentication

All API requests require authentication using a Bearer token. Include your API token in the Authorization header of each request:

Authorization: Bearer YOUR_API_TOKEN

For detailed information about authentication, token generation, and permissions, see the API Authentication documentation.

All endpoints are scoped to a specific account. Only opportunities belonging to the authenticated user's account will be accessible.

The Opportunity Object

An opportunity object represents a potential client engagement or sales opportunity within Drum. To access won or active projects, you'll need to use the Projects API instead.

Core Attributes

Attribute

Type

Description

id

integer

Unique identifier for the opportunity.

name

string

The opportunity name.

description

string | null

Optional detailed description of the opportunity.

project_number

string

Unique opportunity number/code.

currency

string

Three-letter ISO currency code (e.g., "AUD", "USD", "GBP").

Classification

Attribute

Type

Description

project_type

string

Always "opportunity" for this endpoint.

Sales-Specific Dates

Attribute

Type

Description

enquiry_date

string | null

Date the opportunity enquiry was received (YYYY-MM-DD).

target_date

string | null

Target close date (configurable name via account settings).

due_date

string | null

Due date for proposal/response (if enabled, YYYY-MM-DDTHH:MM:SSZ).

deal_won_date

string | null

Date the opportunity was won (auto-set when status changes).

deal_lost_date

string | null

Date the opportunity was lost (auto-set when status changes).

estimated_start_date

string | null

Estimated project start date if won (YYYY-MM-DD).

estimated_end_date

string | null

Estimated project end date if won (YYYY-MM-DD).

Sales Information

Attribute

Type

Description

amount

decimal

Deal value/opportunity amount in currency units.

invoicing_structure

string | null

Either "payment_on_delivery" or "monthly".

estimated_deposit

decimal

Estimated deposit amount (requires view_project_metrics permission).

lead_score

object | null

Lead score details including id and name.

Associations

Attribute

Type

Description

project_status

object | null

Sales status details including id, name, and complete_status boolean.

client

object | null

Client information with id, name, and type (must be "Company" for opportunities).

team

object | null

Team assignment with id and name.

assigned_users

array

Array of assigned users with id and name.

Financial Metrics

Note: Financial data requires the view_project_metrics permission. Without this permission, these fields will not be included in the response.

Attribute

Type

Description

total_budget

decimal

Total opportunity budget in currency units.

total_invoiced

decimal

Total amount invoiced (typically 0 for opportunities).

costs_to_date

decimal

Actual costs incurred on the opportunity.

unbilled_costs

decimal

Costs not yet invoiced.

estimated_deposit

decimal

Estimated deposit amount.

Profitability Metrics

Note: These fields require the view_gross_profit permission in addition to view_project_metrics. Without this permission, these fields will not be included in the response.

Attribute

Type

Description

work_in_progress

decimal

WIP calculation (invoiced - earned revenue).

remaining_cost_to_complete

decimal

Estimated costs remaining.

Counters

Attribute

Type

Description

quotes_count

integer

Number of quotes associated with opportunity.

invoices_count

integer

Number of invoices (typically 0).

progress_claims_count

integer

Number of progress claims (typically 0).

costs_count

integer

Number of cost entries.

Metadata

Attribute

Type

Description

opportunity_tags

array of strings

Tags applied to the opportunity.

planned

boolean

Whether opportunity is in planning state.

Nested Data (Show Endpoint Only)

Attribute

Type

Description

deliverables

array

Array of deliverable objects (only in GET /opportunities/:id endpoint). See Deliverables below.

Example Object (Index)

The index endpoint returns a lightweight representation:

{
"id": 101,
"name": "Enterprise CRM Implementation",
"project_number": "OPP-042",
"description": "Implementation of Salesforce CRM for enterprise client",
"currency": "AUD",
"project_type": "opportunity",
"enquiry_date": "2025-10-01",
"target_date": "2025-12-15",
"estimated_start_date": "2026-01-15",
"estimated_end_date": "2026-06-30",
"project_status": {
"id": 2,
"name": "Proposal Submitted",
"complete_status": false
},
"client": {
"id": 456,
"name": "Enterprise Solutions Ltd",
"type": "Company"
},
"team": {
"id": 3,
"name": "Sales Team"
},
"amount": 250000.00,
"lead_score": {
"id": 4,
"name": "Hot Lead"
},
"total_budget": 250000.00,
"planned": false
}

Example Object (Show)

The show endpoint includes comprehensive details and nested data:

{
"id": 101,
"name": "Enterprise CRM Implementation",
"project_number": "OPP-042",
"description": "Implementation of Salesforce CRM for enterprise client with full data migration and training",
"currency": "AUD",
"project_type": "opportunity",
"enquiry_date": "2025-10-01",
"target_date": "2025-12-15",
"due_date": "2025-11-30T17:00:00Z",
"deal_won_date": null,
"deal_lost_date": null,
"estimated_start_date": "2026-01-15",
"estimated_end_date": "2026-06-30",
"project_status": {
"id": 2,
"name": "Proposal Submitted",
"complete_status": false
},
"client": {
"id": 456,
"name": "Enterprise Solutions Ltd",
"type": "Company"
},
"team": {
"id": 3,
"name": "Sales Team"
},
"amount": 250000.00,
"invoicing_structure": "payment_on_delivery",
"lead_score": {
"id": 4,
"name": "Hot Lead"
},
"assigned_users": [
{
"id": 12,
"name": "Sarah Johnson"
},
{
"id": 18,
"name": "Michael Chen"
}
],
"total_budget": 250000.00,
"total_invoiced": 0.00,
"costs_to_date": 5000.00,
"unbilled_costs": 5000.00,
"estimated_deposit": 50000.00,
"work_in_progress": -5000.00,
"remaining_cost_to_complete": 195000.00,
"quotes_count": 2,
"invoices_count": 0,
"progress_claims_count": 0,
"costs_count": 12,
"opportunity_tags": ["enterprise", "crm", "high-priority"],
"planned": false,
"deliverables": [
{
"id": 50,
"name": "Discovery & Requirements",
"description": "Initial discovery phase with stakeholder workshops",
"position": 1,
"status": "completed",
"billing_type": "fixed_fee",
"allow_time_tracking": "allowed",
"percentage_complete": 100,
"currency": "AUD",
"start_date": null,
"end_date": null,
"duration": 40.0,
"budget": 15000.00,
"invoiced_amount": 0.00,
"total_cost": 5000.00,
"budget_invoiced_percent": 0.0,
"plan_only": false,
"purchase_number": null,
"claim_items_count": 0,
"tasks": [
{
"id": 501,
"name": "Stakeholder Workshops",
"note": "Conduct requirements gathering workshops",
"position": 1,
"item_type": "task",
"status": "completed",
"allow_time_tracking": "allowed",
"active": true,
"visible": true,
"currency": "AUD",
"due_date": null,
"start_date": null,
"estimated_start_date": null,
"completed_date": "2025-10-15T14:30:00Z",
"budget_type": "hourly",
"original_quantity_unit": "hour",
"original_rate": 150.00,
"original_duration": 20.0,
"original_total": 3000.00,
"variation_duration": 0.0,
"variation_total": 0.0,
"actual_duration": 18.0,
"actual_total": 2700.00,
"budget": 3000.00,
"total": 3000.00,
"remaining": 300.00,
"budget_used_percentage": 90.0,
"tracked_times_count": 4,
"costs_count": 0,
"booked_bookings_count": 0,
"resource_type": {
"id": 8,
"name": "Senior Consultant"
}
}
]
}
]
}

Deliverable Object

Deliverables in opportunities represent proposed work packages or phases. The structure is identical to project deliverables. See the Projects API documentation for complete field descriptions.

Task Object

Tasks in opportunities represent proposed work items. The structure is identical to project tasks. See the Projects API documentation for complete field descriptions.


List all opportunities

Returns a paginated list of opportunities for the authenticated account. Results can be filtered using query parameters.

Endpoint

GET /api/v1/opportunities

Path Parameters

Parameter

Type

Description

account_id

integer

The ID of the account to retrieve opportunities from. Must be an account the authenticated user has access to.

Query Parameters

Parameter

Type

Description

status

integer

Filter by opportunity status ID. Only opportunities with this project_status_id will be returned.

project_status

integer

Alternative filter by status ID (same as status).

assigned_to

integer

Filter by assigned user. Provide an account_user_id to return only opportunities where that user is assigned.

opportunity_tag_list

array of strings

Filter by opportunity tags. Provide one or more tag names to return opportunities with any of those tags. Example: opportunity_tag_list[]=urgent&opportunity_tag_list[]=enterprise

lead_score

integer

Filter by lead score ID. Only opportunities with this lead_score_id will be returned.

team

integer

Filter by team ID. Provide a team_id to return only opportunities assigned to that team.

estimated_start_date

string

Filter by estimated start date (from). Returns opportunities with estimated_start_date >= this date. Format: YYYY-MM-DD.

estimated_end_date

string

Filter by estimated end date (to). Returns opportunities with estimated_end_date <= this date. Format: YYYY-MM-DD.

page

integer

Page number for pagination. Defaults to 1.

items

integer

Number of items per page. Defaults to 20.

Example Request

curl https://app.getdrum.com/api/v1/opportunities \
-H "Authorization: Bearer YOUR_API_TOKEN"

Example Request with Filters

curl "https://app.getdrum.com/api/v1/opportunities?status=2&lead_score=4&team=3&page=1&items=50" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Example Request with Tags and Date Range

curl "https://app.getdrum.com/api/v1/opportunities?opportunity_tag_list[]=enterprise&estimated_start_date=2026-01-01&estimated_end_date=2026-12-31" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Response

Returns an array of opportunity objects. The index endpoint returns a lightweight representation without nested deliverables/tasks.

Note: Financial fields (total_budget, estimated_deposit) are only included if the user has the view_project_metrics permission.

[
{
"id": 101,
"name": "Enterprise CRM Implementation",
"project_number": "OPP-042",
"description": "Implementation of Salesforce CRM for enterprise client",
"currency": "AUD",
"project_type": "opportunity",
"enquiry_date": "2025-10-01",
"target_date": "2025-12-15",
"estimated_start_date": "2026-01-15",
"estimated_end_date": "2026-06-30",
"project_status": {
"id": 2,
"name": "Proposal Submitted",
"complete_status": false
},
"client": {
"id": 456,
"name": "Enterprise Solutions Ltd",
"type": "Company"
},
"team": {
"id": 3,
"name": "Sales Team"
},
"amount": 250000.00,
"lead_score": {
"id": 4,
"name": "Hot Lead"
},
"total_budget": 250000.00,
"planned": false
},
{
"id": 102,
"name": "Website Redesign - Tech Startup",
"project_number": "OPP-043",
"description": "Complete website redesign and rebrand",
"currency": "AUD",
"project_type": "opportunity",
"enquiry_date": "2025-10-15",
"target_date": "2026-01-31",
"estimated_start_date": "2026-02-01",
"estimated_end_date": "2026-04-30",
"project_status": {
"id": 1,
"name": "Proposal In Progress",
"complete_status": false
},
"client": {
"id": 457,
"name": "Tech Startup Co",
"type": "Company"
},
"team": {
"id": 2,
"name": "Design Team"
},
"amount": 75000.00,
"lead_score": {
"id": 3,
"name": "Warm Lead"
},
"total_budget": 75000.00,
"planned": false
}
]

Note: The API uses pagination via the page and items query parameters. Use pagination metadata from response headers if available, or implement client-side pagination based on the number of results returned.


Retrieve an opportunity

Retrieves the details of a specific opportunity by ID.

Endpoint

GET /api/v1/opportunities/:id

Path Parameters

Parameter

Type

Description

account_id

integer

The ID of the account the opportunity belongs to.

id

integer

The ID of the opportunity to retrieve.

Example Request

curl https://app.getdrum.com/api/v1/opportunities/101 \
-H "Authorization: Bearer YOUR_API_TOKEN"

Response

Returns a comprehensive opportunity object with nested deliverables and tasks.

Note: Financial fields require appropriate permissions:

  • Basic financial data (total_budget, total_invoiced, etc.) requires view_project_metrics permission

  • Profitability metrics (work_in_progress, remaining_cost_to_complete) require both view_project_metrics AND view_gross_profit permissions

Note: If the requested project ID exists but is a won project (not an opportunity), the endpoint will return a 404 Not Found error. Use the Projects API to access won projects.

{
"id": 101,
"name": "Enterprise CRM Implementation",
"project_number": "OPP-042",
"description": "Implementation of Salesforce CRM for enterprise client with full data migration and training",
"currency": "AUD",
"project_type": "opportunity",
"enquiry_date": "2025-10-01",
"target_date": "2025-12-15",
"due_date": "2025-11-30T17:00:00Z",
"deal_won_date": null,
"deal_lost_date": null,
"estimated_start_date": "2026-01-15",
"estimated_end_date": "2026-06-30",
"project_status": {
"id": 2,
"name": "Proposal Submitted",
"complete_status": false
},
"client": {
"id": 456,
"name": "Enterprise Solutions Ltd",
"type": "Company"
},
"team": {
"id": 3,
"name": "Sales Team"
},
"amount": 250000.00,
"invoicing_structure": "payment_on_delivery",
"lead_score": {
"id": 4,
"name": "Hot Lead"
},
"assigned_users": [
{
"id": 12,
"name": "Sarah Johnson"
},
{
"id": 18,
"name": "Michael Chen"
}
],
"total_budget": 250000.00,
"total_invoiced": 0.00,
"costs_to_date": 5000.00,
"unbilled_costs": 5000.00,
"estimated_deposit": 50000.00,
"work_in_progress": -5000.00,
"remaining_cost_to_complete": 195000.00,
"quotes_count": 2,
"invoices_count": 0,
"progress_claims_count": 0,
"costs_count": 12,
"opportunity_tags": ["enterprise", "crm", "high-priority"],
"planned": false,
"deliverables": [
{
"id": 50,
"name": "Discovery & Requirements",
"description": "Initial discovery phase with stakeholder workshops",
"position": 1,
"status": "completed",
"billing_type": "fixed_fee",
"allow_time_tracking": "allowed",
"percentage_complete": 100,
"currency": "AUD",
"start_date": null,
"end_date": null,
"duration": 40.0,
"budget": 15000.00,
"invoiced_amount": 0.00,
"total_cost": 5000.00,
"budget_invoiced_percent": 0.0,
"plan_only": false,
"purchase_number": null,
"claim_items_count": 0,
"tasks": [
{
"id": 501,
"name": "Stakeholder Workshops",
"note": "Conduct requirements gathering workshops",
"position": 1,
"item_type": "task",
"status": "completed",
"allow_time_tracking": "allowed",
"active": true,
"visible": true,
"currency": "AUD",
"due_date": null,
"start_date": null,
"estimated_start_date": null,
"completed_date": "2025-10-15T14:30:00Z",
"budget_type": "hourly",
"original_quantity_unit": "hour",
"original_rate": 150.00,
"original_duration": 20.0,
"original_total": 3000.00,
"variation_duration": 0.0,
"variation_total": 0.0,
"actual_duration": 18.0,
"actual_total": 2700.00,
"budget": 3000.00,
"total": 3000.00,
"remaining": 300.00,
"budget_used_percentage": 90.0,
"tracked_times_count": 4,
"costs_count": 0,
"booked_bookings_count": 0,
"resource_type": {
"id": 8,
"name": "Senior Consultant"
}
},
{
"id": 502,
"name": "Requirements Documentation",
"note": null,
"position": 2,
"item_type": "task",
"status": "completed",
"allow_time_tracking": "allowed",
"active": true,
"visible": true,
"currency": "AUD",
"due_date": null,
"start_date": null,
"estimated_start_date": null,
"completed_date": "2025-10-20T16:00:00Z",
"budget_type": "hourly",
"original_quantity_unit": "hour",
"original_rate": 125.00,
"original_duration": 20.0,
"original_total": 2500.00,
"variation_duration": 0.0,
"variation_total": 0.0,
"actual_duration": 18.0,
"actual_total": 2250.00,
"budget": 2500.00,
"total": 2500.00,
"remaining": 250.00,
"budget_used_percentage": 90.0,
"tracked_times_count": 3,
"costs_count": 0,
"booked_bookings_count": 0,
"resource_type": {
"id": 9,
"name": "Business Analyst"
}
}
]
},
{
"id": 51,
"name": "Implementation Phase",
"description": "CRM configuration and data migration",
"position": 2,
"status": "not_started",
"billing_type": "fixed_fee",
"allow_time_tracking": "allowed",
"percentage_complete": 0,
"currency": "AUD",
"start_date": null,
"end_date": null,
"duration": 200.0,
"budget": 180000.00,
"invoiced_amount": 0.00,
"total_cost": 0.00,
"budget_invoiced_percent": 0.0,
"plan_only": false,
"purchase_number": null,
"claim_items_count": 0,
"tasks": [
{
"id": 503,
"name": "System Configuration",
"note": "Configure Salesforce to requirements",
"position": 1,
"item_type": "task",
"status": "not_started",
"allow_time_tracking": "allowed",
"active": true,
"visible": true,
"currency": "AUD",
"due_date": null,
"start_date": null,
"estimated_start_date": null,
"completed_date": null,
"budget_type": "hourly",
"original_quantity_unit": "hour",
"original_rate": 150.00,
"original_duration": 80.0,
"original_total": 12000.00,
"variation_duration": 0.0,
"variation_total": 0.0,
"actual_duration": 0.0,
"actual_total": 0.0,
"budget": 12000.00,
"total": 12000.00,
"remaining": 12000.00,
"budget_used_percentage": 0.0,
"tracked_times_count": 0,
"costs_count": 0,
"booked_bookings_count": 0,
"resource_type": {
"id": 10,
"name": "Salesforce Developer"
}
}
]
}
]
}

Error Responses

The Opportunities API uses standard HTTP response codes to indicate success or failure.

HTTP Status Codes

Status Code

Description

200

Success - The request was successful.

401

Unauthorised - Missing, invalid, or expired API token.

403

Forbidden - The authenticated user lacks the required API permissions (api_read, api_create, api_update, or api_delete).

404

Not Found - The requested account or opportunity does not exist, the authenticated user does not have access, or the ID refers to a won project (not an opportunity).

Error Response Format

Error responses include a standard structure with details about what went wrong:

{
"error": "Forbidden"
}

Common Error Scenarios

401 Unauthorised

Occurs when:

  • No Authorisation header is provided

  • The API token is invalid or malformed

  • The API token has expired

Solution: Verify your API token is valid and properly included in the Authorisation header.

403 Forbidden

Occurs when:

  • The authenticated user's role lacks the required API permissions

  • The account user has been archived or deactivated

Solution: Contact your account administrator to verify your API permissions. Admin users automatically have all API permissions.

404 Not Found

Occurs when:

  • The specified account ID doesn't exist or you don't have access

  • The specified opportunity ID doesn't exist within the account

  • The ID refers to a won project (use the Projects API instead)

  • The opportunity exists but belongs to a different account

Solution: Verify the account_id and opportunity id are correct and that you have access to the account. If you receive a 404 when you know the ID exists, check if it's a won project (project_type: "project") rather than an opportunity.


Rate Limiting

Currently, rate limiting is not enforced on API requests. However, infrastructure is in place for future rate limiting:

  • General API: 300 requests per 5 minutes per IP address

  • Per endpoint throttling may be introduced as needed

We recommend implementing exponential backoff in your API client to handle potential future rate limits gracefully.


API Permissions

The Opportunities API requires multiple levels of permissions:

Base API Permissions

Required based on HTTP method:

Method

Required Permission

GET

api_read

POST

api_create

PUT/PATCH

api_update

DELETE

api_delete

Opportunity Visibility Permissions

In addition to api_read, users need one of the following permissions to view opportunities:

Permission

Description

read_all_opportunities

Access all opportunities in the account

read_team_opportunities

Access opportunities assigned to team members

read_assigned_opportunities

Access only opportunities where user is directly assigned

Note: Opportunities use the OpportunityPolicy which is separate from the ProjectPolicy. The permission names may vary slightly between projects and opportunities based on your account's configuration.

Financial Data Permissions

Financial data visibility is controlled by additional permissions:

Permission

Data Included

view_project_metrics

Basic financial data: total_budget, total_invoiced, costs_to_date, unbilled_costs, estimated_deposit, and all task/deliverable financial fields

view_gross_profit

Profitability metrics: work_in_progress, remaining_cost_to_complete (requires view_project_metrics as well)

Note: Without these permissions, financial fields will be completely excluded from API responses. This ensures sensitive financial data is only visible to authorised users.

Permission Hierarchy

  • Account administrators automatically have all API permissions

  • Other users must be granted permissions through their account role configuration

  • Financial permissions are additive: view_gross_profit requires view_project_metrics to be useful


Notes

  • Opportunities vs Projects: This endpoint returns only opportunities (sales pipeline, project_type: "opportunity"). Won projects (project_type: "project") are accessed through the Projects API.

  • Client Restrictions: Opportunities can only be associated with Company clients, not BusinessOverhead. This is enforced at the model level.

  • Sales Statuses: Opportunities use sales-specific project statuses (won, lost, proposal in progress, etc.) which are separate from project statuses.

  • Auto-Dated Fields: deal_won_date and deal_lost_date are automatically set when the opportunity status changes to a "won" or "lost" status type.

  • Multitenancy: All opportunities are scoped to accounts. Users can only access opportunities from accounts they belong to.

  • Authorization: The API enforces permission-based access using OpportunityPolicy. Users are restricted to opportunities they have permission to view based on their role configuration.

  • Soft Deletes: Deleted opportunities are soft-deleted (archived) rather than permanently removed. Archived opportunities are not returned by the API.

  • Money Format: All monetary amounts are returned in decimal format (e.g., 250000.00 for $250,000). The currency field indicates the currency code.

  • Date Format: Dates are returned in ISO 8601 format (YYYY-MM-DD). Datetimes include time zone information (YYYY-MM-DDTHH:MM:SSZ).

  • Nested Data: The show endpoint includes nested deliverables and tasks arrays, ordered by position field. The index endpoint excludes this nested data for performance.

  • Permission-Gated Fields: Financial and profitability data are conditionally included based on user permissions. API clients should handle missing fields gracefully.

  • Eager Loading: The API uses efficient eager loading to minimize database queries. Large opportunities with many deliverables/tasks may still result in substantial response payloads.

  • Lead Scoring: The lead_score association helps prioritize opportunities. Lead scores are configured per account and can be customized.

  • Assigned Users: Unlike projects which use role-based assignments, opportunities use a simpler assignment model where users are directly assigned to opportunities without specific roles.

Did this answer your question?