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

# Get campaign analytics

> Per-contact analytics of a campaign for a period: dialed, connected and converted contacts, the conversion rate, the messages sent by message steps, the outcome flow of the sequence, activity per day and the caller numbers used. Without `from` and `to` the figures cover all time. The period spans at most 366 days. Provider cost is not part of this response. **Required scope:** `campaigns:read` (the legacy `calls:read` scope is also accepted; keys without scope restrictions have full access).



## OpenAPI

````yaml /api-reference/openapi.json get /campaigns/{id}/analytics
openapi: 3.1.0
info:
  title: Famulor API
  version: 1.0.0
  description: >-
    REST API for Famulor. Authenticate with an API key (`fam_...`, created under
    **Settings → API Keys**) or an OAuth 2.0 access token (`fam_at_...`) as a
    Bearer token.


    Every response uses a consistent envelope: `{ "data": ... , "meta": { ... }
    }` on success and `{ "error": { "code", "message" } }` on failure. List
    endpoints paginate with `?limit=` (default 50, max 200) and `?offset=`;
    `meta.pagination.total` carries the total match count.


    REST operations require API Access through the workspace plan or a recurring
    add-on. Without it, regular operations return `403 api_access_required`. The
    invoice-payment and billing-portal operations remain available with a valid
    `billing:write` credential after a failed plan payment so an authorized
    owner, admin, or billing member can recover billing.


    The same customer-facing capabilities are available as MCP tools at
    `https://app.famulor.io/mcp` (Model Context Protocol, streamable HTTP) using
    the same credentials, scopes, and workspace access. MCP availability is
    controlled separately by Connect AI / MCP, not by API Access.
servers:
  - url: https://app.famulor.io/api/v1
    description: Hosted platform.
  - url: https://{domain}/api/v1
    description: White-label tenant domain — same paths, tenant branding.
    variables:
      domain:
        default: app.famulor.io
        description: Your white-label tenant domain.
security:
  - bearerAuth: []
tags:
  - name: Account
    description: Self-inspection of the calling credential.
  - name: Migrations
    description: Preview and import data from supported legacy platforms.
  - name: Assistants
    description: Create and manage voice assistants.
  - name: Tools
    description: >-
      Reusable tools (HTTP APIs, external MCP servers and actions of connected
      apps) assistants can call mid-conversation.
  - name: Voices
    description: Browse the text-to-speech voice library.
  - name: Calls
    description: Start outbound calls and read call history, transcripts and recordings.
  - name: History
    description: Unified conversation history across calls, messaging and assistant emails.
  - name: Campaigns
    description: Outbound calling campaigns with a compliant power dialer.
  - name: Leads
    description: Manage Audience contacts across campaigns, channels and Call QA metrics.
  - name: Segments
    description: >-
      Saved, dynamic lead filters — reusable audience definitions used for
      Audience search and campaign lead assignment.
  - name: Suppression
    description: Cross-channel marketing opt-outs and active workspace suppression records.
  - name: Callbacks
    description: >-
      Scheduled callbacks booked by the Schedule callback tool across voice,
      chat, and email.
  - name: Phone Numbers
    description: Marketplace numbers and customer-provided numbers.
  - name: Famulor Loop
    description: >-
      Personal business-phone access, directory, presence, devices, and Loop
      call recents.
  - name: SIP Trunks
    description: Bring your own SIP provider and numbers.
  - name: Carrier Connections
    description: Connect a supported carrier account and import its existing phone numbers.
  - name: Knowledge Bases
    description: RAG knowledge bases and documents for assistants.
  - name: Settings
    description: Workspace-level settings such as caller-memory defaults.
  - name: Billing
    description: Balance and transaction ledger of the API key's workspace.
  - name: Automations
    description: >-
      Native workspace automations — list, create, update, trigger. Requires
      Automations in the workspace plan.
  - name: Milian Missions
    description: Recurring jobs that Milian runs unattended on schedule.
  - name: Integrations
    description: >-
      Calendar integrations (Cal.com, Calendly, Acuity Scheduling, Google
      Calendar, Outlook, native booking engine). Assign them to assistants to
      provide availability and booking tools, plus provider-supported
      appointment lookup, cancellation, and rescheduling.
  - name: Bookings
    description: >-
      Native booking engine — event types with weekly availability, public
      booking pages at /book/{workspace}/{slug}, and the bookings they produce.
  - name: Dashboards
    description: >-
      Custom analytics dashboards, reusable widgets, and tenant-scoped
      performance analytics. Requires Custom dashboards in the workspace plan.
  - name: Catalog
    description: >-
      Read-only platform catalogs — available models, supported assistant
      languages, and prompt templates.
  - name: Simulations
    description: Assistant simulation tests (plan-gated).
  - name: Versions
    description: Assistant configuration version history.
  - name: Caller IDs
    description: Outbound caller ID verification.
  - name: Widgets
    description: Web widget connectors.
  - name: Messaging
    description: >-
      Telegram, Slack, and Messenger text bots linked to assistants (Chat SDK).
      Includes conversation delay, inactivity end, and conversation-ended
      webhooks.
  - name: QA
    description: Cohort AI Quality Assurance runs over call transcripts.
  - name: White Label
    description: >-
      Manage white-label customer accounts, defaults, credit transfers and
      customer plan offers. Each endpoint documents its required scope and
      workspace eligibility.
  - name: API Keys
    description: >-
      Self-service API keys for the calling workspace or a same-brand workspace
      where the credential's user is owner/admin. A key can only mint further
      keys with a scope subset of its own.
  - name: Workspaces
    description: >-
      List visible workspaces, create an additional workspace for the key owner,
      and mint a dedicated credential for a selected owner/admin workspace.
  - name: SMS
    description: Outbound SMS from workspace phone numbers.
  - name: Milian
    description: >-
      Ask Milian, the AI co-worker in your workspace, and start voice sessions
      with it.
  - name: Translation
    description: >-
      Live translation sessions that interpret a conversation between two
      languages.
  - name: Shopify
    description: Native Shopify app store connections, assistant tools and activity.
  - name: Avatars
    description: Private custom avatars and widget avatar selection.
  - name: Webhook Subscriptions
    description: >-
      Signed workspace event subscriptions, independent of existing
      destinations.
