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

# Retrieve recordings for conversations

> Retrieve recording URLs for every call in the requested conversation sequences, optionally with each call's transcript.

Two limits apply. At most **100 sequence IDs** per request, and those sequences may contain at most **500 calls** in total — a few long sequences can exceed the call limit while well under the sequence limit, in which case split the IDs across requests. Nothing is truncated silently.

Sequences you cannot see are reported in `notFound` rather than failing the request.



## OpenAPI

````yaml /openapi.json post /recordings
openapi: 3.1.0
info:
  title: Julian API
  version: 1.0.0
  description: >-
    API for Julian, 11x's AI calling platform. Programmatically enroll contacts
    into agent calling sequences, manage sequences, and track credit usage. All
    requests are authenticated with an organization API key in the `x-api-key`
    header and rate limited to 10 requests per second per key (HTTP 429 when
    exceeded).
servers:
  - url: https://julian.11x.ai/api/v1
security:
  - apiKeyAuth: []
tags:
  - name: Scheduling
    description: Enroll contacts into an agent's calling sequence.
  - name: Sequences
    description: Manage active sequences.
  - name: Agents
    description: Read agent configuration.
  - name: Conversation Meetings
    description: >-
      Manage the meeting booked during a conversation — list its attendees, add
      attendees before it starts, and cancel it. Every endpoint is addressed by
      an `entityId` that identifies the conversation. Today only voice calls are
      supported, with the form of the call prefix followed by the call ID (e.g.
      `call.abc123`). The meeting is resolved from the calendar booking created
      during the conversation, and the calendar provider remains the source of
      truth.
  - name: Conversation Metadata
    description: >-
      Retrieve completed conversation data asynchronously — designed for batch
      ingestion, backfills, and reconciliation jobs that pull conversation
      metadata instead of receiving it through a webhook.


      **Recommended batch ingestion flow:**


      1. Call `GET /conversations/search/{agentId}` with the time window you
      want to ingest (e.g. yesterday or the last seven days).

      2. Iterate through the returned `sequenceIds`.

      3. For each sequence ID, call `GET /conversations/metadata/{sequenceId}`.

      4. Store the returned `metadata` array in your warehouse.

      5. Use `limit`, `offset`, and `hasMore` to paginate through larger
      backfills.
  - name: Credits
    description: Track credit utilization.
  - name: Webhooks
    description: Events Julian sends to your endpoint.
  - name: Recordings
    description: >-
      Fetch call audio, and optionally transcripts.


      A recording belongs to a single call, so `GET /recordings/{callId}` is
      addressed by call ID. The bulk endpoint selects by **sequence** ID
      instead, because that is the unit `GET /conversations/search/{agentId}`
      returns — same resource, two selectors.


      **Bulk export flow:**


      1. Call `GET /conversations/search/{agentId}` for the window you want.

      2. Pass a page of the returned `sequenceIds` to `POST /recordings` (up to
      100 per request).

      3. Download each `url` before it expires; re-fetch individual calls later
      with `GET /recordings/{callId}`.


      Recording URLs are signed and short-lived — see `expiresAt` on each entry.
paths:
  /recordings:
    post:
      tags:
        - Recordings
      summary: Retrieve recordings for conversations
      description: >-
        Retrieve recording URLs for every call in the requested conversation
        sequences, optionally with each call's transcript.


        Two limits apply. At most **100 sequence IDs** per request, and those
        sequences may contain at most **500 calls** in total — a few long
        sequences can exceed the call limit while well under the sequence limit,
        in which case split the IDs across requests. Nothing is truncated
        silently.


        Sequences you cannot see are reported in `notFound` rather than failing
        the request.
      operationId: listRecordings
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecordingsRequest'
      responses:
        '200':
          description: Recordings grouped by conversation sequence.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecordingsResponse'
        '400':
          description: >-
            `INVALID_REQUEST` — no sequence IDs, or more than 100.

            `TOO_MANY_CALLS` — the requested sequences contain more than 500
            calls in total.

            `INVALID_REQUEST_BODY` — the body is not valid JSON.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
