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

# Live channels

> Read from FreeSWITCH on every request, never cached: the switch is the only thing that knows, and a cached copy is wrong the moment a call ends.



## OpenAPI

````yaml /api-reference/openapi-public.json get /calls/active
openapi: 3.0.3
info:
  description: >-
    The API your own systems use: place and follow calls, have an AI agent call
    someone, run campaigns and get their results, keep contacts in step with
    your CRM, and receive signed webhooks. Authenticate with an integration key
    (Authorization: Bearer ft_...), used only from the IP addresses it allows.
  title: FireTone API
  version: 0.1.0
servers:
  - description: Your platform's API host
    url: https://{host}/api/v1
    variables:
      host:
        default: api.firet.one
security:
  - bearerAuth: []
tags:
  - name: Auth
  - description: >-
      Live calls and what can be done to them: hang up, hold, transfer, park,
      merge, monitor, whisper; the Desk's own call.
    name: Calls
  - description: 'Outbound campaigns: contacts, attempts, outcomes.'
    name: Campaigns
  - description: 'Customers: who called, what is known about them, and their memory.'
    name: Contacts
  - description: What was said on an AI call, and the review of it.
    name: Conversations
  - description: >-
      Your own systems: HTTP connections an IVR calls mid-call, and webhooks for
      call events. Tenant URLs must be public https addresses.
    name: Integrations
  - name: Live
  - name: Provisioning
  - name: Reporting
  - description: Tickets raised by people, agents and the API.
    name: Tickets
  - description: Messages left for an extension or a queue.
    name: Voicemail
paths:
  /calls/active:
    get:
      tags:
        - Live
      summary: Live channels
      description: >-
        Read from FreeSWITCH on every request, never cached: the switch is the
        only thing that knows, and a cached copy is wrong the moment a call
        ends.
      operationId: getCallsActive
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ActiveCallPage'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
components:
  schemas:
    ActiveCallPage:
      properties:
        items:
          items:
            $ref: '#/components/schemas/ActiveCall'
          type: array
        limit:
          type: integer
        offset:
          type: integer
        total:
          type: integer
      required:
        - items
        - total
        - limit
        - offset
      type: object
    ActiveCall:
      properties:
        agent_ids:
          description: >-
            Everyone on this call the server can identify, empty or absent when
            nobody can be. A LIST because the switch reports an internal call as
            ONE channel row naming both parties — the extension that placed it
            and the extension that took it — so a single-valued field names one
            of them and the other agent's desk shows nothing while their handset
            is in their hand. Resolved server-side from the numbers on the leg
            (accountcode, callee_num, presence_id, dest, cid_num); a number
            owned by two agents or two organisations in scope contributes
            nothing rather than a guess. Empty means "cannot attribute", never
            "not yours": a client must not read it as a negative answer. It
            exists so a client stops deciding this by comparing extension
            strings, which claims a stranger's call where the same extension
            number exists in two tenants, and misses a queue call whose agent is
            named only in callee_num.
          items:
            format: uuid
            type: string
          type: array
        call_uuid:
          format: uuid
          type: string
        caller_number:
          type: string
        codec:
          type: string
        context:
          type: string
        created_at:
          type: string
        destination_number:
          type: string
        direction:
          type: string
        muted_agent_ids:
          description: >-
            The subset of agent_ids whose browser phone reports its microphone
            muted (POST /me/phone). A handset's mute is never known, so absence
            means not reported.
          items:
            format: uuid
            type: string
          type: array
        started_at:
          description: >-
            When the call began, from the switch's created_epoch. Use this
            rather than created_at, which is switch-local text with no zone.
          format: date-time
          type: string
        state:
          example: ACTIVE
          type: string
      required:
        - call_uuid
        - direction
        - state
      type: object
    Error:
      properties:
        error:
          properties:
            code:
              enum:
                - invalid_request
                - invalid_credentials
                - unauthenticated
                - forbidden
                - not_found
                - conflict
                - internal
              type: string
            message:
              type: string
          required:
            - code
            - message
          type: object
      required:
        - error
      type: object
  responses:
    Unauthorized:
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
      description: Missing, invalid or expired token
  securitySchemes:
    bearerAuth:
      bearerFormat: JWT or API key
      description: >-
        Every request sends `Authorization: Bearer <token>`. The token is either
        a panel session (a JWT from /auth/login, 12 hours) or an API key
        `ft_<id>_<secret>`. An API key is accepted only from an address on its
        IP allowlist (403 ip_not_allowed otherwise; 403 ip_allowlist_required
        for an old key that has none), is limited to its rate per minute (429
        rate_limited with Retry-After; X-RateLimit-Limit/Remaining/Reset on
        every response), and at most 60 call placements a minute.
      scheme: bearer
      type: http

````