paths:
  /campaigns/{id}/analytics:
    parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: Campaign ID.
    get:
      tags:
        - Campaigns
      summary: Get campaign analytics
      description: >-
        Per-contact analytics of a campaign for a period: dialed, connected and
        converted contacts, the conversion rate, the messages sent by message
        steps, the outcome flow of the sequence, activity per day and the caller
        numbers used. Without `from` and `to` the figures cover all time. The
        period spans at most 366 days. Provider cost is not part of this
        response. **Required scope:** `campaigns:read` (the legacy `calls:read`
        scope is also accepted; keys without scope restrictions have full
        access).
      operationId: getCampaignAnalytics
      parameters:
        - name: from
          in: query
          schema:
            type: string
            example: '2026-11-01'
          description: >-
            Start of the period: an ISO 8601 date or timestamp with a UTC
            offset, for example `2026-11-01` or `2026-11-01T00:00:00+01:00`.
        - name: to
          in: query
          schema:
            type: string
            example: '2026-11-10'
          description: >-
            End of the period (exclusive): an ISO 8601 date or timestamp with a
            UTC offset. Must be after `from`; the period spans at most 366 days.
        - name: phone_number_id
          in: query
          schema:
            type: string
            format: uuid
          description: >-
            Only count contacts called from this caller number (a phone number
            ID). `kpis.messages_sent` is not filtered: messages have no caller
            number.
      responses:
        '200':
          description: The campaign's analytics.
          content:
            application/json:
              schema:
                type: object
                required:
                  - data
                properties:
                  data:
                    $ref: '#/components/schemas/CampaignAnalytics'
              example:
                data:
                  available: true
                  campaign_kind: sequence
                  range:
                    from: '2026-11-01T00:00:00.000Z'
                    to: '2026-11-10T00:00:00.000Z'
                    timezone: Europe/Berlin
                  kpis:
                    dialed: 2
                    connected: 1
                    converted: 1
                    conversion_rate: 0.5
                    dials: 3
                    connected_calls: 1
                    total_duration_sec: 61
                  enrolled: 4
                  enroll_failed: 0
                  sankey:
                    nodes:
                      - id: 0:enrolled
                        key: enrolled
                        label: Enrolled
                        kind: root
                        step: 0
                        value: 4
                      - id: 1:goal_reached
                        key: goal_reached
                        label: Goal reached
                        kind: converted
                        step: 1
                        value: 1
                      - id: 1:~waiting
                        key: waiting
                        label: Waiting
                        kind: final
                        step: 1
                        value: 3
                    links:
                      - source: 0:enrolled
                        target: 1:~waiting
                        value: 3
                      - source: 0:enrolled
                        target: 1:goal_reached
                        value: 1
                  series:
                    - day: '2026-11-01'
                      dials: 3
                      connected: 1
                      converted: 1
                  caller_numbers:
                    - phone_number_id: b1c2d3e4-0000-4000-8000-000000000002
                      number: '+4930123456'
                      dials: 3
                  currency: EUR
                  display_currency: EUR
                  display_currency_rate: 1
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '503':
          $ref: '#/components/responses/CampaignOrProtectionUnavailable'
        '504':
          $ref: '#/components/responses/AnalyticsTimeout'
