> ## 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, calls, campaigns, contacts, phone numbers, billing, and configuration.

# Clear contact internal mark

> Authentication required. Intended for customer-facing agency administrators and project users. Results and actions are tenant-scoped to projects visible to the caller.

Clears the internal mark, putting the contact's calls back into the dashboard figures. Applies retroactively to the whole call history, not only to calls from here on.

Cookie-auth callers must send the `x-csrf-token` header.

Required API key scope: `contacts:write`.



## OpenAPI

````yaml /openapi.yaml delete /api/contacts/internal
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.
  - url: https://devapi.teamfollowup.ai
    description: Development API origin. Public API paths are under /api.
security: []
tags:
  - name: Agents
    description: Manage voice agents, campaigns, workflows, and outcomes.
  - name: Analytics
    description: >-
      Minimal, non-billing performance summary: volume, conversion, and pickup
      metrics.
  - name: Calls
    description: Review calls, test runs, and execution history.
  - name: Campaign Workflows
    description: >-
      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/digest` | 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: Contact list, filters, contact call history, and do-not-call actions.
  - name: GHL
    description: CRM variables and contact helpers used by agent and campaign setup flows.
  - name: Phone Numbers
    description: >-
      Caller ID pool, number search, assignment, movement, and release
      endpoints.
  - name: Power Dialer
    description: >-
      Power Dialer queue, lead cadence, callback, parked lead, and campaign
      schedule endpoints.
  - name: Projects
    description: >-
      Project management endpoints: list, update, disconnect, configure project
      campaigns, and validate setup.
  - name: Skills and Tools
    description: Manage reusable agent behaviors and in-call tool descriptions.
  - name: Voices
    description: Voice catalogue endpoints for choosing the voice used by an agent.
paths:
  /api/contacts/internal:
    delete:
      tags:
        - Contacts
      summary: Clear contact internal mark
      description: >-
        Authentication required. Intended for customer-facing agency
        administrators and project users. Results and actions are tenant-scoped
        to projects visible to the caller.


        Clears the internal mark, putting the contact's calls back into the
        dashboard figures. Applies retroactively to the whole call history, not
        only to calls from here on.


        Cookie-auth callers must send the `x-csrf-token` header.


        Required API key scope: `contacts:write`.
      operationId: unmark-contact-internal
      requestBody:
        required: true
        description: The project, and the contact identified by id or phone number.
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ContactsInternalRequest'
            examples:
              default:
                value:
                  locationId: loc_abc123
                  contactId: contact_123
                  phoneNumber: '+15551234567'
      responses:
        '200':
          description: Internal mark cleared successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsInternalResponse'
              examples:
                default:
                  value:
                    success: true
                    data:
                      contactId: contact_123
                      phoneNumber: '+15551234567'
                      locationId: loc_abc123
                      projectName: Acme Clinic
                      isInternal: false
                      matched: 3
                      changed: true
        '400':
          description: Validation failed or the request is malformed.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: projectName is required
        '401':
          description: Missing or invalid authentication.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Unauthorized
        '403':
          description: Authenticated but not permitted to access the requested project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Access denied to this project
        '404':
          description: Project or contact action target not found.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Project not found or not configured for CRM integration
        '429':
          description: Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: TooManyRequests
        '500':
          description: Unexpected server error.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ContactsErrorResponse'
              examples:
                default:
                  value:
                    success: false
                    error: Unexpected server error.
      security:
        - ApiKeyAuth: []
      x-codeSamples:
        - lang: bash
          label: cURL
          source: |-
            curl --request DELETE \
              --url https://api.teamfollowup.ai/api/contacts/internal \
              --header 'Authorization: Bearer YOUR_API_KEY' \
              --header 'Content-Type: application/json' \
              --data '{
              "locationId": "loc_abc123",
              "contactId": "contact_123",
              "phoneNumber": "+15551234567"
            }'
components:
  schemas:
    ContactsInternalRequest:
      type: object
      additionalProperties: false
      required:
        - locationId
      description: >-
        Identify the contact by `contactId`, by `phoneNumber`, or by both. At
        least one is required. Around 2% of contacts carry no id and are
        reachable only by number.
      anyOf:
        - required:
            - contactId
        - required:
            - phoneNumber
      properties:
        locationId:
          type: string
          minLength: 1
          description: Stable project location id used to tenant-scope the contact action.
          example: loc_abc123
        projectName:
          type: string
          description: Optional display label. Never used as tenant identity.
          example: Acme Clinic
        contactId:
          type: string
          description: Stable contact id. Preferred when the contact has one.
          example: contact_123
        phoneNumber:
          type: string
          description: >-
            Contact phone number. Required when the contact has no id, and worth
            sending alongside one to reach records written before that id
            existed.
          example: '+15551234567'
    ContactsInternalResponse:
      type: object
      additionalProperties: false
      required:
        - success
        - data
      properties:
        success:
          type: boolean
        data:
          $ref: '#/components/schemas/ContactsInternalData'
    ContactsErrorResponse:
      type: object
      additionalProperties: {}
      required:
        - success
        - error
      properties:
        success:
          type: boolean
        error:
          type: string
          example: Access denied to this project
        code:
          type: string
          example: FORBIDDEN
        message:
          type: string
          example: Access denied to this project
    ContactsInternalData:
      type: object
      additionalProperties: false
      required:
        - locationId
        - isInternal
        - matched
        - changed
      properties:
        contactId:
          type:
            - string
            - 'null'
          description: Null when the contact was identified by phone number alone.
          example: contact_123
        phoneNumber:
          type:
            - string
            - 'null'
          example: '+15551234567'
        locationId:
          type: string
          example: loc_abc123
        projectName:
          type: string
          example: Acme Clinic
        isInternal:
          type: boolean
          description: The resulting internal state.
          example: true
        matched:
          type: integer
          description: Contact records the identity resolved to in this project.
          example: 3
        changed:
          type: boolean
          description: Whether this request altered any record.
          example: true
  securitySchemes:
    ApiKeyAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Send your API key as `Authorization: Bearer YOUR_API_KEY`.'

````