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

> ## Agent Instructions
> Use the public API base URL: https://api.teamfollowup.ai/api.
> Authenticate public API requests with Authorization: Bearer YOUR_API_KEY.
> Use product-owned terms: agents, campaigns, projects (GoHighLevel sub-accounts), contacts, calls, outcomes, skills, cadences, phone numbers.
> Scope requests by locationId rather than projectName.
> Read the guide linked from each API reference group before recommending an endpoint.

# Look up TFU Live resources

> TFU Live only. What a workflow’s settings may name in this sub-account: calendars (Find slots, Cancel appointment), tags (tag nodes), custom_fields (contact.custom.<id>), pipelines and their stages (Move stage), reps and teams (Transfer). The same lookups a save verifies against. status unavailable means the lookup could not run, never that there are none.

Required scope: `agents:read`.

Required API key scope: `agents:read`.



## OpenAPI

````yaml /openapi.yaml get /api/tfu-live-agents/{id}/resources/{kind}
openapi: 3.1.0
info:
  title: TFUAI Server API
  version: 1.0.0
  description: >-
    API reference for the TFUAI SaaS server.


    All published endpoints are mounted under `/api`. Responses use a standard
    envelope: `{ "success": true, ... }` on success and `{ "success": false,
    "error": "..." }` on failure.


    Product API modules are being launched module by module. This spec currently
    exposes only contracted public modules.


    Authenticate public API requests with an API key in the `Authorization`
    header: `Authorization: Bearer YOUR_API_KEY`.
servers:
  - url: https://api.teamfollowup.ai
    description: Production API origin. Public API paths are under /api.
security: []
tags:
  - name: Agents
    description: >-
      Build the conversation: identity and settings, script, lead context and
      split testing.
  - name: Analytics
    description: >-
      Understand call volume, pickup, booking and transfer metrics within the
      selected reporting scope.
  - name: Billing
    description: >-
      Balances, spend, purchases and sub-account rebilling. Reference and guides
      only; the builder chatbot has no billing playbook.
  - name: Calls
    description: >-
      Review completed calls, recordings, transcripts and campaign run history;
      distinguish observation from placing a new call.
  - name: Campaigns
    description: >-
      Configure what starts calls, who is eligible, calling windows, caller IDs,
      activation and the actions that follow each outcome.


      What runs after a call lands: for each outcome (booked, opted out, asked
      for a callback…), an ordered chain of actions — tag the contact, move a
      pipeline stage, send an SMS, book an appointment. Stored as a graph:
      `nodes` are the actions, `edges` say what follows what, and
      `dispositionEntries` maps each outcome to the node its chain starts at.


      **Pick the narrowest endpoint that does the job.**


      | To | Call | |

      | --- | --- | --- |

      | See what fires per outcome | `GET .../workflow?view=summary` | Reads as
      plain text, no graph walking |

      | Add steps to an outcome | `POST .../outcomes/{outcome}/nodes` | Server
      derives node ids, edge ids, handles, layout |

      | Change a message, tag or setting | `PATCH .../workflow` | Merges;
      carries no graph, so it cannot damage one |

      | Remove one step | `DELETE .../nodes/{nodeId}` | Also re-links the chain
      around it |

      | Author or replace the whole graph | `PUT .../workflow` | Replaces
      everything you send |


      `PUT` is the only one that can re-wire, position nodes, build an `if`,
      save an unconfigured draft, or copy a whole workflow — and the only one
      that can overwrite a change someone else made after you read it. Use it
      when you are genuinely authoring the graph, and send `expectedVersion`
      when you do. For everything else the narrower endpoints are both easier
      and safer.
  - name: Contacts
    description: >-
      Find contacts and their calls, manage do-not-call status and identify
      internal contacts excluded from reporting.
  - name: In-call Capabilities
    description: >-
      Configure actions and instructions the agent uses during a live call:
      booking, transfers, lookups and custom skills.
  - name: Master agent
    description: >-
      Run a shared agent and campaign across linked projects; manage
      inheritance, local bindings, synchronization and rollout readiness.
  - name: Native Calendar
    description: >-
      The diary of a sub-account with no CRM: its bookable calendars, the free
      slots they offer, and the appointments on them. Availability is computed
      per request against live bookings and is never cached, because a cached
      slot is one somebody else has already taken.
  - name: Native Contacts
    description: >-
      The people a sub-account with no CRM calls, and the fields it keeps on
      them. This is the system of record for those contacts: there is nowhere
      else they exist. A sub-account with a CRM keeps its contacts there and
      every operation here answers 400 for it.
  - name: Phone Numbers
    description: >-
      Find and manage caller IDs, assign numbers to campaigns and understand
      connected Twilio numbers.
  - name: Projects
    description: >-
      Understand project ownership, inspect configuration and validate the local
      resources used by a campaign.
  - name: TFU Live
    description: >-
      Build one TFU Live agent with its Brain, Voice and equipped actions;
      connect it through shared Campaigns.
  - name: Voices
    description: >-
      Browse the voice catalogue and select a voice; configure speech and
      listening behavior in Agents.
