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

# List a campaign's outcomes

> One row per connected call, carrying the outcome post-call analysis recorded — a booked appointment, a qualified lead, an RSVP, whatever the campaign's goal defines as a result. The shape of each outcome and the labels to render it under follow that goal; `vocabulary` tells your UI which set applies. Contacts never dialed or never answered are not here — they live in [`/campaigns/{campaignId}/calls`](/api-reference/campaign-outcomes/list-a-campaigns-calls) — and a campaign with no scorecard produces no rows at all.

**Note:** Scores, conversions, and sentiment are computed by LLMs — best effort, with room to be wrong. We are continuously closing the tracking gaps, but for sensitive workloads we recommend running your own analysis on the transcripts delivered over [webhooks](/voice-agents/webhooks/overview).



## OpenAPI

````yaml /voice-agents/api-reference/openapi.yaml get /campaigns/{campaignId}/results
openapi: 3.1.0
info:
  title: UpliftAI Voice Agents API
  version: '1.0'
  description: >-
    Build voice assistants, start conversations on the web or the phone, run
    calling campaigns, and receive outcomes by webhook. All endpoints take a
    bearer API key unless noted otherwise.
servers:
  - url: https://api.upliftai.org/v1
security:
  - apiKey: []
tags:
  - name: Assistants
  - name: Authoring an assistant
  - name: Starting a conversation
  - name: Sessions & call records
  - name: Campaigns
  - name: Campaign outcomes
  - name: Contacts
  - name: Google Sheet sources
  - name: Integrations & delivery health
