> 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 an animal

PATCH https://acme-api.invivo.benchling.com/api/public/v1/animals/{animalId}
Content-Type: application/json

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

Moving an animal between cages or treatment groups is constrained by the study it is on, and a terminated animal cannot be moved at all; see `cage_id` and `study_group_id` for the rules.

Reference: https://docs.benchling.com/in-vivo/animals/animal-update

## Authentication

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

## Request

### Path parameters

- `animalId` (string, required) — The unique identifier of the animal.

### Body (application/json)

This endpoint expects an AnimalUpdateV1.

- `cage_id` (string, optional) — Unique identifier for a cage.
- `study_group_id` (string, optional) — Unique identifier for a study group.
- `sex` (enum, optional) — The sex of an animal: `m` for male, `f` for female, and `u` for unknown. `u` is only accepted on write when the unknown-sex feature is enabled for your team, and is otherwise rejected.
  - Allowed values: `m`, `f`, `u`
- `name` (string, optional) — The name of the animal.
- `strain` (string, optional) — The strain of the animal, which also determines its species. Must be a strain configured for your team.
- `dob` (date, optional, nullable) — The date of birth of the animal. May not be in the future. Send `null` to clear it, unless your team's entity schema makes it mandatory.
- `metadata` (map from string to any, optional, nullable) — The metadata to be associated to the animal, merged into the existing metadata. Set an individual value to `null` to delete that key; keys your team's entity schema marks mandatory cannot be deleted. A `null` map is accepted but changes nothing — there is no way to clear every key at once.

## Response

### 200

The updated animal.

- `id` (string, required) — Unique identifier for an animal.
- `name` (string, required) — The name of the animal.
- `number` (integer, required) — The position of the animal within its cage.
- `catalog` (string, required, nullable) — The catalog number of the animal.
- `species` (string, required, nullable) — The species of the animal, derived from its strain. Null when the animal has no strain assigned.
- `strain` (string, required, nullable) — The strain of the animal.
- `sex` (enum, required, nullable) — The sex of the animal.
  - Allowed values: `m`, `f`, `u`
