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

# Get conversation artifacts

> Returns everything recorded about a finished conversation: for each agent session, the transcript, the event timeline, detected problems (`findings`), per-turn latency, and optionally a download link for the audio recording; plus a `merged` view that joins all sessions in time order. This is the endpoint to use for transcripts and recordings.

Artifacts are uploaded shortly after a call ends. Until they arrive — and while personal data is still being redacted from them, on organizations that have redaction switched on — the endpoint answers 404 with `code: ARTIFACTS_NOT_READY`; retry after a short wait. When only some sessions could be loaded, the response is 200 and the missing sessions carry an `error` object instead of their artifacts.



## OpenAPI

````yaml /api-reference/voice-openapi.json get /v1/projects/{projectId}/conversations/{id}/artifacts
openapi: 3.0.3
info:
  title: Clarity Voice API
  version: '1.0'
  description: Voice agents, outbound calls, conversations, campaigns, and evals.
servers:
  - url: https://voice-api.onclarity.com
security:
  - organizationApiKey: []
tags:
  - name: Projects
    description: >-
      The projects your organization owns. Every other resource lives in a
      project.
  - name: Agents
    description: Create, configure, version and publish voice agents.
  - name: Outbound calls
    description: Have a published agent phone a number now.
  - name: Conversations
    description: >-
      One record per call session, with its calls, recordings, transcripts and
      artifacts.
  - name: Calls
    description: The calls of a project, with their status, direction, timing and outcome.
  - name: Campaigns
    description: Outbound calling campaigns that phone a list of numbers on a schedule.
  - name: Eval suites
    description: >-
      Reusable sets of eval scenarios and test cases to measure an agent
      against.
  - name: Eval judges
    description: The LLM judges that score eval calls against your test cases.
  - name: Eval scenarios
    description: The simulated-caller scenarios of your eval suites.
  - name: Eval test cases
    description: The checks a judge applies to each eval call.
  - name: Eval submissions
    description: Run an eval suite against an agent and read the verdicts.
paths:
  /v1/projects/{projectId}/conversations/{id}/artifacts:
    parameters:
      - $ref: '#/components/parameters/ProjectIdPath'
      - $ref: '#/components/parameters/ConversationId'
    get:
      tags:
        - Conversations
      summary: Get conversation artifacts
      description: >-
        Returns everything recorded about a finished conversation: for each
        agent session, the transcript, the event timeline, detected problems
        (`findings`), per-turn latency, and optionally a download link for the
        audio recording; plus a `merged` view that joins all sessions in time
        order. This is the endpoint to use for transcripts and recordings.


        Artifacts are uploaded shortly after a call ends. Until they arrive —
        and while personal data is still being redacted from them, on
        organizations that have redaction switched on — the endpoint answers 404
        with `code: ARTIFACTS_NOT_READY`; retry after a short wait. When only
        some sessions could be loaded, the response is 200 and the missing
        sessions carry an `error` object instead of their artifacts.
      operationId: getConversationArtifacts
      parameters:
        - name: include_recording
          in: query
          required: false
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
            default: 'false'
          description: >-
            `true` adds a short-lived signed download link for each session's
            audio recording (`sessions[].recording_signed_url`, expiring at
            `recording_signed_url_expires_at`).
        - name: include_session_config
          in: query
          required: false
          schema:
            type: string
            enum:
              - 'true'
              - 'false'
            default: 'false'
          description: >-
            `true` adds each session's effective agent configuration as it ran
            (`sessions[].session_config`), when it was stored.
      responses:
        '200':
          description: The conversation's artifacts.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConversationArtifacts'
              example:
                project_id: 3c59dc04-8a4b-4f7e-9b1a-6c2a0e5d1f22
                conversation_id: 8f14e45f-ceea-467f-a0e6-3f1c2b9d7a10
                bucket: example-bucket
                sessions_count: 1
                sessions_degraded: 0
                sessions:
                  - session_id: AJ_x8Kd2mQp4Vn
                    call_id: 1b6453892473a467d07372d45eb05abc
                    agent_id: 6f4922f4-5568-461a-8f1d-9c3b2a1e7d55
                    joined_at: '2026-10-20T09:15:02.000Z'
                    left_at: '2026-10-20T09:18:06.000Z'
                    gcs_prefix: >-
                      gs://example-bucket/calls/3c59dc04-8a4b-4f7e-9b1a-6c2a0e5d1f22/AJ_x8Kd2mQp4Vn/
                    transcript: |-
                      AGENT: Hello, how can I help?
                      CALLER: I'd like to move my appointment to Thursday.
                    findings: []
                    fatal_count: 0
                    warning_count: 0
                    recording_signed_url: >-
                      https://storage.googleapis.com/example-bucket/calls/3c59dc04-8a4b-4f7e-9b1a-6c2a0e5d1f22/AJ_x8Kd2mQp4Vn/recording.wav?X-Goog-Signature=abc123
                    recording_signed_url_expires_at: '2026-10-20T10:18:06.000Z'
                merged:
                  transcript: |-
                    AGENT: Hello, how can I help?
                    CALLER: I'd like to move my appointment to Thursday.
                  findings: []
                  fatal_count: 0
                  warning_count: 0
                media_insights: []
                messages: []
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          description: >-
            The conversation does not exist, or its artifacts are not available
            yet (`code: ARTIFACTS_NOT_READY` — retry later) or were never stored
            (`code: NO_ARTIFACTS`, e.g. a call nobody joined).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                error: >-
                  Artifacts not ready for conversation
                  8f14e45f-ceea-467f-a0e6-3f1c2b9d7a10 — all 1 session(s)
                  reported ARTIFACTS_NOT_READY (transient upload lag or an
                  aborted call that stored nothing).
                code: ARTIFACTS_NOT_READY
        '500':
          description: Recording storage is not configured on this deployment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '502':
          description: >-
            Storage failed for every session of the conversation (`code:
            OBJECT_STORAGE_ERROR`). Retry later.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
