Skip to main content

Endpoint

POST /api/v1/process
Triggers asynchronous processing for a completed call. The endpoint is idempotent and will not re-process calls that are already completed.

Request Body

call_id
string
required
Unique identifier for the call (minimum 8 characters)Example: "call_abc123xyz"
tenant_id
string
required
Tenant identifier for configuration lookup (minimum 3 characters)Example: "tenant-production-001"

Response

Returns 202 Accepted with processing status.
call_id
string
The call identifier from the request
tenant_id
string
The tenant identifier from the request
enqueued
boolean
Whether the call was successfully added to the processing queue
  • true: Call was enqueued for processing
  • false: Call was already queued, in-progress, or completed
status
string
Processing status indicatorPossible values:
  • "queued": Call enqueued successfully
  • "already_queued_or_in_progress": Call is already being processed
  • "already_completed": Call was previously completed (idempotent rejection)

Example Request

curl -X POST https://api.example.com/api/v1/process \
  -H "Content-Type: application/json" \
  -d '{
    "call_id": "call_abc123xyz",
    "tenant_id": "tenant-production-001"
  }'

Example Responses

Successfully Enqueued

{
  "call_id": "call_abc123xyz",
  "tenant_id": "tenant-production-001",
  "enqueued": true,
  "status": "queued"
}

Already Completed

{
  "call_id": "call_abc123xyz",
  "tenant_id": "tenant-production-001",
  "enqueued": false,
  "status": "already_completed"
}

Already In Progress

{
  "call_id": "call_abc123xyz",
  "tenant_id": "tenant-production-001",
  "enqueued": false,
  "status": "already_queued_or_in_progress"
}

Processing Behavior

Idempotency

The endpoint implements idempotency at two levels:
  1. Database-level: Checks processed_status in MongoDB before enqueuing
  2. Queue-level: Rejects duplicate (call_id, tenant_id) pairs already in queue or being processed
Source: src/apps/post_call/api/v1/endpoints/process.py:65-86

Status Checking

Before enqueuing, the endpoint:
  1. Queries MongoDB for existing processed_status
  2. Returns already_completed if status is completed
  3. Sets status to pending for all other cases
  4. Proceeds with queue enqueue operation
This check is best-effort — if MongoDB is unavailable, the request can still succeed by enqueuing to the in-memory queue. Source: src/apps/post_call/api/v1/endpoints/process.py:56-116

Queue Management

The CallQueue prevents duplicates:
class CallQueue:
    def __init__(self):
        self.queue: asyncio.Queue[CallJob] = asyncio.Queue()
        self.queued_keys: set[tuple[str, str]] = set()
        self.in_progress_keys: set[tuple[str, str]] = set()
A job is rejected if its (call_id, tenant_id) key exists in either set. Source: src/apps/post_call/app/call_queue.py:19-46

Error Responses

400 Bad Request

Returned when validation fails:
{
  "detail": "call_id is required"
}
{
  "detail": "tenant_id is required"
}
Source: src/apps/post_call/api/v1/endpoints/process.py:36-42

500 Internal Server Error

Returned when the call queue is not initialized:
{
  "detail": "call queue not initialized"
}
This indicates a serious application startup failure. Source: src/apps/post_call/api/v1/endpoints/process.py:52-54

Background Processing

After a call is enqueued, the background worker performs:
  1. Fetch Data: Retrieves transcript and metadata from MongoDB
  2. Assemble Transcript: Reconstructs ordered transcript from linked items
  3. Check Empty: Detects empty transcripts (seq ≤ 2 or no content)
  4. Summarize: Calls OpenAI API for non-empty transcripts
  5. Send Email: Delivers summary to tenant recipients
  6. Update Status: Sets processed_status to completed
See Post-Call Processing Overview for detailed flow.

Manual Reprocessing

Failed calls can be manually reprocessed:
  • Allowed: Calls with processed_status = failed or pending
  • Blocked: Calls with processed_status = completed
To reprocess a failed call, simply POST to this endpoint again with the same call_id and tenant_id. Source: src/apps/post_call/api/v1/endpoints/process.py:28-34

Schema Reference

ProcessRequest

class ProcessRequest(BaseModel):
    call_id: str = Field(..., min_length=8)
    tenant_id: str = Field(..., min_length=3)
Source: src/apps/post_call/api/v1/endpoints/process.py:14-16

ProcessResponse

class ProcessResponse(BaseModel):
    call_id: str
    tenant_id: str
    enqueued: bool
    status: str
Source: src/apps/post_call/api/v1/endpoints/process.py:19-23

CallJob

@dataclass(frozen=True)
class CallJob:
    call_id: str
    tenant_id: str
    attempt: int = 1  # For retry tracking
Source: src/apps/post_call/app/call_queue.py:7-11

Processing Overview

Learn about the complete processing flow

Webhooks

Configure webhooks for processing events

Build docs developers (and LLMs) love