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

# List Signal Imports

> List what the workspace's signals brought in, most recent fact first.

An entry records which signal fired, who or which company it was about,
and whether it was imported, was already in the list, or was filtered out.

Requires the `signals:read` scope on the API key.



## OpenAPI

````yaml /openapi.json get /v1/signals/imports
openapi: 3.1.0
info:
  title: Topo Public API
  description: >-
    Public REST API for Topo. All requests require a bearer API key issued from
    Settings → Developers. See the **Guides** in the left sidebar for
    authentication and rate-limit details.
  version: 1.0.0
servers:
  - url: https://api.topo.io
    description: Production
security:
  - BearerApiKey: []
tags:
  - name: Authentication
    description: >-
      Every request to the Topo Public API is authenticated with a bearer API
      key.


      ```http

      Authorization: Bearer topo_live_4f8a9c2b...

      ```


      Requests without a valid bearer token receive `401 Unauthorized`. After
      repeated failures with the same token, further attempts are
      short-circuited with `429 Too Many Requests` (`data.window_seconds: 60`)
      so a stale or malformed key cannot be retried in a tight loop.


      ### Issuing keys


      API keys are issued from the dashboard under **Settings → Developers → API
      keys**. Each key is bound to a single organization — the workspace it was
      created in — and cannot be used to read or write data from any other
      organization.


      The raw key is shown **once** at creation and never displayed again. If
      the raw key is lost, revoke it and issue a new one.


      ### Scopes


      Keys carry a granular scope list of `resource:action` pairs. A request to
      an endpoint whose required scope is not on the key returns `403
      Forbidden`.


      v1 ships with the following scopes:


      - `account_exclusions:read`, `account_exclusions:write`

      - `account_lists:read`, `account_lists:write`

      - `accounts:read`, `accounts:write`

      - `activities:read`

      - `contact_exclusions:read`, `contact_exclusions:write`

      - `contact_lists:read`, `contact_lists:write`

      - `contacts:read`, `contacts:write`

      - `crm:write`

      - `events:read`, `events:write`

      - `messages:read`

      - `sequences:read`, `sequences:write`

      - `signals:read`, `signals:write`

      - `tasks:read`, `tasks:write`

      - `users:read`

      - `webhooks:read`, `webhooks:write`


      Each endpoint's required scope is listed in its description.


      ### Inspecting the current key


      `GET /v1/me` returns the principal behind the bearer token: the key id,
      its name, the organization id and name, the id of the user who issued the
      key (`null` when it was not issued by a person), the scope list, the key
      prefix, the last-used timestamp, and the creation date. Use it to confirm
      a key is wired up correctly before debugging endpoint-level errors.
  - name: Rate limits
    description: >-
      Requests are rate-limited per organization across three concurrent
      windows. The budget is shared by every API key issued for the
      organization.


      | Window | Default limit |

      |---|---|

      | Per second | 10 requests |

      | Per minute | 60 requests |

      | Per day | 10,000 requests |


      A request is accepted only if it fits inside **all three** windows.
      Exceeding any one of them returns `429`.


      ### Response headers


      Every response carries the state of all three windows. Each window is
      suffixed with its name — `second`, `minute`, or `day`:


      ```http

      X-RateLimit-Limit-second: 5

      X-RateLimit-Remaining-second: 2

      X-RateLimit-Reset-second: 1729435920

      X-RateLimit-Limit-minute: 60

      X-RateLimit-Remaining-minute: 13

      X-RateLimit-Reset-minute: 1729435932

      X-RateLimit-Limit-day: 1000

      X-RateLimit-Remaining-day: 842

      X-RateLimit-Reset-day: 1729519200

      ```


      | Header | Meaning |

      |---|---|

      | `X-RateLimit-Limit-{window}` | Capacity of that window |

      | `X-RateLimit-Remaining-{window}` | Requests left in that window before
      the next `429` |

      | `X-RateLimit-Reset-{window}` | Unix timestamp (seconds) at which that
      window is fully refilled |


      Each window is a token bucket that refills continuously, so
      `X-RateLimit-Remaining-{window}` recovers gradually under steady traffic —
      it does not snap back at a fixed boundary.


      ### When the limit is exceeded


      Requests over the budget return `429` with the standard error envelope and
      a `Retry-After` header. `data.window_seconds` identifies the tier that
      tripped (`1`, `60`, or `86400`):


      ```http

      Retry-After: 3

      ```


      ```json

      {
        "status_code": 429,
        "type": "RateLimitIssue",
        "message": "Rate limit exceeded",
        "data": {
          "limit": 60,
          "reset_at": 1729435932,
          "window_seconds": 60
        },
        "request_id": "req_01HX7K..."
      }

      ```


      `Retry-After` is the number of seconds until the next request is allowed
      and is the recommended signal for backoff. `X-RateLimit-Reset` marks when
      the window is fully refilled, which is later than `Retry-After` whenever
      the bucket has more than one slot.
  - name: Task lifecycle
    description: >-
      A task represents one action a rep is expected to take — reply to a
      message, review a new lead, make a call, or complete a standalone to-do.
      This guide covers the states a task moves through, and how the wording
      used in the Topo app maps onto the values returned by this API.


      ### Statuses


      | `status` | Meaning |

      |---|---|

      | `PENDING` | Waiting for the rep. This is where a task starts. |

      | `IN_PROGRESS` | A call task the rep has started but not yet logged. |

      | `COMPLETED` | The rep acted on the task — a reply was sent, a lead
      approved or refused, a call logged. |

      | `SKIPPED` | The rep dismissed the task without acting on it. Shown as
      **Archived** in the app. |


      `PENDING` and `IN_PROGRESS` are the actionable states. `COMPLETED` and
      `SKIPPED` are terminal, but both can be reversed with `POST
      /v1/tasks/{task_id}/reopen`.


      ### App wording vs. API wording


      The Topo app calls the dismiss action **Archive**. On this API the same
      operation is called *skip*. They are the same thing — only the label
      differs:


      | In the Topo app | On this API |

      |---|---|

      | The **Archive** button | `POST /v1/tasks/{task_id}/skip` |

      | The **Archived** badge | `status: "SKIPPED"` |

      | "Archived 2 hours ago" | `skipped_at` |

      | — | webhook event `task.skipped` |


      These names are part of the frozen `/v1` contract and will not change
      within this major version. If you are mapping API data back to what a user
      sees in the app, treat `SKIPPED` and `skipped_at` as "archived".


      ### Ending a task


      | Action | Endpoint | Result |

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

      | Act on it | `POST /v1/tasks/{task_id}/execute` | `COMPLETED` +
      `completed_at`, and the task's own side effects (message sent, lead
      enrolled or refused, call logged) |

      | Mark done without acting | `POST /v1/tasks/{task_id}/complete` |
      `COMPLETED` + `completed_at` |

      | Dismiss it (archive) | `POST /v1/tasks/{task_id}/skip` | `SKIPPED` +
      `skipped_at` |


      `execute` is the only one of the three that changes anything beyond the
      task itself. `complete` and `skip` record an outcome and nothing more.


      Both terminal states emit a webhook if you are subscribed:
      `task.completed` and `task.skipped` respectively.


      ### Reopening


      `POST /v1/tasks/{task_id}/reopen` returns a `COMPLETED` or `SKIPPED` task
      to `PENDING`. It clears `completed_at` and `skipped_at`, and sets
      `reopened_at`. A task that is already actionable cannot be reopened.


      `reopen_reason` distinguishes an automatic reopen from a manual one.
      `REMINDER_RULE` means Topo brought the task back on its own because a sent
      message went unanswered; `null` means a person reopened it.


      ### Snoozing


      Deferring a task ("Snooze") does **not** change its status. The task stays
      `PENDING` and drops out of the active queue until the chosen time passes,
      then reappears on its own.


      Use `POST /v1/tasks/{task_id}/snooze` with `{ "snoozed_until": "<ISO-8601
      timestamp>" }` to defer a task. The `snoozed_until` timestamp is also
      returned on task objects in `GET /v1/tasks` and `GET /v1/tasks/{task_id}`.
  - name: me
    description: >-
      Identity of the API key in use: the workspace it belongs to and its
      scopes.
  - name: search
    description: >-
      Find records by name across kinds and load any match back. A search result
      carries a typed id (`<type>:<uuid>`) that `GET /v1/fetch` resolves into
      the full record, so a name is enough to reach a lead, an account, a
      sequence template or a task without knowing which endpoint owns it.
  - name: users
    description: List users in the authenticated organization.
  - name: contacts
    description: Manage contact lists, list entries, and contact-level exclusions.
  - name: accounts
    description: Manage account lists, list entries, and account-level exclusions.
  - name: sequences
    description: Manage outbound sequences and inspect their execution state.
  - name: sequence-templates
    description: Manage reusable sequence templates that seed new sequences.
  - name: activities
    description: >-
      Read the immutable event log produced by outbound sequences (sent, opened,
      replied, meeting booked, etc.).
  - name: events
    description: >-
      Ingest first-party events (product usage, website activity, form
      submissions) and read them back to verify ingestion and resolution. Every
      well-formed event is accepted (HTTP 202) and stored. Subject correlation
      to contacts and accounts is asynchronous and best-effort. Replays with the
      same `external_event_id` or identical event content are deduplicated.
  - name: signals
    description: >-
      Create and run buying signals: a signal watches one catalog preset
      (hiring, funding, technology adoption, news, LinkedIn activity, or your
      own first-party events), checks it daily, and imports the qualified people
      or companies into a destination list it creates. Read the imports feed to
      see what each signal brought in.
  - name: webhooks
    description: Manage webhook subscriptions to receive outbound event notifications.
  - name: tasks
    description: List and inspect tasks in the workspace.
  - name: messages
    description: Read email and LinkedIn messages exchanged in outreach sequences.
