> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.benchling.com/in-vivo/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.benchling.com/in-vivo/_mcp/server.

# Update a study task spec

PATCH https://acme-api.invivo.benchling.com/api/public/v1/studies/{studyId}/task-specs/{taskSpecId}
Content-Type: application/json

Updates the specified task specification by setting the values of the parameters passed. Omitted properties are left untouched.

Reference: https://docs.benchling.com/in-vivo/study-task-specs/study-task-spec-update

## Authentication

- OAuth2 — send the obtained token as `Authorization: Bearer <token>`

## Request

### Path parameters

- `studyId` (string, required) — The unique identifier of the study.
- `taskSpecId` (string, required) — The unique identifier of the task specification.

### Body (application/json)

This endpoint expects a TaskSpecPatchV1.

- `title` (string, optional) — The title of the task specification.
- `description` (string, optional, nullable) — The description of the task specification.
- `schedule` (TaskSchedulePatchV1, optional) — Partial update to a task specification schedule. The `type` discriminator selects which nested details object is present.
- `execution` (TaskExecutionPatchV1, optional) — Partial update to a task specification's execution. The `type` discriminator selects which nested workflow patch object is present.

## Response

### 200

The updated task specification.

- `id` (string, required) — Unique identifier for a study task specification.
- `title` (string, required) — The title of the task specification.
- `description` (string, required, nullable) — The description of the task specification.
- `type` (enum, required) — The kind of work a task specification describes.
  - Allowed values: `measurement`, `sample`, `observation`, `dosing`, `other`
- `execution` (TaskExecutionV1, required, nullable) — Execution configuration for typed task specs. Null for `other` task specs.
- `schedule` (TaskScheduleV1, required) — Schedule for a task specification. The `type` discriminator selects which of `one_off`, `recurring` or `conditional` is present; the others are omitted. `timezone` is set from the study on create and always returned on read.
- `target` (TaskTargetTypeV1, required) — Target type embedded on a task specification response.
- `study` (StudyNestedV1, required) — The study a record belongs to, as embedded in animals, dosages, measurements, observations and samples. Carries the same attributes as a study retrieved directly, except that the project is given as an identifier rather than an embedded object.
- `created_at` (datetime, required) — UTC timestamp with microsecond precision, always suffixed with `Z`, in the form `yyyy-MM-ddTHH:mm:ss.SSSSSSZ`.
- `updated_at` (datetime, required) — UTC timestamp with microsecond precision, always suffixed with `Z`, in the form `yyyy-MM-ddTHH:mm:ss.SSSSSSZ`.

## Errors

### 400 Bad Request Error

The request was rejected. Validation failures return a `ValidationErrorResponse`; an unrecognised `X-Studies-Api-Version` header returns an `AuthErrorResponse` with the code `invalid_header`.

- `BadRequestErrorResponse`

### 401 Unauthorized Error

Authentication failed. The body is normally empty; when an otherwise valid access token is missing required claims the body is an `AuthErrorResponse` with the code `invalid_token`.

- `any`

### 403 Forbidden Error

The access token does not grant the scopes this operation requires. The body is normally empty; when the token's team is missing or deleted the body is an `AuthErrorResponse` with the code `invalid_data`.

- `any`

### 404 Not Found Error

No resource matching the given identifier exists on your team. The body is empty.

- `any`

### 429 Too Many Requests Error

A rate limit was exceeded. Retry once the window resets; no `Retry-After` header is sent, so use `X-RateLimit-Reset`.

- `error` ("rate_limit_exceeded", required) — A machine-readable error code.
- `message` (string, required) — A human-readable explanation of the failure.

## Types

### TaskSchedulePatchV1

Partial update to a task specification schedule. The `type` discriminator selects which nested details object is present.

- `type` (enum, required) — How a task specification is scheduled.
  - Allowed values: `one_off`, `recurring`, `conditional`
- `time` (TaskTimeDurationPatchV1, optional) — Partial update to time-of-day configuration. `type` selects whether the nested `all_day` marker or `timed` window is present.
- `one_off` (TaskScheduleOneOffDetailsPatchV1, optional) — Partial update to one-off schedule details.
- `recurring` (TaskScheduleRecurringDetailsPatchV1, optional) — Partial update to recurring schedule details.
- `conditional` (TaskScheduleConditionalDetailsPatchV1, optional) — Partial update to conditional schedule details.

### TaskExecutionPatchV1

