> ## 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.

# Archive Signal

> Retire a signal: it stops checking and importing, disappears from the
default listing, and cannot be resumed until it is unarchived. The
destination list and everything already imported are kept. Prefer
pausing when the signal should only stop for now.

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



## OpenAPI

````yaml /openapi.json post /v1/signals/{signal_id}/archive
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/{signal_id}/archive:
    post:
      tags:
        - signals
      summary: Archive Signal
      description: |-
        Retire a signal: it stops checking and importing, disappears from the
        default listing, and cannot be resumed until it is unarchived. The
        destination list and everything already imported are kept. Prefer
        pausing when the signal should only stop for now.

        Requires the `signals:write` scope on the API key.
      operationId: archive_signal_v1_signals__signal_id__archive_post
      parameters:
        - name: signal_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
            title: Signal Id
          description: ID of the signal.
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignalPublicOutput'
components:
  schemas:
    SignalPublicOutput:
      properties:
        id:
          type: string
          format: uuid
          title: Id
          description: Unique identifier of the signal.
        name:
          anyOf:
            - type: string
            - type: 'null'
          title: Name
          description: Name of the signal and of its destination list.
        signal_type:
          $ref: '#/components/schemas/SignalType'
          description: Catalog preset the signal watches.
        status:
          $ref: '#/components/schemas/SignalRunStatus'
          description: >-
            ACTIVE checks daily, PAUSED is held until resumed, ARCHIVED is
            retired and cannot be resumed.
        cadence:
          anyOf:
            - $ref: '#/components/schemas/RefillFrequency'
            - type: 'null'
          description: How often the signal checks its provider.
        max_per_run:
          anyOf:
            - type: integer
            - type: 'null'
          title: Max Per Run
          description: Daily ceiling on imported entries, when one was set.
        max_companies_per_run:
          anyOf:
            - type: integer
            - type: 'null'
          title: Max Companies Per Run
          description: Daily ceiling on detected companies consumed, when one was set.
        max_contacts_per_company:
          anyOf:
            - type: integer
            - type: 'null'
          title: Max Contacts Per Company
          description: People imported per detected company, when one was set.
        max_per_day:
          type: integer
          title: Max Per Day
          description: >-
            Ceiling on the entries the signal imports in one day, resolved from
            the caps above.
        enrich_email:
          type: boolean
          title: Enrich Email
          description: Whether imported leads get their email enriched.
        enrich_phones:
          type: boolean
          title: Enrich Phones
          description: Whether imported leads get their phone enriched.
        imported_count:
          type: integer
          title: Imported Count
          description: Entries the signal has imported since it was created.
        contact_list_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Contact List Id
          description: Destination list, when the signal imports people.
        account_list_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Account List Id
          description: Destination list, when the signal imports companies.
        created_at:
          type: string
          format: date-time
          title: Created At
          description: When the signal was created.
        archived_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Archived At
          description: When the signal was retired, if it was.
        url:
          type: string
          title: Url
          description: Deep link to the signal in Topo.
        list_url:
          anyOf:
            - type: string
            - type: 'null'
          title: List Url
          description: Deep link to the destination list in Topo.
      type: object
      required:
        - id
        - name
        - signal_type
        - status
        - cadence
        - max_per_run
        - max_companies_per_run
        - max_contacts_per_company
        - max_per_day
        - enrich_email
        - enrich_phones
        - imported_count
        - contact_list_id
        - account_list_id
        - created_at
        - archived_at
        - url
        - list_url
      title: SignalPublicOutput
    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
    SignalRunStatus:
      type: string
      enum:
        - ACTIVE
        - PAUSED
        - ARCHIVED
      title: SignalRunStatus
    RefillFrequency:
      type: string
      enum:
        - DAILY
        - WEEKLY
      title: RefillFrequency
  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.