> This page is for Developer Documentation.

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

# Create TestOrder

POST https://{tenant_name}.benchling.com/api/v3/test-order
Content-Type: application/json

Create a Test Order for a trial sample using a Test Definition in a published assay procedure. New Test Orders start with the `PENDING` or `BLOCKED` status when a discrepancy is detected on the sample or container.

## Required fields

| Field | Description |
| --- | --- |
| `testDefinitionId` | Test Definition to perform. |
| `sampleId` | Unarchived trial sample entity. |
| `procedureId` | Published assay procedure. |

## Constraints

- The Procedure must be an `ASSAY`, have a published version, and include `testDefinitionId` in its published configuration.
- `testDefinitionId` and `containerId`, when present, must reference unarchived objects.
- If `studyIds` is provided, every Study must already be associated with `sampleId`.
- When the Procedure configures allowed dilution factors for this Test Definition, `dilutionFactor` is required and must be one of them. Otherwise, omit it.

## Optional references

- `containerId` identifies the sample container.
- `studyIds` associates the test order with existing studies.

Reference: https://docs.benchling.com/docs/api/benchling-api/test-order/create

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Request

### Body (application/json)

This endpoint expects a CreateTestOrderInput.

- `procedureId` (string, required) — The API ID of the assayprocedure to perform the test.
- `sampleId` (string, required) — The API ID of the trial sample entity to test. The sample must not be archived and must use a trial sample schema.
- `testDefinitionId` (string, required) — The API ID of the test definition to perform.
- `containerId` (string, optional, nullable) — Optional API ID of the container holding the sample. The container must not be archive and must contain the sample.
- `dilutionFactor` (integer, optional, nullable) — Optional positive dilution factor. When the selected procedure includes specifies allowed dilution factors for this Test Definition, this value is required and must be one of its configured allowed factors.
- `studyIds` (list of string, optional) — ID of the study to create the test order in, as a single-item list. The sample must be associated with the study, and the study's sample test plan must include the procedure for the sample's sample definition.

## Response

### 201

Created

- `__typename` (string, optional)
- `analysisComment` (string, optional, nullable) — Additional comments provided for a test order with a status of blocked, invalid, or canceled.
- `container` (ContainerRef, optional, nullable) — The container associated with the sample being tested in this test order
- `createdAt` (string, optional) — Timestamp of when the test order was created.
- `dilutionFactor` (integer, optional, nullable) — The dilution factor of the test order.
- `id` (string, optional) — The ID of the test order.
- `modifiedAt` (string, optional) — Timestamp of when the test order was last modified.
- `name` (string, optional) — The name of the test order.
- `plateWellAssociations` (list of TestOrderLinkedPlateWell, optional) — The plate wells this test order has been linked to.
- `procedure` (ProcedureRef, optional, nullable) — The Assay (Procedure) for which this Test Order is created. Since a Test Definition can be used in multiple Assays, this association ensures clarity on which template should be followed for the specific Test Order. It is necessary to establish this association prior to the Assay Run to avoid ambiguity.
- `procedureMethodExecutionInstance` (ProcedureMethodExecutionInstanceRef, optional, nullable) — The execution instance of the procedure method, linking the Test Order to the specific Assay Run to enable easy retrieval of all related Test Orders.
- `result` (ResultRef, optional, nullable) — The result of the test order.
- `retestSourceProcedureMethodExecutionInstance` (ProcedureMethodExecutionInstanceRef, optional, nullable) — The execution instance of the procedure method this retest order was created in the context of, linking the Test Order to the specific Assay Run to enable easy retrieval of all related Retest Orders.
- `sample` (EntityRef, optional) — The sample being tested in this test order
- `status` (enum, optional) — The status of the test order.
  - Allowed values: `PENDING`, `BLOCKED`, `IN_PROGRESS`, `CANCELLED`, `INVALID`, `COMPLETED`
- `testDefinition` (TestDefinitionRef, optional) — The test definition associated with this test order.

## Errors

### 400 Bad Request Error

Bad Request

- `detail` (GeneralErrorDetail, required, nullable)
- `instance` (string, required)
- `status` (integer, required)
- `title` (string, required, nullable)
- `type` (string, required)
- `invalidId` (string, optional)

### 403 Forbidden Error

Forbidden

- `detail` (GeneralErrorDetail, required, nullable)
- `instance` (string, required)
- `status` (integer, required)
- `title` (string, required, nullable)
- `type` (string, required)
- `invalidId` (string, optional)

### 404 Not Found Error

Not Found