components:
  schemas:
    CampaignAnalytics:
      type: object
      description: >-
        Per-contact campaign analytics for a period: KPIs, the outcome flow,
        activity per day and caller numbers. Provider cost is not part of the
        public payload.
      required:
        - available
        - campaign_kind
        - range
        - kpis
        - enrolled
        - enroll_failed
        - sankey
        - series
        - caller_numbers
        - currency
        - display_currency
        - display_currency_rate
      properties:
        available:
          type: boolean
          const: true
          description: Always `true` in a successful response.
        campaign_kind:
          type: string
          enum:
            - sequence
            - classic
          description: >-
            `sequence` when the campaign has a sequence, `classic` otherwise.
            Classic campaigns show their contact statuses in `sankey` instead of
            outcomes.
        range:
          type: object
          required:
            - from
            - to
            - timezone
          description: The period the figures cover.
          properties:
            from:
              type:
                - string
                - 'null'
              format: date-time
              description: Start of the period. `null` for no lower bound.
            to:
              type:
                - string
                - 'null'
              format: date-time
              description: End of the period. `null` for no upper bound.
            timezone:
              type: string
              description: >-
                Campaign time zone (IANA). Days in `series` are local days of
                this zone.
        kpis:
          type: object
          required:
            - dialed
            - connected
            - converted
            - conversion_rate
            - dials
            - connected_calls
            - total_duration_sec
            - messages_sent
          description: >-
            Figures for the period. `dialed`, `connected` and `converted` count
            contacts, `dials`, `connected_calls` and `messages_sent` count calls
            and messages.
          properties:
            dialed:
              type: integer
              minimum: 0
              description: Contacts with at least one call in the period.
            connected:
              type: integer
              minimum: 0
              description: >-
                Contacts with at least one answered call: it completed, did not
                reach a voicemail or an unavailable number, and had talk time.
            converted:
              type: integer
              minimum: 0
              description: >-
                Contacts that reached a successful end in the period. Campaigns
                without a sequence count contacts with a call marked successful,
                or whose `goal_variable` is true.
            conversion_rate:
              type:
                - number
                - 'null'
              minimum: 0
              maximum: 1
              description: >-
                `converted` divided by `dialed`, at most 1. `null` while nothing
                was dialed.
            dials:
              type: integer
              minimum: 0
              description: Calls placed in the period.
            connected_calls:
              type: integer
              minimum: 0
              description: Answered calls in the period.
            total_duration_sec:
              type: integer
              minimum: 0
              description: Total talk time of those calls in seconds.
            messages_sent:
              type: integer
              minimum: 0
              description: >-
                Messages delivered by message steps (SMS, WhatsApp, email) in
                the period. Does not include messages that could not be sent.
                Always counts the whole campaign: messages have no caller
                number, so the `phone_number_id` filter does not apply to this
                figure.
        enrolled:
          type: integer
          minimum: 0
          description: Contacts in the campaign.
        enroll_failed:
          type: integer
          minimum: 0
          description: >-
            Contacts that were never called: suppressed, invalid number or no
            calling window.
        sankey:
          type: object
          required:
            - nodes
            - links
          description: >-
            Outcome flow from the enrolled contacts through the outcomes of each
            step (up to four steps; later steps are combined as `More`). Message
            steps contribute `sent`, `replied` and `not_sent`. Empty for an
            empty campaign.
          properties:
            nodes:
              type: array
              items:
                $ref: '#/components/schemas/CampaignAnalyticsSankeyNode'
              description: Nodes, sorted by step and then by size.
            links:
              type: array
              items:
                $ref: '#/components/schemas/CampaignAnalyticsSankeyLink'
              description: Links between nodes, largest first.
        series:
          type: array
          description: One point per local day of the period (at most 366), without gaps.
          items:
            type: object
            required:
              - day
              - dials
              - connected
              - converted
            properties:
              day:
                type: string
                format: date
                description: Local day, `YYYY-MM-DD`.
              dials:
                type: integer
                minimum: 0
                description: Calls placed that day.
              connected:
                type: integer
                minimum: 0
                description: Answered calls that day.
              converted:
                type: integer
                minimum: 0
                description: Contacts converted that day.
        caller_numbers:
          type: array
          description: Numbers the calls in the period were placed from.
          items:
            type: object
            required:
              - phone_number_id
              - number
              - dials
            properties:
              phone_number_id:
                type: string
                format: uuid
                description: Phone number ID.
              number:
                type: string
                description: The number in E.164 format.
              dials:
                type: integer
                minimum: 0
                description: Calls placed from this number.
        currency:
          type: string
          deprecated: true
          description: >-
            Always `EUR`. Kept for compatibility: this response contains no
            money amounts.
          example: EUR
        display_currency:
          type: string
          description: >-
            Workspace's resolved display currency. This response contains no
            money amounts; the value is informational.
          example: USD
        display_currency_rate:
          type: number
          description: >-
            Units of display_currency per 1 EUR; 0 when the platform has not
            configured a rate yet.
          example: 1.08
    CampaignAnalyticsSankeyNode:
      type: object
      required:
        - id
        - key
        - label
        - kind
        - step
        - value
      properties:
        id:
          type: string
          description: Node id, `<step>:<key>`. Unique within the graph.
        key:
          type: string
          description: >-
            Outcome id, `enrolled`, a built-in outcome id (`do_not_call`,
            `no_response`, `other`, and for message steps `sent`, `replied`,
            `not_sent`) or a final state.
        label:
          type: string
          description: >-
            Display name of the node. Outcome labels are workspace data and are
            not translated.
        kind:
          type: string
          enum:
            - root
            - outcome
            - converted
            - do_not_call
            - no_response
            - other
            - final
            - bucket
          description: >-
            `root`: all enrolled contacts. `outcome`: an outcome you defined, or
            `sent` / `replied` of a message step. `converted`: an outcome that
            ends successfully. `do_not_call`, `no_response` and `other`: the
            built-in call outcomes. `no_response` also covers `not_sent` (a
            message that could not be sent). `final`: contacts without an
            outcome yet (not reached, in progress, waiting). `bucket`: a status
            bucket of classic campaigns, or `More` for steps beyond the fourth.
        step:
          type: integer
          minimum: 0
          description: >-
            Column of the flow: 0 is the enrolled contacts, 1 to 4 the outcome
            steps.
        value:
          type: integer
          minimum: 0
          description: Number of contacts that reach this node.
    CampaignAnalyticsSankeyLink:
      type: object
      required:
        - source
        - target
        - value
      properties:
        source:
          type: string
          description: '`id` of the node the contacts come from.'
        target:
          type: string
          description: '`id` of the node the contacts go to.'
        value:
          type: integer
          minimum: 1
          description: Number of contacts on this link.
    ErrorEnvelope:
      type: object
      description: Error envelope returned by every /api/v1 endpoint on failure.
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - forbidden
                - api_access_required
                - not_found
                - invalid_request
                - rate_limited
                - conflict
                - telephony_configuration_error
                - telephony_unavailable
                - destination_forbidden
                - internal_error
                - service_unavailable
                - verification_address_required
                - bundle_address_missing
              description: >-
                Stable, machine-readable error code. `service_unavailable` is
                returned by POST /bookings and GET
                /booking-event-types/{id}/slots specifically when the
                availability engine could not be reached (see
                AvailabilityOrProtectionUnavailable).
                `verification_address_required` and `bundle_address_missing` are
                returned by POST /phone-numbers when the verification behind the
                number has no address (see the operation description).
            message:
              type: string
              description: Human-readable description of the error.
            reason:
              type: string
              description: >-
                Optional, more specific and stable reason for this error, for
                example `plan_required`, `read_only_role` or `missing_scope`.
                Branch on `code` first: `reason` is only present on some errors,
                and new values may be added. Campaign operations use
                `attestation_required` (400, `compliance_attestation` missing on
                launch), `launch_required` (400, a sequence campaign was never
                launched; launch it or start it with `compliance_attestation`),
                `sequence_changed` (409, the sequence changed after
                `sequence_hash` was taken), `campaign_sequences_unavailable`
                (403, the plan does not include Campaign sequences),
                `campaign_extension_unavailable` (503 `service_unavailable`, the
                campaign feature is not available yet) and `analytics_timeout`
                (504 `service_unavailable`, the campaign analytics took too
                long; choose a shorter period).
            hint:
              type: string
              description: >-
                Optional recovery advice that is safe to show to the end user,
                for example which settings page to open.
  responses:
    BadRequest:
      description: Invalid request body or parameters.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: invalid_request
              message: '"to_number" is required (E.164 format, e.g. +4930123456).'
    Unauthorized:
      description: Missing, invalid, expired or revoked API key / access token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: unauthorized
              message: Invalid API key.
    Forbidden:
      description: >-
        The credential lacks the required scope or role, or the workspace does
        not have the required capability.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            scopeDenied:
              summary: Required scope is missing
              value:
                error:
                  code: forbidden
                  message: >-
                    This API key is missing the required scope
                    "assistants:write".
            apiAccessRequired:
              summary: API Access is not available
              value:
                error:
                  code: api_access_required
                  message: >-
                    API Access is not available for this workspace. Review
                    Settings → Plan.
    NotFound:
      description: Resource not found (or it belongs to another workspace).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: not_found
              message: Assistant not found
    RateLimited:
      description: Too many requests. Retry after the indicated delay.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            minimum: 1
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: rate_limited
              message: Too many requests. Retry after the indicated delay.
    CampaignOrProtectionUnavailable:
      description: >-
        Either request protection is temporarily unavailable (code
        `internal_error`), or the campaign dialer feature is not available yet
        (code `service_unavailable`; write operations add the reason
        `campaign_extension_unavailable`). Retry after a short delay in both
        cases.
      headers:
        Retry-After:
          description: Seconds to wait before retrying.
          schema:
            type: integer
            minimum: 1
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          examples:
            requestProtectionUnavailable:
              summary: Request protection unavailable
              value:
                error:
                  code: internal_error
                  message: Request protection is temporarily unavailable.
            campaignFeatureUnavailable:
              summary: Campaign dialer not available yet
              value:
                error:
                  code: service_unavailable
                  message: This campaign feature is not available yet.
                  reason: campaign_extension_unavailable
    AnalyticsTimeout:
      description: >-
        The analytics took longer than the time limit (code
        `service_unavailable`, reason `analytics_timeout`). Choose a shorter
        period and try again.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorEnvelope'
          example:
            error:
              code: service_unavailable
              message: >-
                The analytics took too long. Choose a shorter range and try
                again.
              reason: analytics_timeout
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: >-
        API key (`fam_...`, created under **Settings → API Keys**) or an OAuth
        2.0 access token (`fam_at_...`). REST operations also require API Access
        for the credential's workspace. Keys can be restricted to scopes such as
        `assistants:read`, `calls:write`, `campaigns:write`, `automations:read`,
        `dashboards:read`, `dashboards:write`, `leads:write`, `segments:write`,
        `loop:read`, `loop:write`, `phone_numbers:write`, `sip_trunks:write`,
        `knowledge:write`, `voices:read`, `billing:read`, `billing:write`,
        `settings:write`, `platform:read`, `platform:write`; a `*:write` scope
        implies the matching `*:read`. Automation and dashboard endpoints also
        accept the legacy `calls:*` scope. Keys without scope restrictions have
        full access within the workspace's available capabilities.

````

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