paths:
  /api/tfu-live-agents/{id}/resources/{kind}:
    get:
      tags:
        - TFU Live
      summary: Look up TFU Live resources
      description: >-
        TFU Live only. What a workflow’s settings may name in this sub-account:
        calendars (Find slots, Cancel appointment), tags (tag nodes),
        custom_fields (contact.custom.<id>), pipelines and their stages (Move
        stage), reps and teams (Transfer). The same lookups a save verifies
        against. status unavailable means the lookup could not run, never that
        there are none.


        Required scope: `agents:read`.


        Required API key scope: `agents:read`.
      operationId: get-tfu-live-agents-by-id-resources-by-kind
      parameters:
        - name: locationId
          in: query
          required: true
          schema:
            type: string
          description: >-
            Sub-account belonging to the authenticated agency and any narrower
            credential location binding.
        - name: id
          in: path
          required: true
          schema:
            type: string
          description: TFU Live agent id. Never use an ordinary provider agent id.
        - name: kind
          in: path
          required: true
          schema:
            type: string
            enum:
              - calendars
              - tags
              - custom_fields
              - pipelines
              - reps
              - teams
          description: What to look up.
        - name: query
          in: query
          schema:
            type: string
            maxLength: 200
          description: A name to search for, or an exact id.
      responses:
        '200':
          description: >-
            Successful TFU Live response. Setup acceptance is not verified
            readiness or campaign activation.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveLookupResponse'
              example:
                success: true
                data:
                  kind: calendars
                  status: available
                  items:
                    - id: cal_consult01
                      name: Consultations
                      calendarType: round_robin
                      isActive: true
                      source: gohighlevel
                  hasMore: false
                  totalMatches: 1
                  sources:
                    gohighlevel:
                      status: available
        '400':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              example:
                success: false
                error: locationId is required.
                code: invalid_request
        '401':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              example:
                success: false
                error: Unauthorized
                message: Access token is required. Please login
        '403':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              example:
                success: false
                error: InsufficientScope
                message: This API key does not have the required scope.
                requiredScope: agents:write
        '404':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              example:
                success: false
                error: Agent not found.
                code: not_found
        '409':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              example:
                success: false
                error: The agent changed. Read the current version before saving.
                code: conflict
        '422':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              examples:
                invalid_workflow:
                  value:
                    success: false
                    error: Choose the tag this node checks.
                    code: invalid_workflow
                    workflowId: wf_account1
                    stepId: check
                workflow_resource_not_found:
                  value:
                    success: false
                    error: Choose an active calendar verified for this sub-account.
                    code: workflow_resource_not_found
                    workflowId: wf_book0001
                    stepId: slots
                    field: routing[1].calendarId
                workflow_secret_refused:
                  value:
                    success: false
                    error: >-
                      The saved value of the Authorization header was saved for
                      https://api.example.com; this webhook now sends to
                      https://collector.example.net, so enter the value again.
                    code: workflow_secret_refused
                    workflowId: wf_account1
                    stepId: lookup
                    field: headers.Authorization
                invalid_agent:
                  value:
                    success: false
                    error: >-
                      Choose an agent id using up to 100 letters, digits,
                      underscores or hyphens.
                    code: invalid_agent
                setup_incomplete:
                  value:
                    success: false
                    error: >-
                      Fill what this agent still needs before it is set up: Book
                      appointment: Choose the calendar to search.
                    code: setup_incomplete
                    workflowId: wf_book0001
                    stepId: slots
                    field: calendarId
                    setupItems:
                      - kind: workflow_setting
                        workflowId: wf_book0001
                        workflowName: Book appointment
                        stepId: slots
                        node: find_slots
                        field: calendarId
                        message: Choose the calendar to search.
        '429':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              example:
                success: false
                error: TooManyRequests
                message: Too many write requests, please slow down.
        '502':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              example:
                success: false
                error: TFU Live request failed.
                code: provider_unavailable
        '503':
          description: >-
            TFU Live request rejected: { success: false, error, code,
            workflowId?, stepId?, field?, setupItems? }. Read the error and
            current agent before retrying.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TfuLiveError'
              example:
                success: false
                error: TFU_LIVE_CAMPAIGN_PENDING
                code: TFU_LIVE_CAMPAIGN_PENDING
                message: >-
                  The agent draft was saved. Retry creation with the same agent
                  id and original body to finish attaching its campaign.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request GET \
              --url https://api.teamfollowup.ai/api/tfu-live-agents/{id}/resources/{kind} \
              --header 'Authorization: Bearer YOUR_API_KEY'
