Revenue

Approve

Approve posts acceptRisk false. The stored action is approved for its current revision, and the approval time is recorded. Approve send uses this same call when the action is in send mode. A blocked action cannot be approved.

post/v1/revenue-actions/{actionId}/approve

Request

  • Base URL: / (relative, and the document was published on a file host, not at the API’s origin)
  • URL: /v1/revenue-actions/{actionId}/approve
  • Auth: HTTP bearer

Path parameters

actionIdstring uuid required
Example:1a8dfa9b-a7b2-46ea-982c-622a914c00e5

Action id.

Request body

acceptRiskboolean

Explicitly accept a review_required decision.

Response

Approved action.

actionType'warm_follow_up' | 'proposal_nudge' | 'referral_reconnect' | 'customer_risk' | 'meeting_follow_up' | 'meeting_recap' | 'crm_update' | 'follow_up_task' | 'calendar_hold' | 'commitment_rescue' required

Action type.

approvalStatus'pending' | 'approved' | 'rejected' required

Approval state, bound to the exact revision and decision.

approvedAtstring date-time nullable

Approval time.

approvedRevisioninteger

Revision the approval is bound to.

channel'email' | 'slack' | 'call' | 'crm_task' | 'crm' | 'task' | 'calendar' required

Delivery channel.

createdAtstring date-time

Creation time.

detector'requested_follow_up_due' | 'unanswered_proposal' | 'waiting_on_me' | 'dormant_warm_opportunity' | 'neglected_referral' | 'former_customer_reconnect' | 'conversation_action_pack' | 'commitment_due' | 'manual' required

Detector that produced the action.

dismissReasonstring

Dismissal reason label.

dueAtstring date-time nullable

Due time.

executedAtstring date-time nullable

Execution time.

executionErrorstring

Bounded execution error.

executionMode'draft' | 'send' required

Draft lands in the operator's mailbox; send requires a passed unexpired decision and a linked workspace.

executionOwner'rowboat' | 'outbound' required

Exactly one owner may execute a revision.

executionStatus'pending' | 'requested' | 'sent' | 'failed' | 'ambiguous' | 'cancelled' required

Execution state. A lost provider result is ambiguous, never auto-resent.

idstring uuid required

Stable UUID primary key.

policyStatus'pending' | 'passed' | 'review_required' | 'blocked' | 'stale' required

Preflight state. Facade unavailability keeps pending (fail closed).

priorityComponentsobject

Factors the review lists.

priorityScoreinteger required

Explainable priority score (0-100).

proposedMessagestring

Proposed message body.

proposedSubjectstring

Proposed email subject.

providerMessageIdstring

Provider message id after execution.

providerThreadIdstring

Provider thread id after execution.

queueStatus'open' | 'snoozed' | 'dismissed' | 'handled' required

Operator triage state.

reasonstring required

Human-readable evidence-backed reason.

recipientEmailstring

Recipient email address.

reconciliationAttemptsinteger

Number of bounded provider lookups performed.

reconciliationCheckedAtstring date-time nullable

Most recent provider lookup time.

reconciliationErrorstring

Bounded provider lookup error.

reconciliationNextAtstring date-time nullable

Next scheduled read-only lookup time.

reconciliationStatus'pending' | 'found' | 'not_found' | 'error' | 'manual_review'

Read-only provider reconciliation state for an ambiguous write.

relationshipIdstring uuid

Owning relationship id.

relationshipNamestring

Owning company name. The directory is paged, so a task still names a company that is not on the first page.

revisioninteger required

Current revision number.

revisionHashstring required

Canonical hash of the revision content.

senderAccountRefstring

Sender account reference.

snoozedUntilstring date-time nullable

Snooze wake time.

updatedAtstring date-time

Last update time.

Example response

{
  "actionType": "warm_follow_up",
  "approvalStatus": "pending",
  "approvedAt": "2026-07-12T12:05:00Z",
  "approvedRevision": 1,
  "channel": "email",
  "createdAt": "2026-07-12T12:00:00Z",
  "detector": "manual",
  "dismissReason": "not_relevant",
  "dueAt": "2026-07-15T00:00:00Z",
  "evidence": [
    {
      "excerpt": "We are concerned security could delay renewal.",
      "externalEvidenceRefs": [
        "timestamp:12000-16000"
      ],
      "id": "4b8dfa9b-a7b2-46ea-982c-622a914c00e5",
      "occurredAt": "2026-07-31T14:00:00Z",
      "source": "meeting",
      "sourceRecordId": "oppulence:session-42:claim:claim-risk"
    }
  ],
  "executedAt": "2026-07-12T12:06:00Z",
  "executionMode": "draft",
  "executionOwner": "rowboat",
  "executionStatus": "pending",
  "id": "123e4567-e89b-12d3-a456-426614174000",
  "policyStatus": "pending",
  "priorityComponents": {
    "commitment_urgency": 25,
    "evidence_quality": 10,
    "recency_signal": 12,
    "relationship_value": 20,
    "uncertainty_penalty": -5
  },
  "priorityScore": 82,
  "proposedMessage": "Hi Jordan — you asked me to circle back this month...",
  "proposedSubject": "Following up as promised",
  "providerMessageId": "msg_01",
  "providerThreadId": "thread_01",
  "queueStatus": "open",
  "reason": "They asked for a follow-up in July.",
  "recipientEmail": "buyer@example.com",
  "reconciliationAttempts": 1,
  "reconciliationCheckedAt": "2026-07-12T12:07:00Z",
  "reconciliationNextAt": "2026-07-12T12:12:00Z",
  "reconciliationStatus": "pending",
  "relationshipId": "9c8dfa9b-a7b2-46ea-982c-622a914c00e5",
  "relationshipName": "Acme",
  "revision": 1,
  "revisionHash": "sha256:746c1d9cd3925b8e632fc1b4bd539758514cb1aefdf31948fe8d1b45ce74c29d",
  "senderAccountRef": "gmail:me@company.com",
  "snoozedUntil": "2026-07-20T09:00:00Z",
  "updatedAt": "2026-07-12T12:06:00Z"
}

Changes

No recorded changes to this operation across all 50 revisions of this API.