paths:
  /v1/signals/imports:
    get:
      tags:
        - signals
      summary: List Signal Imports
      description: >-
        List what the workspace's signals brought in, most recent fact first.


        An entry records which signal fired, who or which company it was about,

        and whether it was imported, was already in the list, or was filtered
        out.


        Requires the `signals:read` scope on the API key.
      operationId: list_signal_imports_v1_signals_imports_get
      parameters:
        - name: page
          in: query
          required: false
          schema:
            type: integer
            minimum: 1
            default: 1
            title: Page
        - name: size
          in: query
          required: false
          schema:
            type: integer
            maximum: 100
            minimum: 1
            default: 10
            title: Size
        - name: signal_id
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                format: uuid
              - type: 'null'
            description: Return only what this signal brought in.
            title: Signal Id
          description: Return only what this signal brought in.
        - name: signal_type
          in: query
          required: false
          schema:
            anyOf:
              - $ref: '#/components/schemas/SignalType'
              - type: 'null'
            description: Return only entries from signals of this preset.
            title: Signal Type
          description: Return only entries from signals of this preset.
        - name: kind
          in: query
          required: false
          schema:
            anyOf:
              - $ref: '#/components/schemas/SignalImportKind'
              - type: 'null'
            description: Return only people or only companies.
            title: Kind
          description: Return only people or only companies.
        - name: status
          in: query
          required: false
          schema:
            anyOf:
              - $ref: '#/components/schemas/SignalImportStatus'
              - type: 'null'
            description: Return only entries that ended in this state.
            title: Status
          description: Return only entries that ended in this state.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/PublicPaginationEnvelope_SignalImportPublicOutput_