components:
  parameters:
    ProjectIdPath:
      name: projectId
      in: path
      required: true
      schema:
        type: string
      description: Project id
    ConversationId:
      name: id
      in: path
      required: true
      schema:
        type: string
      description: Conversation id
  schemas:
    ConversationArtifacts:
      type: object
      required:
        - project_id
        - conversation_id
        - bucket
        - sessions_count
        - sessions_degraded
        - sessions
        - merged
      properties:
        project_id:
          type: string
        conversation_id:
          type: string
        bucket:
          type: string
          example: example-bucket
        sessions_count:
          type: integer
          minimum: 0
        sessions_degraded:
          type: integer
          minimum: 0
          description: Count of sessions that failed to load (have an `error` field).
        sessions:
          type: array
          items:
            $ref: '#/components/schemas/SessionArtifacts'
        merged:
          $ref: '#/components/schemas/MergedArtifacts'
        media_insights:
          type: array
          description: >-
            Caller-side network stats per call (WebRTC RTT/jitter/loss measured
            at the caller's browser), collected across the conversation's calls.
            Empty for SIP-only conversations and calls where the widget never
            reported.
          items:
            type: object
            additionalProperties: true
            properties:
              call_id:
                type: string
              conversation_id:
                type: string
                nullable: true
        messages:
          type: array
          description: >-
            In-call WhatsApp / email sends of this conversation with their
            events (statuses, button taps, replies, no-response notes),
            including events that arrived after hang-up. The recipient is
            masked; reply texts are withheld on calls with PII redaction on.
          items:
            type: object
            properties:
              id:
                type: string
              channel:
                type: string
                enum:
                  - whatsapp
                  - email
              kind:
                type: string
                enum:
                  - template
                  - text
                  - document
                  - buttons
                  - email
              message_ref:
                type: string
              recipient:
                type: string
                nullable: true
              recipient_source:
                type: string
                nullable: true
              status:
                type: string
              failure_reason:
                type: string
                nullable: true
              origin:
                type: string
              created_at:
                type: string
                format: date-time
              events:
                type: array
                items:
                  type: object
                  properties:
                    event_type:
                      type: string
                    status:
                      type: string
                      nullable: true
                    failure_reason:
                      type: string
                      nullable: true
                    button_id:
                      type: string
                      nullable: true
                    button_label:
                      type: string
                      nullable: true
                    text:
                      type: string
                      nullable: true
                    provider_ts:
                      type: string
                      nullable: true
                    received_at:
                      type: string
                    delivered_to_agent:
                      type: boolean
    Error:
      type: object
      required:
        - error
      additionalProperties: true
      properties:
        error:
          type: string
          description: Error message
        code:
          type: string
          description: >-
            A stable machine-readable reason, present on the refusals a client
            may branch on. Among them: `PUBLISH_CAPABILITY_REQUIRED` (403, the
            credential may not change what is live), `AGENT_NOT_PUBLISHED` (409,
            the agent has no published version yet),
            `AGENT_TYPE_NOT_DISPATCHABLE` (422, a Voice Assist agent named where
            an agent must place or take a call; the body carries `agent_type`
            and `agent_id`), `NOT_APPLICABLE_TO_AGENT_TYPE` (422, a voice-only
            setting written on a Voice Assist agent), `AGENT_TYPE_BOUNDARY`
            (409), `AGENT_TYPE_NOT_SUPPORTED` (400), `VOICE_ASSISTANT_REQUIRED`
            (403, the organization is not licensed for Voice Assist),
            `ORGANIZATION_UNAVAILABLE` (503) and `REGION_PROFILE_CONFLICT`
            (503).
    SessionArtifacts:
      type: object
      description: |
        One agent session's artifacts. On success, the artifact fields
        (metadata, timeline_jsonl, transcript, findings, summary, counts,
        recording_*) are populated. On failure, `error` is populated and the
        artifact fields are absent.
      required:
        - session_id
        - call_id
        - agent_id
        - joined_at
        - left_at
        - gcs_prefix
      properties:
        session_id:
          type: string
          description: Agent session id — the GCS prefix key. Authoritative.
        call_id:
          type: string
          nullable: true
          description: >-
            DB call row whose `participant_identity == session_id`, if any.
            Display-only.
        agent_id:
          type: string
          nullable: true
          description: |
            The agent that ran the session; null once that agent is deleted. A
            deleted agent's sessions are still served, with their transcript and
            recording.
        joined_at:
          type: string
          format: date-time
          nullable: true
        left_at:
          type: string
          format: date-time
          nullable: true
        gcs_prefix:
          type: string
          example: gs://example-bucket/calls/<pid>/<session_id>/
        metadata:
          additionalProperties: true
          type: object
        timeline_jsonl:
          type: string
          description: >-
            Raw NDJSON. One event per line, 1-based line numbers
            cross-referenced by `findings[].evidence.line`.
        transcript:
          type: string
        findings:
          type: array
          items:
            $ref: '#/components/schemas/TimelineFinding'
        summary:
          $ref: '#/components/schemas/TimelineSummary'
        fatal_count:
          type: integer
          minimum: 0
        warning_count:
          type: integer
          minimum: 0
        recording_signed_url:
          type: string
          format: uri
          nullable: true
        recording_signed_url_expires_at:
          type: string
          format: date-time
          nullable: true
        dictionary_usage:
          allOf:
            - $ref: '#/components/schemas/DictionaryUsage'
          nullable: true
          description: >
            Dictionary entries in effect for this session, whether each

            kind could take effect, and per-entry hits with the transcript lines

            they touched. `null` when the session recorded none (calls before

            088, runtimes that do not record it, degraded legs) — never zero
            counts.
        caller_auth:
          $ref: '#/components/schemas/CallerAuthSummary'
        error:
          type: object
          description: >-
            Present instead of the artifact fields when this session's GCS fetch
            failed.
          required:
            - status
            - message
          properties:
            status:
              type: integer
            message:
              type: string
    MergedArtifacts:
      type: object
      description: >-
        Cross-session rollup. Findings are tagged with `session_id` so callers
        can locate the source session.
      required:
        - transcript
        - findings
        - summary
        - fatal_count
        - warning_count
      properties:
        transcript:
          type: string
          description: Chronologically-merged transcript across all sessions.
        findings:
          type: array
          items:
            allOf:
              - $ref: '#/components/schemas/TimelineFinding'
              - type: object
                required:
                  - session_id
                properties:
                  session_id:
                    type: string
        summary:
          $ref: '#/components/schemas/TimelineSummary'
        fatal_count:
          type: integer
          minimum: 0
        warning_count:
          type: integer
          minimum: 0
    TimelineFinding:
      type: object
      description: >-
        Deterministic classifier finding over `timeline_jsonl`. `evidence.line`
        is a 1-based line number callers can Read directly to validate the
        diagnosis.
      required:
        - category
        - severity
        - summary
      properties:
        category:
          type: string
          enum:
            - error_event
            - log_error
            - tool_failure
            - silence_recovery
            - repeated_nudges
            - unexpected_end
            - tool_unfinished
            - malformed_event
        severity:
          type: string
          enum:
            - fatal
            - warning
            - info
        summary:
          type: string
        evidence:
          type: object
          properties:
            line:
              minimum: 1
              type: integer
            lines:
              type: array
              items:
                minimum: 1
                type: integer
            ts:
              type: number
            snippet:
              type: string
        extra:
          additionalProperties: true
          type: object
        suggested_file:
          type: string
    TimelineSummary:
      type: object
      description: Aggregate shape of a session's timeline.
      required:
        - total_events
        - session_started
        - session_ended
        - end_call_requested
        - nudge_count
      properties:
        total_events:
          type: integer
          minimum: 0
        session_started:
          type: boolean
        session_ended:
          type: boolean
        end_call_requested:
          type: boolean
        nudge_count:
          type: integer
          minimum: 0
        first_ts:
          type: number
          nullable: true
        last_ts:
          type: number
          nullable: true
    DictionaryUsage:
      type: object
      description: >-
        Which dictionary entries were in effect for the session and how they
        were used.
      required:
        - version
        - kinds
        - totals
        - tier_switched
      properties:
        version:
          type: integer
          example: 1
        kinds:
          type: array
          description: Always three, in order replacements, keyterms, pronunciations.
          items:
            $ref: '#/components/schemas/DictionaryKindUsage'
        totals:
          type: object
          required:
            - entries
            - used
            - hits
          properties:
            entries:
              type: integer
              minimum: 0
            used:
              type: integer
              minimum: 0
            hits:
              type: integer
              minimum: 0
        tier_switched:
          type: boolean
          description: >-
            The STT or TTS tier was not the primary at call end; the status
            describes the primary.
    CallerAuthSummary:
      type: object
      nullable: true
      description: >-
        How caller authentication went on one session. Null when the session
        recorded none. Never carries a private session value.
      required:
        - enabled
        - outcome
        - attempts_used
        - max_attempts
        - verified_at
        - identities
        - refused_tools
        - exhausted_action
      properties:
        enabled:
          type: boolean
          enum:
            - true
        outcome:
          type: string
          enum:
            - verified
            - not_verified
            - exhausted
        attempts_used:
          type: integer
          minimum: 0
        max_attempts:
          type: integer
          nullable: true
        verified_at:
          type: number
          nullable: true
          description: Unix epoch seconds.
        identities:
          type: array
          items:
            additionalProperties:
              type: string
            type: object
        refused_tools:
          type: array
          items:
            type: object
            required:
              - tool
              - ts
            properties:
              tool:
                type: string
              ts:
                type: number
                nullable: true
                description: Unix epoch seconds.
        exhausted_action:
          type: string
          nullable: true
          enum:
            - end_call
            - transfer
            - continue
            - null
    DictionaryKindUsage:
      type: object
      required:
        - kind
        - state
        - reason
        - provider
        - model
        - strategy
        - mode
        - hit_label
        - entries
      properties:
        kind:
          type: string
          enum:
            - replacements
            - keyterms
            - pronunciations
        state:
          type: string
          description: >-
            active | not_supported | disabled | not_applicable (readers MUST
            tolerate other values).
        reason:
          type: string
          nullable: true
          description: >-
            stt_provider_ignores_keyterms | tts_provider_ignores_pronunciations
            | tts_fallback_mixes_providers | pronunciations_not_built |
            realtime_model | no_tts_provider (readers MUST tolerate other
            values).
        provider:
          type: string
          nullable: true
        model:
          type: string
          nullable: true
        strategy:
          type: string
          nullable: true
          description: 'Replacements only: manual | provider_api.'
        mode:
          type: string
          nullable: true
          description: 'Pronunciations only: text | ssml.'
        hit_label:
          type: string
          enum:
            - applied
            - heard
            - found_in_result
        entries:
          type: array
          description: Sorted by hits desc, then runtime order.
          items:
            $ref: '#/components/schemas/DictionaryEntryUsage'
    DictionaryEntryUsage:
      type: object
      required:
        - index
        - dictionary
        - hits
        - trackable
        - occurrences
        - overrides
      properties:
        index:
          type: integer
          minimum: 0
        find:
          type: string
        replace:
          type: string
        term:
          type: string
        pronunciation:
          type: string
        dictionary:
          type: object
          nullable: true
          required:
            - id
            - name
          properties:
            id:
              type: string
            name:
              type: string
        hits:
          type: integer
          minimum: 0
        trackable:
          type: boolean
          description: >-
            false for a provider-applied deletion, whose hits cannot be found in
            the result.
        occurrences:
          type: array
          items:
            type: object
            required:
              - line
              - line_ts
              - speaker
              - count
              - derived
            properties:
              line:
                type: integer
                description: >-
                  1-based line in this session's timeline_jsonl — the transcript
                  row's `(Lnnn)` tag.
              line_ts:
                type: number
                nullable: true
              speaker:
                type: string
                enum:
                  - caller
                  - agent
              count:
                minimum: 1
                type: integer
              derived:
                type: boolean
        overrides:
          type: array
          items:
            type: object
            required:
              - dictionary
              - text
            properties:
              dictionary:
                type: object
                required:
                  - id
                  - name
                properties:
                  id:
                    type: string
                  name:
                    type: string
              text:
                type: string
  responses:
    Unauthorized:
      description: No credential was sent, or the API key is invalid or revoked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Invalid or revoked token
    Forbidden:
      description: >-
        The credential carries no access to this project, or the operation needs
        administrative rights
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  securitySchemes:
    organizationApiKey:
      type: http
      scheme: bearer
      description: >-
        Your organization API key (it starts with `anek_org_`). The same key
        works on the Voice API and the Support API. See
        [Authentication](/authentication).

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.