Partial update to a task specification's execution. The `type` discriminator selects which nested workflow patch object is present.

- `type` (enum, required) — Discriminator for the nested execution workflow object.
  - Allowed values: `measurement_workflow`, `sample_workflow`, `observation_workflow`, `dosing_workflow`
- `sample_workflow` (WorkflowTemplateSamplePatchV1, optional) — Partial update to sample-collection settings on a task specification.
- `dosing_workflow` (WorkflowTemplateDosingPatchV1, optional) — Partial update to dosing settings on a task specification.
- `observation_workflow` (WorkflowTemplateObservationPatchV1, optional) — Partial update to observation settings on a task specification.
- `measurement_workflow` (WorkflowTemplateMeasurementPatchV1, optional) — Partial update to measurement settings. Omitted properties are left untouched; `null` clears `weight_percentage_change`, `assign_identifier` or `cursor_position` where clearing is permitted.

### TaskExecutionV1

Execution configuration for a typed task specification. `type` selects the variant, which carries only its own workflow object.

- `type`: `measurement_workflow` (TaskExecutionMeasurementV1)
  - `measurement_workflow` (WorkflowTemplateMeasurementV1, required, nullable) — The measurement workflow template. Null in task specification lists and `study.task_spec.*` webhooks, which carry no template.
- `type`: `sample_workflow` (TaskExecutionSampleV1)
  - `sample_workflow` (WorkflowTemplateSampleV1, required, nullable) — The sample workflow template. Null in task specification lists and `study.task_spec.*` webhooks, which carry no template.
- `type`: `observation_workflow` (TaskExecutionObservationV1)
  - `observation_workflow` (WorkflowTemplateObservationV1, required, nullable) — The observation workflow template. Null in task specification lists and `study.task_spec.*` webhooks, which carry no template.
- `type`: `dosing_workflow` (TaskExecutionDosingV1)
  - `dosing_workflow` (WorkflowTemplateDosingV1, required, nullable) — The dosing workflow template. Null in task specification lists and `study.task_spec.*` webhooks, which carry no template.

### TaskScheduleV1

Schedule for a task specification. The `type` discriminator selects which of `one_off`, `recurring` or `conditional` is present; the others are omitted. `timezone` is set from the study on create and always returned on read.

- `time` (TaskTimeDurationV1, required) — Time-of-day configuration for a scheduled task. When `type` is `timed`, the nested `timed` object carries the window; when `type` is `all_day`, `timed` is omitted.
- `timezone` (string, required) — IANA timezone of the schedule. Derived from the study on create.
- `type` (enum, required) — How a task specification is scheduled.
  - Allowed values: `one_off`, `recurring`, `conditional`
- `one_off` (TaskScheduleOneOffDetailsV1, optional) — Details for a one-off schedule.
- `recurring` (TaskScheduleRecurringDetailsV1, optional) — Details for a recurring schedule.
- `conditional` (TaskScheduleConditionalDetailsV1, optional) — Details for a conditional schedule.

### TaskTargetTypeV1

Target type embedded on a task specification response.

- `type` (enum, required) — What a task specification is aimed at.
  - Allowed values: `animal`, `group`

### StudyNestedV1

The study a record belongs to, as embedded in animals, dosages, measurements, observations and samples. Carries the same attributes as a study retrieved directly, except that the project is given as an identifier rather than an embedded object.

- `id` (string, required) — Unique identifier for a study.
- `project_id` (string, required, nullable) — The project of the study. Null when the study is not in a project.
- `name` (string, required) — The name of the study.
- `code` (string, required, nullable) — The code of the study.
- `study_code_id` (string, required, nullable) — The unique identifier of the study code template.
- `type` (enum, required) — Whether the study is run in-house or by an external partner. The `all` value accepted by some filters is not a valid study type and is never returned.
  - Allowed values: `internal`, `external`
- `status` (enum, required) — Review status of a study.
  - Allowed values: `awaiting_approval`, `in_progress`, `rejected`
