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

# One caller's memory

> Everything remembered about one person.

The row from the list, plus the rolling `summary`, the recent `transcript` turns, and every `fact`.

Each fact carries where it came from (`source`, `source_channel`) and when it became true
(`valid_from`), so you can tell what the agent learned on which conversation.

There is no way to **edit** a remembered value — by design. You change what the agent looks for (the
agent's memory fields), or you delete: [one fact](/developers/memory/delete-fact) or
[in bulk](/developers/memory/flush).


## OpenAPI

````yaml developers/openapi.json GET /v1/agents/{agent_id}/memory/subjects/{subject_id}
openapi: 3.1.0
info:
  title: Vocily API
  description: >-
    Public REST API for Vocily. Build and configure an agent, publish a version
    and put it live, place outbound calls, and read back calls, chats and what
    the agent remembered. Authenticate with a workspace API key as a Bearer
    token.


    Some things stay in the dashboard, by design: creating an API key, buying or
    connecting a phone number, setting an agent's webhook URL, connecting
    WhatsApp and its templates, building HTTP tools, and running batch
    campaigns.
  version: v1
servers:
  - url: https://api.vocily.ai
    description: Production
security: []
paths:
  /v1/agents/{agent_id}/memory/subjects/{subject_id}:
    get:
      tags:
        - agent-memory
      summary: Get Subject
      description: One caller's whole notebook — their facts, summary and recent turns.
      operationId: get_subject_v1_agents__agent_id__memory_subjects__subject_id__get
      parameters:
        - name: agent_id
          in: path
          required: true
          schema:
            type: string
            title: Agent Id
          description: The agent's id, as `GET /v1/agents` returns it.
        - name: subject_id
          in: path
          required: true
          schema:
            type: string
            title: Subject Id
          description: The remembered person's id, from `GET …/memory/subjects`.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MemorySubjectDetail'
              example:
                id: 00000004-0000-4000-8000-000000000004
                msisdn_full: '+919876543210'
                display_name: Rahul
                fact_count: 3
                interaction_count: 2
                last_channel: phone
                last_seen_at: '2026-09-16T17:41:09Z'
                first_seen_at: '2026-08-30T11:02:55Z'
                summary: >-
                  Returning customer. Prefers WhatsApp. Last called about a
                  delayed order.
                transcript:
                  - role: user
                    content: it still has not arrived
                  - role: assistant
                    content: I have raised it with the courier.
                facts:
                  - id: 00000005-0000-4000-8000-000000000005
                    category: identity
                    key: callee_name
                    value: Rahul
                    source: extracted
                    source_channel: phone
                    valid_from: '2026-08-30T11:04:12Z'
                    expires_at: null
                  - id: 00000006-0000-4000-8000-000000000006
                    category: preference
                    key: preferred_channel
                    value: whatsapp
                    source: extracted
                    source_channel: phone
                    valid_from: '2026-09-16T17:40:02Z'
                    expires_at: null
        '401':
          description: Missing or invalid API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                detail: Invalid API key
                code: UNAUTHORIZED
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '429':
          description: Rate limit exceeded — honor `Retry-After`.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiError'
              example:
                code: rate_limited
      security:
        - bearerAuth: []
components:
  schemas:
    MemorySubjectDetail:
      properties:
        id:
          type: string
          title: Id
          description: This person's id, for reading and erasing their memory.
        msisdn_full:
          type: string
          title: Msisdn Full
          description: Their number, E.164.
        display_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Display Name
          description: What the agent knows them as, if anything.
        fact_count:
          type: integer
          title: Fact Count
          description: How many facts are held about them.
        interaction_count:
          type: integer
          title: Interaction Count
          description: How many conversations they have had with this agent.
        last_channel:
          anyOf:
            - type: string
            - type: 'null'
          title: Last Channel
          description: >-
            How they last got in touch — `voice` (a phone call) or `whatsapp`.
            Widget conversations are not recorded in memory, so they never
            appear here. A **record** of what happened, which is a different
            question from the agent's `memory.channels` setting, which decides
            what is *allowed* to feed memory.
        last_seen_at:
          type: string
          format: date-time
          title: Last Seen At
          description: When they last spoke to it (UTC, ISO 8601).
        first_seen_at:
          type: string
          format: date-time
          title: First Seen At
          description: When they first did (UTC, ISO 8601).
        summary:
          anyOf:
            - type: string
            - type: 'null'
          title: Summary
          description: The agent's running summary of who they are.
        transcript:
          items:
            additionalProperties: true
            type: object
          type: array
          title: Transcript
          description: Recent turns kept as context for the next conversation.
        facts:
          items:
            $ref: '#/components/schemas/MemoryFactRead'
          type: array
          title: Facts
          description: Everything the agent remembers about them, fact by fact.
      type: object
      required:
        - id
        - msisdn_full
        - display_name
        - fact_count
        - interaction_count
        - last_channel
        - last_seen_at
        - first_seen_at
        - summary
        - transcript
        - facts
      title: MemorySubjectDetail
      description: One caller's whole notebook.
    ApiError:
      type: object
      description: >-
        Error envelope. `code` is derived from the HTTP status, so branch on it
        for the CLASS of failure; the specific reason is `detail.code`. Every
        public refusal carries both.
      properties:
        detail:
          type: object
          description: >-
            The reason. `code` is the domain reason (e.g. `call_not_found`) and
            `message` is a sentence safe to log. On a `422` it also carries
            `errors[]`, one entry per rejected field — see
            `HTTPValidationError`.
          properties:
            code:
              type: string
              example: call_not_found
            message:
              type: string
              example: Call not found
          required:
            - code
            - message
        code:
          type: string
          description: Derived from the HTTP status, not the domain reason.
          example: NOT_FOUND
    HTTPValidationError:
      type: object
      title: HTTPValidationError
      description: >-
        A request the API could not read: a field of the wrong type, out of
        range, missing, or one we do not accept. Same envelope as every other
        error.
      properties:
        detail:
          type: object
          description: >-
            What was wrong, as `code`, a one-line `message`, and every offending
            field in `errors`.
          required:
            - code
            - message
            - errors
          properties:
            code:
              type: string
              enum:
                - validation_error
            message:
              type: string
              description: >-
                The first problem in one line, with a count of the rest — e.g.
                `model.temperature: Input should be less than or equal to 2 (and
                1 more)`.
            errors:
              type: array
              items:
                $ref: '#/components/schemas/ValidationError'
              description: >-
                One entry per offending field. **Every problem is reported at
                once**, not just the first, so a malformed body needs one round
                trip to fix rather than one per field.
        code:
          type: string
          enum:
            - VALIDATION_ERROR
          description: Derived from the HTTP status, as on every error.
    MemoryFactRead:
      properties:
        id:
          type: string
          title: Id
          description: >-
            This fact's id. Pass it to `DELETE …/memory/facts/{fact_id}` to
            erase just this one.
        category:
          type: string
          title: Category
          description: >-
            Which group it belongs to — identity, contact, preference, account,
            context.
        key:
          type: string
          title: Key
          description: >-
            Which field it fills, matching a `key` in the agent's
            `memory.fields`.
        value:
          type: string
          title: Value
          description: What is remembered.
        source:
          type: string
          title: Source
          description: >-
            How it was learned. `caller_asserted` — the caller said it, which is
            all the extractor ever hears. `tool_verified` — confirmed by a tool
            against your own system. `operator_set` — set in the dashboard. Only
            `tool_verified` and `operator_set` are established fact.
        source_channel:
          anyOf:
            - type: string
            - type: 'null'
          title: Source Channel
          description: Which channel the conversation was on.
        valid_from:
          type: string
          format: date-time
          title: Valid From
          description: When it was learned (UTC, ISO 8601).
        expires_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Expires At
          description: When it stops being used. `null` means it does not expire.
      type: object
      required:
        - id
        - category
        - key
        - value
        - source
        - source_channel
        - valid_from
        - expires_at
      title: MemoryFactRead
      description: One thing the agent holds about a caller.
    ValidationError:
      type: object
      title: ValidationError
      required:
        - field
        - message
        - type
      properties:
        field:
          type: string
          description: >-
            The offending field as a path from the root of your request —
            `voice.speed`, `variables[0].key`, or `query.limit` for a query
            parameter. **This is the field to read.**
        message:
          type: string
          description: What is wrong with it, in plain language.
        type:
          type: string
          description: >-
            A stable machine code for the kind of failure, e.g.
            `extra_forbidden` for a field we do not accept, `missing` for a
            required one, or `less_than_equal` for a number out of range. Switch
            on this rather than on `message`, which may be reworded.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: 'Your API key as a Bearer token, e.g. `Authorization: Bearer vk_…`.'

````