components:
  schemas:
    SignalType:
      type: string
      enum:
        - LINKEDIN_OWN_POST_ENGAGEMENT
        - LINKEDIN_COMPETITOR_POST_ENGAGEMENT
        - LINKEDIN_PERSON_POST_ENGAGEMENT
        - LINKEDIN_KEYWORD_MENTION
        - LINKEDIN_OWN_COMPANY_FOLLOWERS
        - LINKEDIN_COMPETITOR_FOLLOWERS
        - LINKEDIN_COMPANY_PAGE_FOLLOWERS
        - HIRING_SIGNALS
        - JOB_DESCRIPTION_KEYWORD
        - FUNDING_EVENTS
        - TECH_ADOPTION
        - NEWS_EVENTS
        - NEW_JOB
        - CUSTOM_EVENT
        - LINKEDIN_PARTNER_FOLLOWERS
        - LINKEDIN_CUSTOMER_FOLLOWERS
        - LINKEDIN_PARTNER_POST_ENGAGEMENT
        - LINKEDIN_CUSTOMER_POST_ENGAGEMENT
        - LINKEDIN_COMPANY_PAGE_POST_ENGAGEMENT
        - LINKEDIN_OWN_PROFILE_POST_ENGAGEMENT
        - LINKEDIN_OWN_EMPLOYEES_POST_ENGAGEMENT
        - LINKEDIN_COMPETITOR_EMPLOYEES_POST_ENGAGEMENT
        - LINKEDIN_PARTNER_EMPLOYEES_POST_ENGAGEMENT
        - LINKEDIN_CUSTOMER_EMPLOYEES_POST_ENGAGEMENT
        - LINKEDIN_OWN_BRAND_MENTION
        - LINKEDIN_COMPETITOR_MENTION
        - LINKEDIN_PARTNER_MENTION
        - LINKEDIN_CUSTOMER_MENTION
        - LINKEDIN_EVENT_MENTION
        - COMPETITOR_TECH_ADOPTION
        - INTEGRATION_TECH_ADOPTION
        - LINKEDIN_EVENT_PAGE_FOLLOWERS
        - CHAMPION_CHANGED_JOB
        - CRM_LIST_ENTRY
      title: SignalType
    SignalImportKind:
      type: string
      enum:
        - CONTACT
        - ACCOUNT
      title: SignalImportKind
    SignalImportStatus:
      type: string
      enum:
        - FOUND
        - IMPORTED
        - ALREADY_IN_LIST
        - EXPIRED
        - REJECTED
      title: SignalImportStatus
      description: |-
        Display status for a signal occurrence — collapses the DB-level
        `SignalStatus`/`SignalSkipReason` pair into the states the product
        surfaces. ALREADY_IN_LIST and EXPIRED are kept out of REJECTED so
        neither an ordinary duplicate nor a fact that simply aged out reads as
        a qualification failure.
    PublicPaginationEnvelope_SignalImportPublicOutput_:
      properties:
        items:
          items:
            $ref: '#/components/schemas/SignalImportPublicOutput'
          type: array
          title: Items
          description: Records on this page.
        total_count:
          type: integer
          title: Total Count
          description: Total number of records matching the query.
        total_pages:
          type: integer
          title: Total Pages
          description: Total number of pages.
        has_more:
          type: boolean
          title: Has More
          description: Whether more pages remain after the current one.
      type: object
      required:
        - items
        - total_count
        - total_pages
        - has_more
      title: PublicPaginationEnvelope[SignalImportPublicOutput]
    SignalImportPublicOutput:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: Unique identifier of the imported entry.
        signal_id:
          type: string
          format: uuid
          title: Signal Id
          description: Signal that produced the entry.
        signal_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Signal Name
          description: Name of the signal that produced the entry.
        signal_type:
          $ref: '#/components/schemas/SignalType'
          description: Catalog preset behind the signal.
        kind:
          $ref: '#/components/schemas/SignalImportKind'
          description: Whether the entry is a person or a company.
        status:
          $ref: '#/components/schemas/SignalImportStatus'
          description: >-
            FOUND is detected but not processed yet, IMPORTED landed in the
            destination list, ALREADY_IN_LIST was a duplicate, REJECTED was
            filtered out.
        skip_detail:
          anyOf:
            - type: string
            - type: 'null'
          title: Skip Detail
          description: Why the entry was rejected, when it was.
        failed_filters:
          anyOf:
            - items:
                type: string
              type: array
            - type: 'null'
          title: Failed Filters
          description: >-
            Filter field names that rejected the entry, when skip_detail is
            FILTERS_NOT_MATCHED.
        occurred_at:
          type: string
          format: date-time
          title: Occurred At
          description: When the underlying fact happened at the source.
        processed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Processed At
          description: When the signal decided what to do with the entry.
        contact_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Contact Id
          description: The imported lead, once it exists in the workspace.
        account_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Account Id
          description: The imported account, once it exists in the workspace.
        first_name:
          anyOf:
            - type: string
            - type: 'null'
          title: First Name
          description: First name of the person.
        last_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Last Name
          description: Last name of the person.
        job_title:
          anyOf:
            - type: string
            - type: 'null'
          title: Job Title
          description: Job title of the person.
        email:
          anyOf:
            - type: string
            - type: 'null'
          title: Email
          description: Email of the person.
        linkedin_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Linkedin Url
          description: LinkedIn profile of the person.
        company_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Company Name
          description: Company the person works at.
        company_domain:
          anyOf:
            - type: string
            - type: 'null'
          title: Company Domain
          description: Domain of the company the person works at.
        account_name:
          anyOf:
            - type: string
            - type: 'null'
          title: Account Name
          description: Name of the detected company.
        account_domain:
          anyOf:
            - type: string
            - type: 'null'
          title: Account Domain
          description: Domain of the detected company.
      type: object
      required:
        - id
        - signal_id
        - signal_name
        - signal_type
        - kind
        - status
        - skip_detail
        - failed_filters
        - occurred_at
        - processed_at
        - contact_id
        - account_id
        - first_name
        - last_name
        - job_title
        - email
        - linkedin_url
        - company_name
        - company_domain
        - account_name
        - account_domain
      title: SignalImportPublicOutput
  securitySchemes:
    BearerApiKey:
      type: http
      scheme: bearer
      bearerFormat: topo_live_<64hex>
      description: Bearer API key issued from Settings → Developers.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.