- `dob` (date, required, nullable) — The date of birth of the animal.
- `donor` (string, required, nullable) — The donor identifier of the animal.
- `ear` (string, required, nullable) — The ear marking identifying the animal.
- `tag` (string, required, nullable) — The tag identifying the animal.
- `tail` (string, required, nullable) — The tail marking identifying the animal.
- `study` (StudyNestedV1, required, nullable) — The study the animal is enrolled on. Null when it is not on a study.
- `study_group` (StudyGroupNestedV1, required, nullable) — The treatment group the animal is assigned to. Null when it is not on a study, or is on one but not yet grouped.
- `cage` (CageNestedV1, required, nullable) — The cage the animal is housed in.
- `tracking_date` (date, required, nullable) — The date from which the animal's tracking days are counted.
- `disease_induction_date` (date, required, nullable) — The date the animal had a disease induced.
- `disease_survivor` (boolean, required, nullable) — Whether the animal survived the induced disease.
- `terminated_at` (date, required, nullable) — The date the animal was terminated. Null while the animal is alive. A terminated animal cannot be moved between cages or study groups.
- `terminated_by` (StudyAuthorUserV1, required, nullable) — The user who recorded the termination.
- `terminated_reason` (AnimalTerminatedReasonV1, required, nullable) — Why the animal was terminated.
- `metadata` (map from string to any, required, nullable) — The metadata associated to the animal.
- `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

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

### StudyGroupNestedV1

The treatment group an animal is assigned to within a study, as embedded in the animal. The study is given as an identifier rather than an object to keep the animal response from nesting the same study twice.

- `id` (string, required) — Unique identifier for a study group.
- `study_id` (string, required) — Unique identifier for a study.
- `name` (string, required) — The name of the study group.
- `no` (integer, required, nullable) — The position of the group in the study's group ordering.
- `color` (string, required, nullable) — The colour used to represent the group in the interface.
- `max_animals` (integer, required, nullable) — The number of animals the group can hold. Assigning an animal to a group already at this capacity is rejected. Null when the group is uncapped.
- `control` (boolean, required) — Whether the group is the study's control group.
- `metadata` (map from string to any, required, nullable) — The metadata associated to the study group.
- `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`.

### CageNestedV1

The cage an animal is housed in, as embedded in the animal. The study is given as an identifier rather than an object to keep the animal response from nesting the same study twice.

- `id` (string, required) — Unique identifier for a cage.
- `study_id` (string, required, nullable) — The study the cage belongs to. Null for a cage not assigned to a study.
- `name` (string, required) — The name of the cage.
- `catalog` (string, required, nullable) — The catalog number of the cage.
- `metadata` (map from string to any, required, nullable) — The metadata associated to the cage.
- `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`.

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

### AnimalTerminatedReasonV1

Why an animal was terminated. The reason is chosen from the shared glossary, or recorded free-form when no glossary entry fits.

- `glossary_id` (string, required, nullable) — The glossary entry the reason was chosen from. Null when the reason was recorded free-form.
- `title` (string, required, nullable) — The reason for the termination.
- `comment` (string, required, nullable) — Any further detail recorded alongside the reason.

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

## Examples

**Request**

```json
{
  "cage_id": "cge_6uFo3TUYezxtFuImb9kk8K",
  "study_group_id": "grp_1OEdawZKhmLCf88R4AnCZm",
  "name": "Animal 1",
  "metadata": {
    "animal-internal-id": "ANIMAL-4321"
  }
}
```

**Response**

```json
{
  "id": "aml_71H39zdfOc89pNIutQSI22",
  "name": "Animal 1",
  "number": 1,
  "catalog": "A0000001",
  "species": "Mus musculus",
  "strain": "C57BL/6J",
  "sex": "m",
  "dob": "2026-09-09",
  "donor": null,
  "ear": "2R",
  "tag": "T-0041",
  "tail": "1",
  "study": {
    "id": "sdy_6y9Wop1uArRjD93UiQ5qFy",
    "project_id": "pjt_7IrvD7jMtAGvBl4AQUUr3g",
    "name": "Benchling In Vivo",
    "code": "CD-26-445",
    "study_code_id": "sdc_n6vkWmmHoACZ15pTxztHk",
    "type": "internal",
    "status": "in_progress",
    "description": "Efficacy study in a xenograft model.",
    "timezone": "America/Los_Angeles",
    "metadata": {
      "study-internal-id": "STUDY-1234"
    },
    "author": {
      "id": "usr_72aeLmlraBB7Ekzu2zTsMW",
      "name": "Jo Harper",
      "email": "jo.harper@example.com",
      "timezone": "UTC"
    },
    "owner": {
      "id": "usr_5TSgutt2ZHPnKOdYbaNlRo",
      "name": "Sam Ellis",
      "email": "sam.ellis@example.com",
      "timezone": "UTC"
    },
    "started_on": "2026-09-10",
    "tracking_day_base": 0,
    "completed_at": null,
    "canceled_at": null,
    "created_at": "2026-09-10T07:27:34.132511Z",
    "updated_at": "2026-09-10T07:27:34.132511Z"
  },
  "study_group": {
    "id": "grp_1OEdawZKhmLCf88R4AnCZm",
    "study_id": "sdy_6y9Wop1uArRjD93UiQ5qFy",
    "name": "Vehicle",
    "no": 1,
    "color": "#e9429d",
    "max_animals": 10,
    "control": true,
    "metadata": {
      "study-group-internal-id": "GROUP-1234"
    },
    "created_at": "2026-09-10T07:27:10.770562Z",
    "updated_at": "2026-09-10T07:27:10.770562Z"
  },
  "cage": {
    "id": "cge_6uFo3TUYezxtFuImb9kk8K",
    "study_id": "sdy_6y9Wop1uArRjD93UiQ5qFy",
    "name": "Cage 1",
    "catalog": "C0000001",
    "metadata": {
      "cage-internal-id": "CAGE-1234"
    },
    "created_at": "2026-09-10T07:27:10.734591Z",
    "updated_at": "2026-09-10T07:27:10.734591Z"
  },
  "tracking_date": "2026-09-10",
  "disease_induction_date": "2026-09-10",
  "disease_survivor": false,
  "terminated_at": null,
  "terminated_by": null,
  "terminated_reason": null,
  "metadata": {
    "animal-internal-id": "ANIMAL-1234"
  },
  "created_at": "2026-09-10T07:27:10.785238Z",
  "updated_at": "2026-09-10T07:27:10.785238Z"
}
```

**SDK Code**

```python
import requests

url = "https://acme-api.invivo.benchling.com/api/public/v1/animals/aml_7KpQ2mNvR4tXwZ9bYcDfGh"

payload = {
    "cage_id": "cge_6uFo3TUYezxtFuImb9kk8K",
    "study_group_id": "grp_1OEdawZKhmLCf88R4AnCZm",
    "name": "Animal 1",
    "metadata": { "animal-internal-id": "ANIMAL-4321" }
}
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/animals/aml_7KpQ2mNvR4tXwZ9bYcDfGh';
const options = {
  method: 'PATCH',
  headers: {Authorization: '<token>.', 'Content-Type': 'application/json'},
  body: '{"cage_id":"cge_6uFo3TUYezxtFuImb9kk8K","study_group_id":"grp_1OEdawZKhmLCf88R4AnCZm","name":"Animal 1","metadata":{"animal-internal-id":"ANIMAL-4321"}}'
};

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