components:
  schemas:
    RecordingsRequest:
      type: object
      properties:
        sequenceIds:
          type: array
          items:
            type: string
          minItems: 1
          maxItems: 100
          description: >-
            Conversation sequence IDs, as returned by `GET
            /conversations/search/{agentId}`. Duplicates are collapsed.
          example:
            - call-sequence.xyz123
            - call-sequence.xyz456
        includeTranscripts:
          type: boolean
          default: false
          description: >-
            When `true`, include each call's transcript text alongside its
            recording.
      required:
        - sequenceIds
    RecordingsResponse:
      type: object
      properties:
        recordings:
          type: array
          items:
            $ref: '#/components/schemas/SequenceRecordings'
        notFound:
          type: array
          items:
            type: string
          description: >-
            Requested sequence IDs that do not exist or do not belong to your
            organization. Omitted when every requested ID resolved.
      required:
        - recordings
    Error:
      type: object
      required:
        - error
        - message
      properties:
        error:
          type: string
          description: Machine-readable error code.
          example: INVALID_PHONE_NUMBER
        message:
          type: string
          description: Human-readable explanation.
    SequenceRecordings:
      type: object
      properties:
        sequenceId:
          type: string
          example: call-sequence.xyz123
        calls:
          type: array
          description: One entry per call in the sequence, ordered by call step.
          items:
            $ref: '#/components/schemas/CallRecordingEntry'
      required:
        - sequenceId
        - calls
    CallRecordingEntry:
      type: object
      description: Recording — and optionally transcript — for a single call.
      properties:
        callId:
          type: string
          example: call.abc123
        recordingStatus:
          type: string
          enum:
            - downloaded
            - no-recording
            - call-not-found
          description: >-
            Whether audio was located for this call. Describes the **audio
            only** — a call can have a transcript and no recording, so do not
            filter on this value when you also want transcripts.


            - `downloaded` — audio was located and `url` is present.

            - `no-recording` — the call has no retrievable audio (never
            recorded, cleaned up, or hosted by a provider this API cannot sign
            for).

            - `call-not-found` — no call exists for the id.
        url:
          type: string
          format: uri
          description: >-
            Short-lived link to the call audio. Absent when `recordingStatus` is
            not `downloaded`.


            Treat this as a secret: anyone holding the URL can fetch the audio
            until it expires, so do not forward it into tickets or third-party
            tools.
        expiresAt:
          type: string
          format: date-time
          description: >-
            When `url` stops working — **3 hours** after the response is
            generated. Present only for URLs this API signs; provider-hosted
            audio carries its own lifetime, which we do not control and
            therefore do not report. Re-fetch with `GET /recordings/{callId}` at
            any time.
        durationSeconds:
          type: integer
          example: 184
        scheduledAt:
          type: string
          format: date-time
        stepNumber:
          type: integer
          description: Position of this call within its sequence.
          example: 1
        transcript:
          type: string
          description: >-
            Formatted transcript text. Present only when transcripts were
            requested and the call has one — independent of `recordingStatus`.
          example: '[Agent] (0:00): Hi, is this Victor?'
      required:
        - callId
        - recordingStatus
  responses:
    Unauthorized:
      description: >-
        `UNAUTHORIZED` or `INVALID_API_KEY` — API key missing, invalid, or not
        authorized for this agent's organization.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missingApiKey:
              summary: Missing API key
              value:
                error: UNAUTHORIZED
                message: >-
                  API key is required. Please provide your API key in the
                  x-api-key header.
            invalidApiKey:
              summary: Invalid API key
              value:
                error: INVALID_API_KEY
                message: The provided API key is invalid.
    InternalServerError:
      description: >-
        `INTERNAL_SERVER_ERROR` — unexpected server error. Retry with backoff
        and contact the 11x team if it persists.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: INTERNAL_SERVER_ERROR
            message: Internal Server Error. Please contact 11x team.
  securitySchemes:
    apiKeyAuth:
      type: apiKey
      in: header
      name: x-api-key
      description: Organization API key. Get it from the 11x team or from the platform.

````