Opportunity Intake API

JDG Capital CRM · version 1.0 · OpenAPI 3.1

Approval is mandatory. Every batch needs a unique request ID, source, approving identity, approval timestamp, and explicitly_approved: true on every opportunity. The timestamp must record the actual approval instant, must not be in the future, and must use UTC Z or the correct numeric offset. Previewing never writes opportunities.

Authentication and safety

Use Authorization: Bearer … with a dedicated token carrying opportunities:intake. Browser cookies are not accepted by these endpoints. Tokens are shown once when an administrator creates them, are stored only as hashes, and may expire or be revoked.

Requests are rate limited and audited. Never place a token in a URL, payload, log message, or source-control file.

POST/api/v1/opportunity-intakes/preview

Validates approval, fields, provenance, update protections, exact matches, and possible duplicates. Preserve the complete response, especially preview_id, expires_at, can_confirm, and possible_duplicates, through the explicit confirmation step.

POST/api/v1/opportunity-intakes/{previewId}/confirm

Pass the exact unexpired preview_id as previewId and send {"confirm":true}. When possible_duplicates is non-empty, resolve every listed external_id by selecting a returned candidate target_id or explicitly rejecting it. The complete confirmation commits or rolls back as one transaction.

Preview example

curl -X POST "$CRM_URL/api/v1/opportunity-intakes/preview" \
  -H "Authorization: Bearer $JDG_INTAKE_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{
    "request_id": "research-2026-07-19-001",
    "source": "authorized-ai-research",
    "approved_by": {"email": "reviewer@example.com", "name": "Reviewer"},
    "approval_timestamp": "2026-07-19T18:00:00Z",
    "opportunities": [{
      "external_id": "platform:12345",
      "business_name": "Acme Services",
      "explicitly_approved": true,
      "listing_url": "https://example.com/listing/12345",
      "asking_price": 1200000,
      "revenue": null,
      "sde": 350000,
      "provenance_type": "listing_reported",
      "research_date": "2026-07-19"
    }]
  }'

Unknown financial values must be JSON null, never zero.

Confirm example

curl -X POST "$CRM_URL/api/v1/opportunity-intakes/PREVIEW_UUID/confirm" \
  -H "Authorization: Bearer $JDG_INTAKE_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"confirm": true, "duplicate_resolutions": {}}'

For an ambiguous record, provide "external-id":{"target_id":42} or "external-id":{"action":"reject"} under duplicate_resolutions.

Provenance and update rules

Accepted provenance types are listing_reported, broker_reported, cim_reported, buyer_adjusted, inferred, and verified. Null inputs do not erase CRM data. Inferred values cannot overwrite CIM, buyer-adjusted, or verified values. Manual notes and linked CRM relationships are not replaced by intake data.

Download the machine-readable OpenAPI 3.1 specification · Return to CRM