components:
  schemas:
    TfuLiveLookupResponse:
      type: object
      required:
        - success
        - data
      properties:
        success:
          const: true
        data:
          type: object
          required:
            - kind
            - status
            - items
          additionalProperties: false
          properties:
            kind:
              type: string
              enum:
                - calendars
                - tags
                - custom_fields
                - pipelines
                - reps
                - teams
            status:
              type: string
              enum:
                - available
                - unavailable
              description: >-
                unavailable: the lookup could not run. It is unknown, never an
                empty list.
            items:
              type: array
              items:
                type: object
                additionalProperties: {}
              description: >-
                calendars { id, name, calendarType, isActive, source: native |
                gohighlevel }; tags { id, name }; custom_fields { id, name,
                fieldKey, dataType, picklistOptions?, model? }; pipelines { id,
                name, stages: [{ id, name, position }] }; reps { id, name,
                phone, status, teamId, timezone }; teams { id, name, memberCount
                }.
            hasMore:
              type: boolean
              description: 'More than 200 matched: narrow the search.'
            totalMatches:
              type: integer
            reason:
              type: string
            message:
              type: string
            sources:
              type: object
              description: >-
                calendars only: each source read. A native sub-account lists its
                native calendars (and GoHighLevel ones only when it holds a
                GoHighLevel connection); a GoHighLevel sub-account lists
                GoHighLevel calendars only, since a real call there cannot book
                on a native one. A source that could not be read is unavailable
                on its own and the others are still listed; status is
                unavailable only when none could be read.
              additionalProperties:
                type: object
                required:
                  - status
                additionalProperties: false
                properties:
                  status:
                    type: string
                    enum:
                      - available
                      - unavailable
                  reason:
                    type: string
            note:
              type: string
              description: >-
                calendars only: which source is missing from the list, and that
                native calendars work in roleplay but cannot book a real call
                yet.
      additionalProperties: false
    TfuLiveError:
      type: object
      required:
        - success
        - error
      properties:
        success:
          const: false
        error:
          type: string
          description: >-
            What to do about it, in words. A status-wide gate (authentication,
            scope, rate limit) may use its own error name with a message.
        code:
          type: string
          enum:
            - invalid_workflow
            - setup_incomplete
            - workflow_resource_not_found
            - workflow_resource_unavailable
            - workflow_secret_refused
            - invalid_agent
            - invalid_request
            - unauthorized
            - insufficient_balance
            - forbidden
            - not_found
            - conflict
            - too_large
            - provider_unavailable
            - internal_error
            - AGENT_OPERATION_UNSUPPORTED
            - TFU_LIVE_CAMPAIGN_PENDING
          description: >-
            The kind of refusal: invalid_workflow (a workflow’s structure or a
            node’s settings), setup_incomplete (a setting still to fill or a
            Brain template placeholder still in the prompt, where the agent must
            be complete: preparing it, or a save that sets it up; setupItems
            lists every one), workflow_resource_not_found (a calendar, custom
            field, pipeline stage, team or rep the sub-account lacks, or an
            inactive calendar), workflow_resource_unavailable (503: the
            sub-account’s resources could not be read; retry),
            workflow_secret_refused (a secret header rule), invalid_agent (any
            other part of the agent), else by status. TFU_LIVE_* names a product
            state.
        workflowId:
          type: string
          description: >-
            The workflow a workflow refusal is about. Absent on a workflow being
            created, which has no id yet.
        stepId:
          type: string
          description: The step inside it.
        field:
          type: string
          description: >-
            The setting inside the step: calendarId, routing[1].calendarId,
            items[0].field, destination.teamId, headers.Authorization;
            brain.prompt for a placeholder. On a create from a Brain template,
            the request value: values.<to-fill id>, values or brainTemplateId.
        setupItems:
          type: array
          items:
            type: object
            required:
              - kind
              - message
            additionalProperties: false
            description: >-
              Something the agent still needs before it can be prepared for real
              calls.
            properties:
              kind:
                type: string
                enum:
                  - workflow_setting
                  - prompt_placeholder
                description: >-
                  workflow_setting: a setting still to fill (a calendar, a tag,
                  who takes a transfer, zip codes, a choice’s answers, an item’s
                  label); prompt_placeholder: a Brain template [bracketed]
                  placeholder still in the prompt (legacy: templates no longer
                  hold any).
              workflowId:
                type: string
              workflowName:
                type: string
              stepId:
                type: string
              node:
                type: string
                description: The node type.
              field:
                type: string
                description: >-
                  The setting inside the step (calendarId, destination,
                  items[0].choices), or brain.prompt.
              placeholder:
                type: string
              message:
                type: string
                description: What to do, in words.
          description: >-
            On setup_incomplete: everything the agent still needs, the first of
            which the refusal names.
      additionalProperties: {}
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Send your API key as `Authorization: Bearer YOUR_API_KEY`.'

````