Coming soon · Contract draft
Opportunities & Pipeline
A commercial opportunity graph from account and scope through pipeline forecast and governed engagement promotion.
Reviewable specification — not callable
Canonical owner
Opportunity, pipeline, scope, and promotion services
Contract posture
P1 · Documentation first · implementation follows approval
Contract metadata
Draft version
0.2 review draft
Review owner
Commercial/Knowledge + Developer Platform
Last reviewed
July 14, 2026
Target wave
Wave 4 · Commercial lifecycle
Contract dependencies
- • Canonical identity and provider mapping policy
- • Field-level visibility rules
- • Transactional event outbox
What this unlocks
Integrate deal lifecycle
Read a stable domain model for opportunities & pipeline without depending on GUI routes or database shapes.
Draft delivery scope
Create a reviewable proposal and apply only the bounded commands the canonical owner permits.
Promote won work safely
React to durable lifecycle facts and connect external systems with explicit direction and provenance.
Lifecycle and invariants
Opportunities & Pipeline exposes a bounded lifecycle with explicit commands and named authority at every transition.
openqualifiedproposalwonlostpromoted| From | To | Command | Authority |
|---|---|---|---|
| open | qualified | Qualify opportunity | Opportunity and promotion services |
| qualified | proposal | Publish proposal | Opportunity and promotion services |
| proposal | won | Record win | Opportunity and promotion services |
| won | promoted | Promote to engagement | Opportunity and promotion services |
Lifecycle invariants
- • Promotion is idempotent and creates one engagement identity.
- • Rates remain separately scoped.
Authority boundaries
The interfaces expose canonical capabilities; they do not become a second owner of domain rules or state.
DigitalStack owns
- • Canonical opportunity and stage lifecycle
- • Delivery scope and forecast
- • Promotion mapping into commercial engagement
Explicitly not building
- • Silent won/lost decisions
- • Rate access through ordinary CRM scopes
- • Duplicate project identity during promotion
Surface decisions
Deliberate additions, retained boundaries, and removals from the proposed external contract.
Lifecycle, scope, workstreams, forecast, rate, pipeline, and promotion resources
The API should cover the deal-to-delivery boundary explicitly.
Confirmed promotion into commercial engagement
A CRM stage change alone must not create delivery state.
Silent won/lost decisions and rates under general opportunity read
Commercial decisions and sensitive financial data require distinct authority.
Interface plan
REST API
PlannedVersioned opportunities & pipeline resources, commands, idempotency, and operation status.
Reads + explicit commands
GraphQL
PlannedComposable Opportunity reads with mutations delegated to the same canonical domain service.
Composable reads + bounded delegated mutations
MCP / Agent API
PlannedBounded read, draft, and confirmed apply tools with evidence and audit attribution.
Read + proposal/confirmed commands only
Webhooks
PlannedPast-tense opportunity lifecycle facts with minimal payloads.
Past-tense durable facts only
Connected Apps
PlannedSalesforce / HubSpot plus consumer clients, with declared direction and authority.
Declared direction and field authority required
Cross-interface parity
Each surface delegates to the named canonical owner; a blank surface is an intentional denial of authority, not missing documentation.
| Capability | REST | GraphQL | MCP | Webhook | Canonical owner |
|---|---|---|---|---|---|
| Primary read | GET /opportunities | opportunity(id: ID!): Opportunity | get_opportunities_pipeline | — | Opportunity, pipeline, scope, and promotion services |
| Primary command | POST /opportunities | draftOpportunityChange(input: DraftOpportunityChangeInput!): OpportunityChangeProposal! | draft_opportunities_pipeline_change | opportunity.created | Opportunity, pipeline, scope, and promotion services |
Scopes
Existing scopes are grantable for the operations marked callable; planned scopes are not grantable yet.
opportunities:readexisting scope · planned expansionopportunities:writeplanned scopeopportunities:operateplanned scopeBehavioral contract
Cross-cutting rules every implementation and interface must satisfy.
Canonical delegation
Every interface delegates to Opportunity, pipeline, scope, and promotion services; no resolver, gateway, worker, or connector reimplements domain rules.
Least-privilege principals
Scopes are evaluated with tenant, role, field-visibility, and principal-type constraints before data is read or changed.
Safe writes
Mutations use explicit confirmation where required, optimistic concurrency, idempotency, and durable actor attribution.
Transactional facts
Webhook facts are emitted from the canonical commit path, versioned, minimal, and safe to redeliver.
Declared provider authority
Every Connected App declares direction, field authority, provenance, and conflict behavior before activation.
REST API
Proposed endpoints
/api/v1/opportunitiesList opportunities & pipeline
Return an authorized, paginated collection with stable filters and provenance.
opportunities:read
/api/v1/opportunitiesconfirmationCreate Opportunity
Create one canonical resource with idempotency and actor attribution.
opportunities:write
/api/v1/opportunities/{id}Retrieve Opportunity
Return canonical detail, lifecycle state, permissions, and allowed actions.
opportunities:read
/api/v1/opportunities/{id}confirmationUpdate Opportunity
Update bounded editable fields using optimistic versioning.
opportunities:write
/api/v1/opportunities/{id}/promoteconfirmationpromote Opportunity
Run one explicit domain command after validation and authorization.
opportunities:operate
promote a Opportunity
curl --request POST \
+ --url https://www.digitalstack360.com/api/v1/opportunities/opportunity_123/promote \
+ --header "Authorization: Bearer $DSTACK_API_KEY" \
+ --header "Content-Type: application/json" \
+ --header "Idempotency-Key: opportunities-pipeline-promote-v2" \
+ --data '{
"expected_version": 2,
"reason": "Confirmed through the reviewed integration workflow"
}'{
"data": {
"id": "opportunity_123",
"status": "promoted",
"version": 3,
"operation_id": "op_01k4..."
}
}GraphQL
Proposed graph
Types
OpportunityOpportunityConnectionOpportunityChangeProposalOperationQueries
opportunity(id: ID!): OpportunityopportunityList(filter: OpportunityFilter, pagination: PaginationInput): OpportunityConnection!Mutations
draftOpportunityChange(input: DraftOpportunityChangeInput!): OpportunityChangeProposal!applyOpportunityChange(input: ApplyOpportunityChangeInput!): OpportunityPayload!query OpportunityDetail($id: ID!) {
opportunity(id: $id) {
id
status
version
updatedAt
allowedActions { id label requiresConfirmation }
source { kind externalId }
}
}MCP / Agent API
Proposed tools
Get Opportunities & Pipeline
get_opportunities_pipelineRead the authorized opportunities & pipeline state, provenance, and allowed actions.
- Scope
- opportunities:read
- Input
- Resource id or a bounded filter.
- Output
- Canonical detail with source provenance and allowed actions.
- Write boundary
- Read only.
Draft Opportunities & Pipeline change
draft_opportunities_pipeline_changeBuild a reviewable proposal from explicit user intent and DigitalStack evidence.
- Scope
- opportunities:write
- Input
- Target, requested outcome, expected version, and optional evidence references.
- Output
- A persisted proposal, validation results, and conflicts.
- Write boundary
- Creates a proposal; it does not mutate canonical state.
Apply Opportunities & Pipeline change
apply_opportunities_pipeline_changeApply a reviewed proposal through the canonical service.
- Scope
- opportunities:operate
- Input
- Proposal id, expected version, idempotency key, and explicit confirmation.
- Output
- Updated canonical resource and audit reference.
- Write boundary
- Confirmation, optimistic versioning, and idempotency required.
User: Review the proposed opportunities & pipeline change and help me apply it.
1. Call get_opportunities_pipeline to inspect current state, provenance, and allowed actions.
2. Call draft_opportunities_pipeline_change to create a proposal without changing canonical state.
3. Show validation results, conflicts, and the exact command to the user.
4. After explicit confirmation, call apply_opportunities_pipeline_change with the proposal version.
Never infer authority from access to the MCP client.Webhooks
Proposed event catalog
Event types
opportunity.createdplanned eventA canonical Opportunity was created.
payload: opportunity_id, status, created_at
opportunity.updatedplanned eventGoverned Opportunity fields changed.
payload: opportunity_id, changed_fields, version, occurred_at
opportunity.promotedplanned eventThe promote command completed.
payload: opportunity_id, prior_status, status, occurred_at
{
"event_id": "evt_01k4...",
"type": "opportunity.promoted",
"event_version": 1,
"occurred_at": "2026-07-16T14:22:04Z",
"workspace_id": "ws_abc123",
"resource": {
"type": "opportunity",
"id": "opportunity_123"
},
"actor": {
"id": "user_123"
},
"payload": {
"opportunity_id": "opportunity_123",
"prior_status": "draft",
"status": "promoted"
},
"source": null
}Connected Apps
Proposed connection roles
Claude / ChatGPT / IDE clients
Consumer application
Read, explain, and submit bounded opportunities & pipeline proposals through MCP.
Authority: Client access never implies domain approval or unrestricted mutation authority.
Salesforce / HubSpot
Synchronization provider
Exchange opportunity identity, stage, scope, and forecast.
Authority: DigitalStack promotion is explicit and idempotent; provider stage alone does not create delivery.
Open contract decisions
Resolve before implementation approval
- • Which scope changes after promotion create amendments instead of editing the opportunity?
Proof obligations
| Must remain true | Failure indicator |
|---|---|
| Opportunity, pipeline, scope, and promotion services remains the singular canonical owner. | An interface or connector persists a second authoritative lifecycle state. |
| Draft and apply remain separate actions. | An agent or integration silently converts inferred intent into a canonical mutation. |
| Every write is attributable, versioned, and idempotent. | A retry duplicates work or stale state overwrites a newer human decision. |
| Connected App direction and field authority are explicit. | Provider data silently becomes canonical or conflicts are resolved without policy. |