Voicetta
    Voicetta.

    Voicetta API

    Thread Events

    Get the finished SMS and WhatsApp conversation, including transcript, outcome, evaluations, and follow-up history.

    Thread Events

    A thread.completed event represents a finished SMS or WhatsApp conversation.

    Messages tell you what happened during the conversation.

    The thread tells you how the conversation ended.

    It can contain:

    • the transcript
    • summary
    • intent
    • outcome
    • sentiment
    • evaluation results
    • follow-ups
    • cost information

    When it fires

    A thread is not completed when the last message arrives.

    Voicetta waits for the conversation to become inactive before grading it.

    The default inactivity period is 30 minutes.

    If a recovery follow-up is needed, the conversation can stay open longer.

    Expect thread.completed roughly 30 minutes after the conversation goes quiet, unless a follow-up extends it.

    If you need the live conversation, use message events.

    Payload

    json
    { "event": "thread.completed", "event_id": "c82fa013-5b7d-4029-8e4f-8d3c6b5f9a42", "version": 1, "occurred_at": "2026-08-20T14:45:00+00:00", "thread": { "thread_id": "c82fa013-5b7d-4029-8e4f-8d3c6b5f9a42", "workspace_id": "2a1f8e7d-4c3b-4a29-9f18-6d5e4c3b2a19", "assistant_id": "7c6b5a49-3e2d-4c1b-8a97-5f4e3d2c1b09", "assistant_name": "Front Desk", "channel": "whatsapp", "close_reason": "graded", "message_count": 6, "started_at": "2026-08-20T14:12:00+00:00", "last_message_at": "2026-08-20T14:19:00+00:00", "completed_at": "2026-08-20T14:45:00+00:00", "anchor_message_id": "b71e9d02-4a6c-4f18-9d3e-7c2b5a4e8f31", "customer": { "customer_id": "5d4c3b2a-1f09-4e8d-7c6b-5a493e2d1c0b", "name": "Jane Texter", "phone": "+15551234567" }, "transcript": [ { "role": "user", "content": "Do you have a room free on Friday?" }, { "role": "assistant", "content": "Yes, we have a double available." } ], "analysis": { "summary": "Customer asked about Friday availability and held a double room.", "intent": "booking_enquiry", "outcome": "booked", "sentiment": "positive" }, "evaluations": [ { "evaluation_id": "3e2d1c0b-5a49-4f8e-9d7c-6b5a493e2d1c", "title": "Offered a booking reference", "result": "pass", "initial_result": "fail", "rationale": "The reference was given after the follow-up.", "recovered": true } ], "costs": { "currency": "USD", "total": "0.0300", "charged_message_count": 3 }, "follow_ups": [ { "status": "sent", "channel": "whatsapp", "sent_at": "2026-08-20T14:40:00+00:00" } ] } }

    Reading the fields

    • thread_id is the conversation id.
    • thread_id is also present on message events.
    • anchor_message_id identifies the message associated with the grading.
    • completed_at is when grading finished.
    • last_message_at is when the conversation went quiet.
    • message_count is the number of messages in the transcript.
    • evaluations[].recovered tells you whether a failed criterion was fixed by a follow-up.

    Costs

    costs.total is an indicative value based on message usage.

    It is not the amount charged on your invoice.

    Use your invoice for billing.

    close_reason

    Always read close_reason.

    Not every completed thread has evaluation results.

    ReasonMeaningGraded?
    gradedNormal completed conversationYes
    no_reply_after_follow_upRecovery follow-up was not answeredYes
    customer_opted_outCustomer opted outPartly
    no_enabled_evaluationsNo evaluations were enabledNo
    empty_transcriptNothing could be gradedNo
    grading_failedGrading failedNo
    follow_up_failedRecovery follow-up failedNo
    follow_up_daily_capDaily follow-up limit was reachedNo
    follow_up_no_criteriaNothing needed recoveryPartly
    follow_up_no_customer_phoneNo phone number was availableNo
    follow_up_missing_openai_keyFollow-up generation was not configuredNo
    follow_up_send_ambiguousFollow-up delivery could not be confirmedNo
    follow_up_skipped:<reason>Follow-up was skippedNo

    Do not treat every thread as graded.

    For quality reporting, use graded and no_reply_after_follow_up as your graded population.

    Treat the other close reasons as not graded.

    Why ungraded threads are still delivered

    A conversation happened even if grading failed.

    We still send it.

    That gives your product a complete picture of communication instead of silently hiding conversations because evaluation did not run.

    What threads do not contain

    Threads do not contain:

    • recordings
    • voice latency
    • voice configuration
    • is_test

    Those fields only apply to voice calls.

    Reading threads through the API

    text
    GET /v1/threads

    You can filter by date, assistant, channel, and close_reason.

    Use:

    text
    close_reason=graded

    when you only want conversations that produced evaluation results.