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

# List ICP signals

> Signals detected on companies matching your watched ICPs — including companies that are not in your Key Accounts and that you have never unlocked.

**To poll:** call with no cursor, process the events, save `next_cursor`, and pass it back next time to get whatever has been detected since. `next_cursor` comes back on every non-empty page, including the last one; `has_more: false` means you are caught up, not that the feed has ended.

**Delivery is at-least-once.** Each event carries a stable `id`; store the ids you have processed and skip repeats rather than assuming an event arrives exactly once.

Events are ordered by when they were detected, oldest first. Note that is not the same as when they happened: news commonly surfaces days after the fact, so `occurred_at` can move backwards from one event to the next while `detected_at` never does.



## OpenAPI

````yaml /reference/openapi.yaml get /v2/icp-signals
openapi: 3.1.0
info:
  title: Tamtam Public API
  version: 2.0.0
servers:
  - url: https://api.tamtam.ai/api
security: []
paths:
  /v2/icp-signals:
    get:
      tags:
        - ICP Signal Watches
      summary: List ICP signals
      description: >-
        Signals detected on companies matching your watched ICPs — including
        companies that are not in your Key Accounts and that you have never
        unlocked.


        **To poll:** call with no cursor, process the events, save
        `next_cursor`, and pass it back next time to get whatever has been
        detected since. `next_cursor` comes back on every non-empty page,
        including the last one; `has_more: false` means you are caught up, not
        that the feed has ended.


        **Delivery is at-least-once.** Each event carries a stable `id`; store
        the ids you have processed and skip repeats rather than assuming an
        event arrives exactly once.


        Events are ordered by when they were detected, oldest first. Note that
        is not the same as when they happened: news commonly surfaces days after
        the fact, so `occurred_at` can move backwards from one event to the next
        while `detected_at` never does.
      operationId: list-icp-signals
      parameters:
        - description: >-
            Target account UUID. Required for staff callers; ignored for
            customer API keys (they always read their own account).
          explode: false
          in: query
          name: account_id
          schema:
            description: >-
              Target account UUID. Required for staff callers; ignored for
              customer API keys (they always read their own account).
            type: string
        - description: >-
            Only return events detected for this ICP. Omit for every watched ICP
            on the account.
          explode: false
          in: query
          name: icp_criteria_id
          schema:
            description: >-
              Only return events detected for this ICP. Omit for every watched
              ICP on the account.
            type: string
        - description: >-
            Repeatable. Only return these signal types (news, job_posting). Omit
            for all of them.
          explode: false
          in: query
          name: signal_type
          schema:
            description: >-
              Repeatable. Only return these signal types (news, job_posting).
              Omit for all of them.
            items:
              type: string
            type:
              - array
              - 'null'
        - description: >-
            Only return events detected at or after this RFC3339 timestamp.
            Prefer the cursor for sequential polling: since re-reads a window,
            the cursor advances through it.
          explode: false
          in: query
          name: since
          schema:
            description: >-
              Only return events detected at or after this RFC3339 timestamp.
              Prefer the cursor for sequential polling: since re-reads a window,
              the cursor advances through it.
            examples:
              - '2026-08-01T00:00:00Z'
            format: date-time
            type: string
        - description: >-
            Pagination cursor from a previous call. Save next_cursor and pass it
            back unchanged to fetch what has arrived since. Cursors stay valid
            indefinitely unless this endpoint returns a 400.
          explode: false
          in: query
          name: cursor
          schema:
            description: >-
              Pagination cursor from a previous call. Save next_cursor and pass
              it back unchanged to fetch what has arrived since. Cursors stay
              valid indefinitely unless this endpoint returns a 400.
            type: string
        - description: Maximum events to return.
          explode: false
          in: query
          name: limit
          schema:
            default: 100
            description: Maximum events to return.
            format: int32
            maximum: 500
            minimum: 1
            type: integer
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListIcpSignalsResponseDto'
          description: OK
        default:
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ErrorModel'
          description: Error
      security:
        - apikeyAuth: []
        - bearerAuth: []