paths:
  /campaigns/{campaignId}/results:
    get:
      tags:
        - Campaign outcomes
      summary: List a campaign's outcomes
      description: >-
        One row per connected call, carrying the outcome post-call analysis
        recorded — a booked appointment, a qualified lead, an RSVP, whatever the
        campaign's goal defines as a result. The shape of each outcome and the
        labels to render it under follow that goal; `vocabulary` tells your UI
        which set applies. Contacts never dialed or never answered are not here
        — they live in
        [`/campaigns/{campaignId}/calls`](/api-reference/campaign-outcomes/list-a-campaigns-calls)
        — and a campaign with no scorecard produces no rows at all.


        **Note:** Scores, conversions, and sentiment are computed by LLMs — best
        effort, with room to be wrong. We are continuously closing the tracking
        gaps, but for sensitive workloads we recommend running your own analysis
        on the transcripts delivered over
        [webhooks](/voice-agents/webhooks/overview).
      operationId: getCampaignResults
      parameters:
        - name: campaignId
          in: path
          required: true
          schema:
            type: string
            format: uuid
          example: a5be4d9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx
        - name: limit
          in: query
          description: Rows per page. Values above 100 are clamped, not rejected.
          required: false
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
        - name: cursor
          in: query
          description: The `nextCursor` of the previous page.
          required: false
          schema:
            type: string
      responses:
        '200':
          description: One page of outcomes, newest first.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CampaignResults'
              example:
                artifactModel: lead_list
                vocabulary:
                  conversionVerb: qualified
                  conversionNoun: lead
                rows:
                  - sessionId: a5be4d9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx#+923001234567#a1
                    goalKind: lead
                    name: عائشہ خان
                    phone: '+923001234567'
                    runId: d1403129-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                    payload:
                      kind: lead
                      status: qualified
                      interest: سائبر سیکیورٹی ڈپلومہ
                      nextStep: ڈیمو سیشن کے لیے رابطہ
                      summary: پروگرام میں دلچسپی ہے، فیس اور شیڈول بتا دیا گیا۔
                    createdAt: '2026-08-18T05:16:47.324Z'
                  - sessionId: a5be4d9e-xxxx-xxxx-xxxx-xxxxxxxxxxxx#03214567890#a2
                    goalKind: lead
                    name: بلال احمد
                    phone: '03214567890'
                    runId: d1403129-xxxx-xxxx-xxxx-xxxxxxxxxxxx
                    payload:
                      kind: lead
                      status: callback
                      notes: شام چھ بجے دوبارہ کال کرنے کو کہا۔
                    createdAt: '2026-08-18T05:11:02.881Z'
        '400':
          description: The `cursor` could not be decoded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
              example:
                message: Invalid pagination cursor
                error: Bad Request
                statusCode: 400
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
components:
  schemas:
    CampaignResults:
      type: object
      properties:
        artifactModel:
          description: The row shape this campaign's goal produces.
          type: string
          enum:
            - day_sheet
            - guest_list
            - lead_list
            - order_list
            - payment_list
            - outreach_list
            - reservation_list
        vocabulary:
          description: >-
            How this goal words a successful outcome, for labelling a UI:
            `booked` an `appointment`, `qualified` a `lead`.
          type: object
          properties:
            conversionVerb:
              type: string
            conversionNoun:
              type: string
        rows:
          description: >-
            Ordered newest first by `slotIso` where the goal has one, by
            `createdAt` otherwise.
          type: array
          items:
            $ref: '#/components/schemas/CampaignResultRow'
        nextCursor:
          type: string
          description: Absent on the last page.
    Error:
      type: object
      properties:
        message:
          description: >-
            One message per failed field for validation errors, a single string
            otherwise.
          oneOf:
            - type: string
            - type: array
              items:
                type: string
        error:
          type: string
        statusCode:
          type: integer
    CampaignResultRow:
      type: object
      properties:
        sessionId:
          description: >-
            The call that produced this outcome, as
            `{campaignId}#{contactId}#a{attempt}`. Pass it to the [session
            detail](/api-reference/sessions-%26-call-records/get-a-calls-transcript-and-outcomes)
            for the transcript and recording.
          type: string
        goalKind:
          type: string
          enum:
            - appointment
            - event
            - lead
            - order_confirmation
            - payment_reminder
            - outreach
            - reservation_confirmation
        name:
          description: Contact name as enrolled. Absent for contacts that carried no name.
          type: string
        phone:
          description: >-
            The number as supplied in the contact list — local (`0300…`) or
            E.164 (`+92300…`), not normalized.
          type: string
        runId:
          description: The launch run that enrolled this contact.
          type: string
          format: uuid
        payload:
          $ref: '#/components/schemas/ConversionPayload'
        slotIso:
          description: >-
            The time the caller agreed to, on goals that carry one (appointment,
            event, reservation).
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
    ConversionPayload:
      description: >-
        What the agent got out of the call. `kind` tracks the campaign's
        `goalKind`, except that an `event` campaign records `rsvp` payloads.
        Every field but `kind` is best-effort — the agent omits whatever the
        caller never said.
      oneOf:
        - title: Appointment
          type: object
          properties:
            kind:
              type: string
              const: appointment
            outcome:
              type: string
            summary:
              type: string
        - title: RSVP
          type: object
          properties:
            kind:
              type: string
              const: rsvp
            outcome:
              type: string
              enum:
                - confirmed
                - maybe
            party:
              type: integer
              minimum: 1
              description: Headcount the caller is bringing, including themselves.
            summary:
              type: string
        - title: Lead
          type: object
          properties:
            kind:
              type: string
              const: lead
            outcome:
              type: string
            status:
              type: string
              enum:
                - qualified
                - callback
                - not_interested
                - wrong_person
                - needs_human
            interest:
              type: string
            nextStep:
              type: string
            notes:
              type: string
            summary:
              type: string
        - title: Order confirmation
          type: object
          properties:
            kind:
              type: string
              const: order_confirmation
            status:
              type: string
              enum:
                - confirmed
                - cancelled
                - amended
                - address_incomplete
                - wrong_person
                - callback
            address:
              type: string
              description: Delivery address as the caller gave or corrected it.
            orderId:
              type: string
            orderValue:
              type: object
              properties:
                amount:
                  type: number
                currency:
                  type: string
            summary:
              type: string
        - title: Payment reminder
          type: object
          properties:
            kind:
              type: string
              const: payment_reminder
            status:
              type: string
              enum:
                - will_pay
                - already_paid
                - dispute
                - callback
                - wrong_person
            promiseDate:
              type: string
              description: The date the caller committed to pay by.
            summary:
              type: string
        - title: Outreach
          type: object
          properties:
            kind:
              type: string
              const: outreach
            status:
              type: string
              enum:
                - interested
                - callback
                - not_interested
                - wrong_person
            summary:
              type: string
        - title: Reservation confirmation
          type: object
          properties:
            kind:
              type: string
              const: reservation_confirmation
            status:
              type: string
              enum:
                - confirmed
                - cancelled
                - rescheduled
                - wrong_person
                - callback
            party:
              type: integer
              minimum: 1
            reservationTime:
              type: string
            summary:
              type: string
  responses:
    Unauthorized:
      description: A bearer key was sent but is not recognized.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            message: invalid authorization
            error: Unauthorized
            statusCode: 401
    Forbidden:
      description: No API key sent, or the key lacks permission for this resource.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            message: Forbidden resource
            error: Forbidden
            statusCode: 403
    NotFound:
      description: No such resource in the API key's project.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            message: 'Realtime assistant not found: 00000000-0000-4000-8000-000000000000'
            error: Not Found
            statusCode: 404
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: Project API key (`sk_api_…`).

````