- `description` (string, required, nullable) — The description of the study.
- `timezone` (string, required, nullable) — The timezone of the study, as an IANA timezone identifier.
- `metadata` (map from string to any, required, nullable) — The metadata associated to the study.
- `author` (StudyAuthorUserV1, required, nullable) — The author of the study.
- `owner` (StudyAuthorUserV1, required, nullable) — The owner of the study.
- `started_on` (date, required) — Calendar date with no time or offset component, in ISO-8601 form.
- `tracking_day_base` (integer, required, nullable) — The day number assigned to the study's start date, from which all subsequent tracking days are counted.
- `completed_at` (datetime, required, nullable) — The completed timestamp of the study.
- `canceled_at` (datetime, required, nullable) — The canceled timestamp of the study.
- `created_at` (datetime, required) — UTC timestamp with microsecond precision, always suffixed with `Z`, in the form `yyyy-MM-ddTHH:mm:ss.SSSSSSZ`.
- `updated_at` (datetime, required) — UTC timestamp with microsecond precision, always suffixed with `Z`, in the form `yyyy-MM-ddTHH:mm:ss.SSSSSSZ`.

### ValidationErrorResponse

Returned when a request body or parameter fails validation.

- `message` (string, required) — A summary of the failure.
- `errors` (map from string to list of string, required) — Failure messages keyed by the offending field, using the field's name as it appears on the wire. Nested fields are dotted, e.g. `schedule.duration`.

### AuthErrorResponse

Returned when a request is rejected during authentication, before it is processed.

- `error` (enum, required) — A machine-readable error code.
  - Allowed values: `invalid_header`, `invalid_token`, `invalid_data`
- `error_description` (string, required) — A human-readable explanation of the failure.

### ProblemDetail

An RFC 9457 problem detail, returned when a request is rejected before it reaches a controller method — most commonly an unparseable or absent JSON body. Unlike the rest of this API, null members are omitted rather than serialised as `null`.

- `title` (string, required) — A short, human-readable summary of the problem type.
- `status` (integer, required) — The HTTP status code, repeated in the body.
- `detail` (string, required) — A human-readable explanation specific to this occurrence.
- `instance` (string, required) — The path of the request that produced the problem.

### TaskTimeDurationPatchV1

Partial update to time-of-day configuration. `type` selects whether the nested `all_day` marker or `timed` window is present.

- `type` (enum, required) — Whether a scheduled task fills the whole day or a timed window.
  - Allowed values: `all_day`, `timed`
- `all_day` (TaskTimeDurationPatchV1AllDay, optional) — Empty marker object when switching to an all-day schedule.
- `timed` (TaskTimeTimedDetailsPatchV1, optional) — Partial update to a timed task window. Either bound may be omitted.

### TaskScheduleOneOffDetailsPatchV1

Partial update to one-off schedule details.

- `duration` (TaskDurationPatchV1, optional) — Partial update to a schedule date range. Either bound may be omitted.

### TaskScheduleRecurringDetailsPatchV1

Partial update to recurring schedule details.

- `duration` (TaskDurationPatchV1, optional) — Partial update to a schedule date range. Either bound may be omitted.
- `repeat` (TaskRepeatValuePatchV1, optional) — Partial update to a recurring schedule interval.

### TaskScheduleConditionalDetailsPatchV1

Partial update to conditional schedule details.

- `condition` (TaskConditionPatchV1, optional) — Partial update to a conditional schedule trigger.

### WorkflowTemplateSamplePatchV1

Partial update to sample-collection settings on a task specification.

- `samples` (list of string, optional) — Replacement list of sample glossary identifiers.
- `auto_generate_sample_id` (boolean, optional) — Whether sample identifiers are generated automatically.

### WorkflowTemplateDosingPatchV1

Partial update to dosing settings on a task specification.

- `treatments` (list of string, optional) — Replacement list of treatments.
- `skip_dosing_for_un_required_animals` (boolean, optional) — Whether dosing is skipped for animals that do not require it.
- `use_new_body_weight` (boolean, optional) — Whether a newly measured body weight is used for dosing.

### WorkflowTemplateObservationPatchV1

Partial update to observation settings on a task specification.

- `observations` (list of string, optional) — Replacement list of observation glossary identifiers.

### WorkflowTemplateMeasurementPatchV1

Partial update to measurement settings. Omitted properties are left untouched; `null` clears `weight_percentage_change`, `assign_identifier` or `cursor_position` where clearing is permitted.

- `measurements` (list of string, optional) — Replacement list of measurement variable slugs.
- `weight_percentage_change` (enum, optional, nullable) — Baseline for weight percentage change tracking. Send `null` to clear.
  - Allowed values: `first_measurement`, `latest_measurement`, `maximum_measurement`, `tracking_date`, `disease_induction_date`
- `assign_identifier` (enum, optional, nullable) — Identifier assignment strategy. Send `null` to clear.
  - Allowed values: `donor`, `ear`, `tag`, `tail`