components:
  schemas:
    ListIcpSignalsResponseDto:
      additionalProperties: false
      properties:
        events:
          description: >-
            Events in detection order, oldest first, so a consumer can walk
            forward without new arrivals reshuffling the page.
          items:
            $ref: '#/components/schemas/IcpSignalEventDto'
          type:
            - array
            - 'null'
        has_more:
          description: >-
            True when more events are already waiting. False means you are
            caught up, not that the feed is finished.
          type: boolean
        next_cursor:
          description: >-
            Pass back unchanged to fetch events detected after this page.
            Returned on every non-empty page, including the last: a feed has no
            end, only a current position.
          type: string
      required:
        - events
        - has_more
      type: object
    ErrorModel:
      additionalProperties: false
      properties:
        detail:
          description: >-
            A human-readable explanation specific to this occurrence of the
            problem.
          examples:
            - Property foo is required but is missing.
          type: string
        errors:
          description: Optional list of individual error details
          items:
            $ref: '#/components/schemas/ErrorDetail'
          type:
            - array
            - 'null'
        instance:
          description: >-
            A URI reference that identifies the specific occurrence of the
            problem.
          examples:
            - https://example.com/error-log/abc123
          format: uri
          type: string
        status:
          description: HTTP status code
          examples:
            - 400
          format: int64
          type: integer
        title:
          description: >-
            A short, human-readable summary of the problem type. This value
            should not change between occurrences of the error.
          examples:
            - Bad Request
          type: string
        type:
          default: about:blank
          description: A URI reference to human-readable documentation for the error.
          examples:
            - https://example.com/errors/example
          format: uri
          type: string
      type: object
    IcpSignalEventDto:
      additionalProperties: false
      properties:
        company_linkedin_id:
          description: >-
            LinkedIn numeric company ID of the company the signal fired on. Pass
            it to the company endpoints to read more.
          examples:
            - '104924588'
          type: string
        detected_at:
          description: >-
            When we found it. Lags occurred_at by days for news, and is the
            order this feed is paginated in.
          examples:
            - '2026-08-11T09:14:22Z'
          format: date-time
          type: string
        headline:
          description: One-line statement of what happened.
          examples:
            - Target Co was acquired by Acquirer SA
          type: string
        icp_criteria_id:
          description: The watched ICP this event was detected for.
          type: string
        icp_fit:
          additionalProperties: {}
          description: >-
            Which of the ICP's criteria matched at detection time, snapshotted
            so the answer survives later edits to the ICP.


            Covers the whole ICP, including criteria backed by research
            questions. A company we had not researched yet is held back rather
            than reported unverified, so its first signal can arrive a cycle
            later than the article did.
          type: object
        id:
          description: >-
            Stable event id. This feed is at-least-once: store processed ids and
            skip repeats rather than assuming each event arrives exactly once.
          examples:
            - 9b7d5f2e-1c3a-4f8b-9e6d-2a1b3c4d5e6f
          type: string
        occurred_at:
          description: >-
            When the event happened in the world. For news this is the
            publication date, which carries day precision only.
          examples:
            - '2026-08-10T00:00:00Z'
          format: date-time
          type: string
        payload:
          additionalProperties: {}
          description: >-
            Signal-specific detail. For news: topic, article_url, article_title,
            snippet, country_code, company_name.
          type: object
        signal_type:
          description: 'Kind of signal. One of: news, job_posting.'
          examples:
            - news
          type: string
        source_ref_id:
          description: >-
            Id of the underlying record (e.g. the news article) when one was
            stored. Absent when the source could not be ingested.
          type: string
      required:
        - id
        - icp_criteria_id
        - signal_type
        - company_linkedin_id
        - headline
        - occurred_at
        - detected_at
        - payload
      type: object
    ErrorDetail:
      additionalProperties: false
      properties:
        location:
          description: >-
            Where the error occurred, e.g. 'body.items[3].tags' or
            'path.thing-id'
          type: string
        message:
          description: Error message text
          type: string
        value:
          description: The value at the given location
      type: object
  securitySchemes:
    apikeyAuth:
      description: Account API key passed in the Authorization header
      in: header
      name: Authorization
      type: apiKey
    bearerAuth:
      description: Bearer JWT obtained via the OAuth 2.1 authorization flow
      scheme: bearer
      type: http

````