- `detail` (GeneralErrorDetail, required, nullable)
- `instance` (string, required)
- `status` (integer, required)
- `title` (string, required, nullable)
- `type` (string, required)
- `invalidId` (string, optional)

### 409 Conflict Error

Conflict

- `detail` (GeneralErrorDetail, required, nullable)
- `instance` (string, required)
- `status` (integer, required)
- `title` (string, required, nullable)
- `type` (string, required)
- `invalidId` (string, optional)

### 429 Too Many Requests Error

Too Many Requests

- `detail` (TooManyRequestsErrorDetail, required, nullable)
- `instance` (string, required)
- `status` (integer, required)
- `title` (string, required, nullable)
- `type` (string, required)
- `invalidId` (string, optional)

### 500 Internal Server Error

Internal Server Error

- `detail` (InternalServerErrorDetail, required, nullable)
- `instance` (string, required)
- `status` (integer, required)
- `title` (string, required, nullable)
- `type` (string, required)
- `errorId` (string, optional)

## Types

### ContainerRef

- `__typename` (string, optional)
- `id` (string, optional)

### TestOrderLinkedPlateWell

Represents the association between a Test Order and a specific well position on a plate. When samples are plated for testing, this type captures which plate (`WellPlate`) and well position (`wellPosition`) the test order's sample has been placed in. A Test Order can be linked to multiple plate wells when the sample is distributed across multiple wells.

- `__typename` (string, optional)
- `plate` (WellPlateRef, optional) — The plate linked from the test order.
- `wellPosition` (string, optional) — Alphanumeric position of plate well eg. A1, B19

### ProcedureRef

- `__typename` (string, optional)
- `id` (string, optional)

### ProcedureMethodExecutionInstanceRef

- `__typename` (string, optional)
- `id` (string, optional)

### ResultRef

- `__typename` (string, optional)
- `id` (string, optional)

### EntityRef

- `__typename` (string, optional)
- `id` (string, optional)

### TestDefinitionRef

- `__typename` (string, optional)
- `id` (string, optional)

### GeneralErrorDetail

- string
- map from string to any

### TooManyRequestsErrorDetail

- string
- map from string to any

### InternalServerErrorDetail

- string
- map from string to any

### WellPlateRef

- `__typename` (string, optional)
- `id` (string, optional)

## Examples

**Request**

```json
{
  "procedureId": "pc_H7vB5nQ9",
  "sampleId": "bfi_k3Yp8dR1",
  "testDefinitionId": "tdef_V9qL2mX7",
  "containerId": "con_F6wN4sT2",
  "dilutionFactor": 100,
  "studyIds": [
    "stdy_M4cJ8rP6"
  ]
}
```

**Response**

```json
{
  "__typename": "string",
  "analysisComment": null,
  "container": {
    "__typename": "string",
    "id": "string"
  },
  "createdAt": "string",
  "dilutionFactor": null,
  "id": "string",
  "modifiedAt": "string",
  "name": "string",
  "plateWellAssociations": [
    {
      "__typename": "string",
      "plate": {
        "__typename": "string",
        "id": "string"
      },
      "wellPosition": "string"
    }
  ],
  "procedure": {
    "__typename": "string",
    "id": "string"
  },
  "procedureMethodExecutionInstance": {
    "__typename": "string",
    "id": "string"
  },
  "result": {
    "__typename": "string",
    "id": "string"
  },
  "retestSourceProcedureMethodExecutionInstance": {
    "__typename": "string",
    "id": "string"
  },
  "sample": {
    "__typename": "string",
    "id": "string"
  },
  "status": "PENDING",
  "testDefinition": {
    "__typename": "string",
    "id": "string"
  }
}
```

**SDK Code**

```python
import requests

url = "https://{tenant_name}.benchling.com/api/v3/test-order"

payload = {
    "procedureId": "pc_H7vB5nQ9",
    "sampleId": "bfi_k3Yp8dR1",
    "testDefinitionId": "tdef_V9qL2mX7",
    "containerId": "con_F6wN4sT2",
    "dilutionFactor": 100,
    "studyIds": ["stdy_M4cJ8rP6"]
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript
const url = 'https://{tenant_name}.benchling.com/api/v3/test-order';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"procedureId":"pc_H7vB5nQ9","sampleId":"bfi_k3Yp8dR1","testDefinitionId":"tdef_V9qL2mX7","containerId":"con_F6wN4sT2","dilutionFactor":100,"studyIds":["stdy_M4cJ8rP6"]}'
};

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