---
title: "Remove many contacts from the sequence"
method: POST
path: "/sequences/{sequence_id}/contacts/bulk-remove/"
tags: ["sequences"]
---

# Remove many contacts from the sequence

`POST /sequences/{sequence_id}/contacts/bulk-remove/`

## Request

- Base URL: `https://api.getoneprofile.ai` (the document declares no server; this is the origin it was published from)
- URL: `https://api.getoneprofile.ai/sequences/{sequence_id}/contacts/bulk-remove/`
- Auth: one of:
  - API key in header `X-API-Key`
  - HTTP bearer

Removes the listed contacts, or with scope='all' every contact the given filters match, less any excluded_ids. The set is resolved on the server, never from a client-side id list, so the action covers every match across pages. Each removal keeps the durable single-remove semantics.

## Path parameters

- `sequence_id` string, uuid, required

## Request body

- BulkRemoveContactsSchema: One bulk removal.
  - `created_from` string, date-time, nullable: Only remove contacts added on or after this instant. The grid's date range, which a scope='all' removal has to honour or it reaches past what the person was looking at.
  - `created_to` string, date-time, nullable
  - `enrolment_ids` string[]
  - `exclude` boolean: Read 'statuses' and 'stop_reasons' as 'everything but', matching the Contacts tab's one Include/Exclude toggle.
  - `excluded_ids` string[]: With scope='all', contacts to leave out: the rows unticked after ticking the header checkbox.
  - `group` 'in_progress' | 'needs_approval' | 'paused' | 'done' | 'blocked': The Audience tab's tab a contact sits under; every contact is under one. The tabs used to be counts that overlapped (a bounced contact was both "reachable" and "blocked", so the counts added up past the roster) and opened a list of names over the roster they repeated (Natsuki, 2026-10-02). They partition the roster now and filter it in place, so a tab's count is exactly the rows it shows, and each row's own status chip names the state that put it there. Derived at read time from the status, the stop reason, the contact's current-step task and whether an address reaches them, never stored.
  - `limit` integer, nullable: With scope='all', act on only the FIRST n of the resolved set (in the roster's order) instead of every match.
  - `scope` 'ids' | 'all'
  - `search` string, nullable
  - `sort` 'created_desc' | 'created_asc' | 'status' | 'status_desc' | 'next_due': The orders the Audience tab can list a sequence's contacts in.
  - `statuses` EnrolmentStatus[], nullable
  - `stop_reasons` StopReason[], nullable

## Response `200`

Successful Response

- BulkRemoveContactsResponseSchema
  - `removed` integer, required

## Other responses

- `401`: Unauthorized
- `403`: Forbidden
- `404`: Not found.
- `422`: Invalid request made to the API.
- `500`: Internal server error.
- `502`: Bad gateway error.
- `503`: Service unavailable.

---

[API](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile.md) · [All operations](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/llms.txt) · [OpenAPI document](https://skmtc.dev/getoneprofile/apis/api-reference-oneprofile/revisions/4a6bd71e3f02?raw)
