> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cekura.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Send Calls

> Primary ingestion endpoint for production call logs. Your agent (or its provider's post-call webhook) POSTs here with the transcript, recording URL, and metadata; Cekura stores it as a `CallLog`, schedules metric evaluation, and surfaces it in Observability.



## OpenAPI

````yaml post /observability/v1/observe/
openapi: 3.1.0
info:
  title: Cekura API
  version: v1
  description: >-
    Complete API documentation for the Cekura platform. This API provides
    endpoints for testing, observing, and evaluating AI voice agents — including
    managing agents, running evaluators, defining metrics, and analyzing call
    quality.
servers:
  - url: https://api.cekura.ai
security: []
paths:
  /observability/v1/observe/:
    post:
      tags:
        - Observability
      summary: Ingest a production call (webhook)
      description: >-
        Primary ingestion endpoint for production call logs. Your agent (or its
        provider's post-call webhook) POSTs here with the transcript, recording
        URL, and metadata; Cekura stores it as a `CallLog`, schedules metric
        evaluation, and surfaces it in Observability.


        **Identifying the agent (pick one):**

        - `agent` — Cekura agent ID (preferred when you've already registered
        via `POST /aiagents/`)

        - `assistant_id` — external assistant identifier
        (VAPI/Retell/OpenAI-style `asst_...`). Cekura resolves it to your agent.


        **Transcript formats** (via `transcript_type`):

        - `vapi`, `retell`, `elevenlabs`, `bland`, `livekit`, `pipecat`,
        `koreai` — provider-native shapes; pass `transcript_json` exactly as the
        provider emits it.

        - `cekura` (default) — `[{role, content, start_time, end_time}, ...]`.
        Valid roles: `"Testing Agent"` (the caller) and `"Main Agent"` (the
        agent under test). Note: `"agent"` and `"user"` are **not** valid for
        this format.


        **Provider-specific alternatives:**

        - LiveKit webhooks: `POST /observability/v1/livekit/observe/` (raw
        LiveKit webhook shape)

        - Pipecat webhooks: `POST /observability/v1/pipecat/observe/` (raw
        Pipecat webhook shape)


        **Fields to know:**

        - `voice_recording_url` — link to the call audio; enables audio-based
        metrics.

        - `metadata` — freeform tags for filtering in Observability
        (`customer_id`, `campaign_id`, etc.).

        - `dynamic_variables` — values injected into the agent at runtime; shown
        alongside the transcript.

        - `customer_number` — caller's number in E.164 format, e.g.
        `+14155551234`.

        - `call_ended_reason` — reason for call termination (`completed`,
        `user-hangup`, `agent-hangup`, etc.).

        - `metric_ids` — comma-separated metric IDs to evaluate immediately
        (e.g. `"1,2,3"`).


        **Async processing:** metrics are evaluated in the background. The
        initial response shows `status: "evaluating"` with an empty `metrics`
        list. Retrieve the call log again after 30–60 seconds to see completed
        metric results.


        **Billing:** each ingested call consumes observability credits. Calls
        with audio cost more than text-only calls. Check your balance via `GET
        /test_framework/v1/billing_info`.
      operationId: observe-create
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCallLog'
            examples:
              CreateCallLogWithVoiceRecordingURL:
                value:
                  call_id: call_12345678
                  agent: 1
                  voice_recording_url: https://example.com/recordings/call_12345678.mp3
                  transcript_type: vapi
                  transcript_json:
                    - role: agent
                      message: Hello, how can I help you today?
                      time: 0
                    - role: user
                      message: I need help with my account
                      time: 2.5
                  call_ended_reason: completed
                  customer_number: '+1234567890'
                  metadata:
                    customer_id: cust_123
                    campaign_id: camp_456
                  timestamp: '2025-10-03T10:30:00Z'
                  dynamic_variables:
                    customer_name: John Doe
                    order_id: ORD-12345
                summary: Create Call Log with Voice Recording URL
              CreateCallLogWithAssistantID:
                value:
                  call_id: call_87654321
                  assistant_id: asst_abc123
                  voice_recording_url: https://example.com/recordings/call_87654321.mp3
                  transcript_type: retell
                  transcript_json:
                    - role: agent
                      message: Thank you for calling. How may I assist you?
                      time: 0
                  call_ended_reason: user-hangup
                  customer_number: '+9876543210'
                summary: Create Call Log with Assistant ID
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/CreateCallLog'
          multipart/form-data:
            schema:
              $ref: '#/components/schemas/CreateCallLog'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CallLogList'
          description: ''
        '400':
          content:
            application/json:
              schema:
                type: object
                properties:
                  field_name:
                    type: array
                    items:
                      type: string
          description: ''
      security:
        - api_key: []
components:
  schemas:
    CreateCallLog:
      type: object
      properties:
        id:
          type: integer
          readOnly: true
        call_id:
          type: string
          description: |-
            Unique identifier for the call.
            Example: 
            - `"call_abc123xyz"`
            - `"stereo_audio_session_456"`
          maxLength: 100
        trace_id:
          type: string
          default: ''
          description: >-
            OpenTelemetry trace ID (32-char hex string). Example:
            "4bf92f3577b34da6a3ce929d0e0e4736"
          maxLength: 32
        agent:
          type: integer
          description: |

            Agent ID, required if assistant_id not provided
            Example: `2421`
        assistant_id:
          type:
            - string
            - 'null'
          description: |

            Provider's Assistant ID, required if agent not provided
            Example: 
            - `"asst_abc123xyz"`
            - `"agent_xyz789"`
        voice_recording:
          type:
            - string
            - 'null'
          format: uri
          description: |-
            Audio recording file of the call.
            Example: Binary data `"recordings/call_123_20240315.mp3"`
        voice_recording_url:
          type:
            - string
            - 'null'
          format: uri
          description: |

            URL to call recording audio file
            Example: `"https://storage.example.com/recordings/call_123.mp3"`
        transcript_type:
          enum:
            - cekura
            - vocera
            - vapi
            - retell
            - deepgram
            - pipecat
            - livekit
            - elevenlabs
            - none-mono
          type: string
          x-spec-enum-id: cf3e002831f464f4
          writeOnly: true
          description: >-
            Format of the `transcript_json` payload. Tells Cekura how to parse
            roles and timestamps.


            - `vapi` — Vapi webhook format: `[{"role": "bot"|"user", "message":
            "...", "time": 0.0}]`

            - `retell` — Retell webhook format

            - `elevenlabs` — ElevenLabs format

            - `livekit` — LiveKit format

            - `pipecat` — Pipecat format

            - `deepgram` — Deepgram format

            - `cekura` (default) — `[{"role": "Testing Agent"|"Main Agent",
            "content": "...", "start_time": 0.0, "end_time": 2.5}]`. **Valid
            roles are `"Testing Agent"` and `"Main Agent"` only** — using
            `"agent"` or `"user"` will return a validation error.

            - `none-mono` — mono audio with no transcript; Cekura generates the
            transcript automatically.


            Omit this field to use the default Cekura format.


            * `cekura` - cekura

            * `vocera` - vocera

            * `vapi` - vapi

            * `retell` - retell

            * `deepgram` - deepgram

            * `pipecat` - pipecat

            * `livekit` - livekit

            * `elevenlabs` - elevenlabs

            * `none-mono` - none-mono
        transcript_json:
          description: >

            Call transcript in supported format (Vapi, Retell, Deepgram,
            ElevenLabs, Cekura)


            Check the [Transcript
            Format](/documentation/advanced/transcript-format) documentation for
            more details.


            Cekura Transcript Format Example:

            ```json

            [
               {
                  "role": "Testing Agent",
                  "content": "Hello.",
                  "end_time": 1.9399999,
                  "start_time": 1.4399999
               },
               {
                  "role": "Main Agent",
                  "content": "Hello. I want to book appointment today. My name is John.",
                  "end_time": 7.539999511718751,
                  "start_time": 3.1
               },
               {
                  "role": "Testing Agent",
                  "content": "Well, I mean, sure. What time exactly are we talking about here",
                  "end_time": 15.71,
                  "start_time": 12.01
               },
               {
                  "role": "Main Agent",
                  "content": "6 PM.",
                  "end_time": 18.269999,
                  "start_time": 17.609999
               }
            ]

            ```
        call_ended_reason:
          type:
            - string
            - 'null'
          description: |

            Reason why the call ended
            Example: 
            - `"customer-ended-call"`
            - `"agent-ended-call"`
        customer_number:
          type:
            - string
            - 'null'
          description: |

            Customer's phone number or identifier
            Example: 
            - `"+1234567890"`
            - `"customer_abc123"`
        metadata:
          description: |

            Additional call metadata
            Example:
            ```json
            {
                "customer_id": "123",
                "order_id": "ORD-12345",
                "name": "John Doe"
            }
            ```
        timestamp:
          type: string
          format: date-time
          description: |-
            When the call occurred.
            Example: `2024-03-15T10:15:45Z`
        dynamic_variables:
          description: >

            Dynamic variables used to replace {{variables}} in agent
            description.

            Example:

            ```json

            {
                "subscription_id": "SUB-12345",
                "product_type": "premium"
            }

            ```
        feedback:
          type:
            - string
            - 'null'
          description: |

            Feedback about the call
            Example: `"Great call"`
        redact_fields:
          type: array
          items:
            enum:
              - person_name
              - age
              - phone_number
              - email_address
              - date
              - time
              - location
              - origin
              - gender_sexuality
              - physical_attribute
              - occupation
              - username
              - password
              - ip_address
              - url
              - filename
              - event
              - vehicle_id
              - dob
              - healthcare_number
              - medical_professional
              - credit_card
              - account_number
              - bank_account
              - money
              - ssn
              - passport_number
              - driver_license
              - numerical_pii
            type: string
            description: |-
              * `person_name` - person_name
              * `age` - age
              * `phone_number` - phone_number
              * `email_address` - email_address
              * `date` - date
              * `time` - time
              * `location` - location
              * `origin` - origin
              * `gender_sexuality` - gender_sexuality
              * `physical_attribute` - physical_attribute
              * `occupation` - occupation
              * `username` - username
              * `password` - password
              * `ip_address` - ip_address
              * `url` - url
              * `filename` - filename
              * `event` - event
              * `vehicle_id` - vehicle_id
              * `dob` - dob
              * `healthcare_number` - healthcare_number
              * `medical_professional` - medical_professional
              * `credit_card` - credit_card
              * `account_number` - account_number
              * `bank_account` - bank_account
              * `money` - money
              * `ssn` - ssn
              * `passport_number` - passport_number
              * `driver_license` - driver_license
              * `numerical_pii` - numerical_pii
            x-spec-enum-id: 99d2b7efd95189c4
          description: >

            Optional list of sensitive fields to redact from the transcript and
            audio. If not provided, no redaction will occur.

            Available fields include: phone_number, email_address, credit_card,
            ssn, dob, healthcare_number, etc.

            Note: Redacting any fields incurs a cost of 0.4 credits per minute,
            regardless of how many fields are selected.

            Example: `["phone_number", "email_address", "credit_card"]`
        metric_ids:
          type: string
          writeOnly: true
          description: >-
            Comma-separated metric IDs to evaluate for this call. Example:
            "118,119". To run metrics after the call is created, use the
            evaluate_metrics endpoint instead.
        main_agent_channel_index:
          type:
            - integer
            - 'null'
          description: >-
            Channel index (0 or 1) of the main agent in stereo recordings. When
            provided, skips automatic channel detection. Example: `0` means
            channel 0 is the main agent, channel 1 is the customer/testing
            agent.
      required:
        - call_id
    CallLogList:
      type: object
      description: ''
      properties:
        id:
          type: integer
          readOnly: true
        duration:
          type: string
          readOnly: true
          description: |-
            Call duration in minutes in MM:SS format.
            Example: `01:10`
        success:
          type:
            - boolean
            - 'null'
          description: |-
            Whether the call was successful.
            Example: `true` or `false`
        is_reviewed:
          type: boolean
          description: |-
            Whether the call has been reviewed.
            Example: `true` or `false`
        status:
          enum:
            - success
            - failure
            - reviewed_success
            - reviewed_failure
          type: string
          x-spec-enum-id: a5dfbbcee6f2a6ce
          description: |-
            Status of the call or conversation.
            Example: `"completed"` or `"failed"`

            * `success` - Success
            * `failure` - Failure
            * `reviewed_success` - Reviewed Success
            * `reviewed_failure` - Reviewed Failure
        feedback:
          type: string
          description: |-
            Feedback about the call.
            Example: `"Great Call"`
        metrics:
          type: array
          items:
            $ref: '#/components/schemas/CallLogListSerializerMetrics'
          readOnly: true
          description: Metrics of the call
        call_ended_reason:
          type: string
          description: |
            Reason why the call ended.
            Example: 
            - `"customer-ended-call"`
            - `"agent-ended-call"`
          maxLength: 100
        customer_number:
          type: string
          description: |
            Customer's phone number or identifier.
            Example: 
            - `"+1234567890"`
            - `"customer_abc123"`
          maxLength: 100
        agent:
          type:
            - integer
            - 'null'
          description: Agent ID
        agent_name:
          type: string
          readOnly: true
          description: Agent name
        call_id:
          type: string
          description: |-
            Unique identifier for the call.
            Example: 
            - `"call_abc123xyz"`
            - `"stereo_audio_session_456"`
          maxLength: 100
        trace_id:
          type: string
          description: >-
            OpenTelemetry trace ID (32-char hex). Set when OTel tracing is
            enabled.
          maxLength: 32
        timestamp:
          type: string
          format: date-time
          description: |-
            When the call occurred.
            Example: `2024-03-15T10:15:45Z`
        error_message:
          type:
            - string
            - 'null'
        dropoff_point:
          type: string
          description: |-
            Point in conversation where user disengaged.
            Example: `"end of conversation as no queries remaining"`
          maxLength: 1000
        topic:
          type: string
          description: |
            Topic of the call.
            Example: 
            - `"product_inquiry"`
            - `"technical_support"`
          maxLength: 1000
        created_at:
          type: string
          format: date-time
          readOnly: true
          description: |-
            When this record was created.
            Example: `2024-03-15T10:30:45Z`
        updated_at:
          type: string
          format: date-time
          readOnly: true
          description: |-
            When this record was last updated.
            Example: `2024-03-15T10:35:11Z`
        transcript:
          type: string
          description: >
            Full text transcript of the call.

            Example: 

            ```text

            [00:01] Testing Agent: Hello. 

            [00:02] Main Agent: Hello, how can I help you today?

            [00:03] Testing Agent: Well, I mean, sure. What time exactly are we
            talking about here

            [00:04] Main Agent: 6 PM.

            [00:05] Testing Agent: Great. I'll book that for you. Just a sec.

            [00:06] Main Agent: Okay.

            ```
        transcript_object:
          type: string
          readOnly: true
          description: |-
            Structured transcript data with timestamps.
            Example: 
            ```json
            [
                {
                    "role": "Testing Agent",
                    "content": "Hello",
                    "start_time": 1.2,
                    "end_time": 1.8
                },
                {
                    "role": "Main Agent",
                    "content": "Hello, how can I help you today?",
                    "start_time": 1.8,
                    "end_time": 2.5
                }
            ]`
        evaluation:
          type: string
          readOnly: true
          description: Evaluation of the call
      required:
        - call_id
    CallLogListSerializerMetrics:
      type: object
      properties:
        id:
          type: integer
          description: Metric ID
        name:
          type: string
          description: Metric name
        type:
          type: string
          description: Metric type
        score:
          type: number
          format: double
          description: Evaluated metric score, Present if metrictype is not enum
        enum:
          type: string
          description: Metric enum, Present if type is enum
        value:
          type: string
          description: Evaluated metric value, Present if metric type is enum
      required:
        - enum
        - id
        - name
        - score
        - type
        - value
  securitySchemes:
    api_key:
      type: apiKey
      name: X-CEKURA-API-KEY
      in: header
      description: >-
        API Key Authentication. It should be included in the header of each
        request.

````