- `cursor_position` (string, optional, nullable) — Cursor position for measurement entry. Send `null` to clear.

### WorkflowTemplateMeasurementV1

Measurement settings for a measurement task specification.

- `measurements` (list of string, required, nullable) — Measurement variable slugs to record.
- `weight_percentage_change` (enum, required, nullable) — Baseline for weight percentage change tracking.
  - Allowed values: `first_measurement`, `latest_measurement`, `maximum_measurement`, `tracking_date`, `disease_induction_date`
- `assign_identifier` (enum, required, nullable) — Identifier assignment strategy. Null when none is configured.
  - Allowed values: `donor`, `ear`, `tag`, `tail`
- `cursor_position` (string, required, nullable) — Cursor position for measurement entry. Must be one of the values in `measurements` when set.

### WorkflowTemplateSampleV1

Sample-collection settings for a sample task specification.

- `samples` (list of string, required) — Team glossary identifiers of the samples to collect.
- `auto_generate_sample_id` (boolean, required) — Whether sample identifiers are generated automatically.

### WorkflowTemplateObservationV1

Observation settings for an observation task specification.

- `observations` (list of string, required) — Team glossary identifiers of the observations to record.

### WorkflowTemplateDosingV1

Dosing settings for a dosing task specification.

- `treatments` (list of string, required) — Treatments to administer.
- `skip_dosing_for_un_required_animals` (boolean, required) — Whether dosing is skipped for animals that do not require it.
- `use_new_body_weight` (boolean, required) — Whether a newly measured body weight is used for dosing.

### TaskTimeDurationV1

Time-of-day configuration for a scheduled task. When `type` is `timed`, the nested `timed` object carries the window; when `type` is `all_day`, `timed` is omitted.

- `type` (enum, required) — Whether a scheduled task fills the whole day or a timed window.
  - Allowed values: `all_day`, `timed`
- `timed` (TaskTimeTimedDetailsV1, optional) — Start and end times for a timed task window.

### TaskScheduleOneOffDetailsV1

Details for a one-off schedule.

- `duration` (TaskDurationV1, required) — Inclusive calendar date range for a one-off or recurring schedule.

### TaskScheduleRecurringDetailsV1

Details for a recurring schedule.

- `duration` (TaskDurationV1, required) — Inclusive calendar date range for a one-off or recurring schedule.
- `repeat` (TaskRepeatValueV1, required) — Repeat interval for a recurring schedule.

### TaskScheduleConditionalDetailsV1

Details for a conditional schedule.

- `condition` (TaskConditionalV1, required) — Condition that triggers a conditional schedule.

### StudyAuthorUserV1

A user referenced as the author or owner of a study.

- `id` (string, required) — Unique identifier for a user.
- `name` (string, required) — The name of the user.
- `email` (string, required) — The email address of the user.
- `timezone` (string, required) — The timezone of the user. Defaults to `UTC` when the user has none set.

### TaskTimeDurationPatchV1AllDay

Empty marker object when switching to an all-day schedule.

### TaskTimeTimedDetailsPatchV1

Partial update to a timed task window. Either bound may be omitted.

- `from` (string, optional) — Time of day with no date or offset, in ISO-8601 local time form.
- `to` (string, optional) — Time of day with no date or offset, in ISO-8601 local time form.

### TaskDurationPatchV1

Partial update to a schedule date range. Either bound may be omitted.

- `start` (date, optional) — New start date.
- `end` (date, optional) — New end date.

### TaskRepeatValuePatchV1

Partial update to a recurring schedule interval.

- `value` (integer, optional) — New number of `unit`s between occurrences.
- `unit` (enum, optional) — The unit for a recurring schedule interval.
  - Allowed values: `days`, `weeks`
- `on_day` (list of enum, optional) — Replacement weekdays when `unit` is `weeks`.
  - Allowed values: `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`, `sunday`

### TaskConditionPatchV1

Partial update to a conditional schedule trigger.

- `value` (list of integer, optional) — Replacement condition values, such as study-day numbers.
- `unit` (enum, optional) — The unit for a conditional schedule value.
  - Allowed values: `days`, `weeks`

### TaskTimeTimedDetailsV1

Start and end times for a timed task window.

- `from` (string, required) — Time of day with no date or offset, in ISO-8601 local time form.
- `to` (string, required) — Time of day with no date or offset, in ISO-8601 local time form.

### TaskDurationV1

