# Preview a bulk reassignment (/docs/api-reference/scheduling-reassignments/preview-scheduling-reassignment)

Who each booking would go to, and why not when nobody can take it, without moving anything. It works down them in order, so two can't both be promised the same free hour. Change any of it and start the run with `assignments`. Covers the first 500. Things can change before you start it: the run decides again.

`POST https://api.coss.com/v1/scheduling/reassignments/preview`

Authenticate with your API key as a bearer token (`Authorization: Bearer coss_test_…`). Responses are JSON with snake_case fields; errors are `{ error: { type, code, message, param?, issues?, request_id } }` (https://coss.com/docs/api-reference/errors.md).

## Request body

- `selection` (object, required)
  - `host` (string): This host's bookings, by id or uid.
  - `out_of_office` (string): The bookings that fall in this entry.
  - `booking_ids` (string[], at most 5000 items)
  - `series` (string): A series' occurrences still to come.
  - `start_after` (string): An ISO 8601 instant with an offset.
  - `start_before` (string): An ISO 8601 instant with an offset.
  - `event_types` (string[], at most 100 items)
  - `external_conflict` (boolean): Only those with something else on the host's calendar at that time.
- `strategy` (object, default {})
  - `to_host` (string): Give them all to this host.
  - `preferred_hosts` (string[], at most 20 items): Try these first, in order.
  - `otherwise` ("auto" | "leave"): After `preferred_hosts`: `auto` picks the fairest who's free, `leave` keeps it where it is.
  - `assignments` (object[], at most 5000 items): Who each goes to: a preview, with your changes.
    - `booking` (string, required)
    - `to_host` (string, required)
    - `from_host` (string)
- `overrides` (("any_host" | "out_of_office" | "outside_availability" | "host_busy" | "limit_reached" | "calendar_unverified")[], at most 6 items)

## Example request

TypeScript (the `coss` package):

```ts
import { Coss } from "coss";

const coss = new Coss({
  apiKey: process.env.COSS_API_KEY,
  baseUrl: "https://api.coss.com",
});

const { data, error } = await coss.scheduling.reassignments.preview({
  selection: {
    host: "doctor_482",
    start_before: "2027-08-14T00:00:00.000Z",
  },
  strategy: {
    preferred_hosts: [
      "doctor_518",
    ],
  },
});
```

HTTP:

```sh
curl -X POST "https://api.coss.com/v1/scheduling/reassignments/preview" \
  -H "Authorization: Bearer $COSS_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "selection": {
    "host": "doctor_482",
    "start_before": "2027-08-14T00:00:00.000Z"
  },
  "strategy": {
    "preferred_hosts": [
      "doctor_518"
    ]
  }
}'
```

## Response 200

What would happen.

- `object` ("scheduling.reassignment_preview", required)
- `items` (object[], required)
  - `booking` (string, required)
  - `event_type` (string, required)
  - `title` (string, required)
  - `status` ("held" | "pending_approval" | "confirmed" | "cancelled" | "declined", required)
  - `start` (string, required)
  - `end` (string, required)
  - `series` (string | null, required)
  - `group_session` (string | null, required)
  - `from_host` (string | null, required)
  - `to_host` (string | null, required): Null when nobody could take it.
  - `reason` (string | null, required): Why it would stay where it is.
- `truncated` (boolean, required): There are more than a preview covers.

Example:

```json
{
  "object": "scheduling.reassignment_preview",
  "items": [
    {
      "booking": "book_01kd2m9a0b1c2d3e4f5g6h7j8m",
      "event_type": "evtype_01kd2m9a0b1c2d3e4f5g6h7j8m",
      "title": "Consultation",
      "status": "confirmed",
      "start": "2027-08-03T15:00:00.000Z",
      "end": "2027-08-03T15:30:00.000Z",
      "series": null,
      "group_session": null,
      "from_host": "host_01kd2m9a0b1c2d3e4f5g6h7j8m",
      "to_host": "host_01kd2m9a0b1c2d3e4f5g6h7j8n",
      "reason": null
    }
  ],
  "truncated": false
}
```

## Errors

- `400`: The body is not valid JSON (`invalid_json`). Also when the `Coss-Version` header names an unknown API version (`invalid_api_version`).
- `401`: The API key is missing, invalid, revoked or expired (`authentication_error`).
- `403`: The API key lacks the permission this endpoint needs (`permission_error`), or its organization is suspended (`organization_suspended`).
- `404`: Nothing with this id or uid exists in the environment (`not_found`).
- `415`: The body is not sent as `application/json` (`unsupported_media_type`).
- `422`: The selection or strategy doesn't make sense (`invalid_reassignment`).
- `429`: Too many requests with this API key (`rate_limited`), or too many requests with invalid keys from this address (`too_many_failed_authentications`). Retry after `Retry-After` seconds. Successful responses carry `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` (seconds until the limit is fully restored).
- `500`: Unexpected server error (`api_error` / `internal_error`).
- `503`: The API key could not be verified right now; retry (`service_unavailable`).