Inclusive calendar date range for a one-off or recurring schedule.

- `start` (date, required, nullable) — Inclusive start date of the schedule window.
- `end` (date, required, nullable) — Inclusive end date of the schedule window.

### TaskRepeatValueV1

Repeat interval for a recurring schedule.

- `value` (integer, required) — How many `unit`s between occurrences.
- `unit` (enum, required) — The unit for a recurring schedule interval.
  - Allowed values: `days`, `weeks`
- `on_day` (list of enum, required, nullable) — Days of the week when `unit` is `weeks`. Null when the repeat is not weekly.
  - Allowed values: `monday`, `tuesday`, `wednesday`, `thursday`, `friday`, `saturday`, `sunday`

### TaskConditionalV1

Condition that triggers a conditional schedule.

- `type` (enum, required) — The condition that triggers a conditional schedule.
  - Allowed values: `age`, `study_day`, `tracking_day`
- `value` (list of integer, required) — Condition values (for example study-day numbers).
- `unit` (enum, required) — The unit for a conditional schedule value.
  - Allowed values: `days`, `weeks`

## Examples

**Request**

```json
{}
```

**Response**

```json
{
  "id": "tsp_2Z3wOcuU0l0s9H6up0umd6",
  "title": "string",
  "description": "string",
  "type": "measurement",
  "execution": {
    "measurement_workflow": {
      "assign_identifier": "donor",
      "cursor_position": "string",
      "measurements": [
        "weight",
        "body_temperature"
      ],
      "weight_percentage_change": "first_measurement"
    },
    "type": "string"
  },
  "schedule": {
    "time": {
      "type": "all_day",
      "timed": {
        "from": "09:00:00",
        "to": "09:00:00"
      }
    },
    "timezone": "America/Los_Angeles",
    "type": "one_off",
    "one_off": {
      "duration": {
        "start": "2026-09-18",
        "end": "2026-09-18"
      }
    },
    "recurring": {
      "duration": {
        "start": "2026-09-18",
        "end": "2026-09-18"
      },
      "repeat": {
        "value": 1,
        "unit": "days",
        "on_day": [
          "monday"
        ]
      }
    },
    "conditional": {
      "condition": {
        "type": "age",
        "value": [
          1
        ],
        "unit": "days"
      }
    }
  },
  "target": {
    "type": "animal"
  },
  "study": {
    "id": "sdy_3vQ8kZpLmN2xRt7YwBcDfG",
    "project_id": "pjt_9kLmNpQrStUvWxYzAbCdEf",
    "name": "string",
    "code": "string",
    "study_code_id": "sdc_7hJ4nQrXsT9wYzAbCdEfGh",
    "type": "internal",
    "status": "in_progress",
    "description": "string",
    "timezone": "America/Los_Angeles",
    "metadata": {
      "cohort_size": 24,
      "species": "Mus musculus"
    },
    "author": {
      "id": "usr_2fBnKqWxYz5tRvMpLsJdHc",
      "name": "string",
      "email": "string",
      "timezone": "string"
    },
    "owner": {
      "id": "usr_2fBnKqWxYz5tRvMpLsJdHc",
      "name": "string",
      "email": "string",
      "timezone": "string"
    },
    "started_on": "2026-09-18",
    "tracking_day_base": 1,
    "completed_at": "2026-09-18T14:03:22.123456Z",
    "canceled_at": "2026-09-18T14:03:22.123456Z",
    "created_at": "2026-09-18T14:03:22.123456Z",
    "updated_at": "2026-09-18T14:03:22.123456Z"
  },
  "created_at": "2026-09-18T14:03:22.123456Z",
  "updated_at": "2026-09-18T14:03:22.123456Z"
}
```

**SDK Code**

```python
import requests

url = "https://acme-api.invivo.benchling.com/api/public/v1/studies/sdy_3vQ8kZpLmN2xRt7YwBcDfG/task-specs/tsp_2Z3wOcuU0l0s9H6up0umd6"

payload = {}
headers = {
    "Authorization": "<token>.",
    "Content-Type": "application/json"
}

response = requests.patch(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://acme-api.invivo.benchling.com/api/public/v1/studies/sdy_3vQ8kZpLmN2xRt7YwBcDfG/task-specs/tsp_2Z3wOcuU0l0s9H6up0umd6';
const options = {
  method: 'PATCH',
  headers: {Authorization: '<token>.', 'Content-Type': 'application/json'},
  body: '{}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```