Skip to navigation

What's new in v3

The V3 REST API is Benchling’s recommended API for new development. It is served from a single unified base path, covers substantially more of the platform than V2, and has a stable tier with a 90-day breaking-change notice.

The V3 REST API is designed to provide consistent, complete coverage across all Benchling types, in accordance with FAIR principles. The REST API, V3 Events, and the V3 Python SDK are all powered by the Benchling Domain Graph, which is what keeps coverage and naming consistent across developer interfaces. It also lets us apply platform-wide frameworks, such as generic batch writes and field selection, uniformly across the API rather than endpoint by endpoint.

Use V3 for new development

V3 has broader coverage than V2, a stable tier with a 90-day breaking-change notice, and features that V2 does not have: batch writes, field selection, and typed filters. New endpoints ship to V3 first.

For Python, use the V3 Python SDK. V2 and V3 can be used side by side in the same integration.

Base path

All V3 endpoints are served from a single base path on your tenant:

Base path
https://{tenant_name}.benchling.com/api/v3

Stability

V3 has two stability levels. They track the state of the underlying product: a generally available feature typically has a stable API, while features in beta or Limited Availability expose beta endpoints.

stablebeta
Base path/api/v3/api/v3
How to accessDefaultEARLY-ACCESS: true header
Breaking change frequencyRareFrequent
Breaking change window90 daysNo notice
Recommended environmentsprod, test, dev, othertest and dev only

To call a beta operation, send the EARLY-ACCESS header:

Endpoint
GET /api/v3/entry/etr_8rVKW0g7/parts/items
EARLY-ACCESS: true

Beta operations are open to everyone; the header is all they need. If a request to a documented endpoint returns 404, check whether the operation is beta and retry with the header.

For the full guarantees, notice periods, and how breaking changes are communicated, see the V3 Stability Guidelines.

Authentication

Authenticate exactly as you do for V2. Tokens are issued from /oauth/token, which sits at the root of your tenant and is deliberately not tied to a versioned API path, so the same token works for V2 and V3:

Endpoint
POST /oauth/token

The endpoint supports the client_credentials, authorization_code, and refresh_token grant types. Send the resulting token as a bearer token on every V3 call. For the full walkthrough of app credentials, delegated auth, and personal API keys, see Authentication.

The Python SDK

The V3 Python SDK provides typed access to the V3 API:

pip install benchling-v3-sdk-python
Python
from benchling_v3_sdk import Benchling
benchling = Benchling(
base_url="https://{tenant_name}.benchling.com",
client_id="<your-client-id>",
client_secret="<your-client-secret>",
)
for container in benchling.container.list():
print(container.id, container.name)

Pass early_access="true" to the client to call beta endpoints. See Getting Started with the V3 Python SDK for API key, client credentials, and bearer token authentication, and Common SDK Interactions and Examples for pagination, async tasks, error handling, and retries.

The V2 Python SDK is a separate package, benchling-sdk, that calls V2 endpoints. Both SDKs can be used in the same integration.

Calling V3 without the SDK

Any HTTP client works:

Python
import requests
BASE_URL = "https://{tenant_name}.benchling.com/api/v3"
access_token = "..." # obtained from POST /oauth/token
response = requests.get(
f"{BASE_URL}/container/items",
headers={
"Accept": "application/json",
"Authorization": f"Bearer {access_token}",
},
params={"sort": "modifiedAt:desc", "pageSize": 25},
timeout=30,
)
response.raise_for_status()
page = response.json()
for container in page["items"]:
print(container["id"], container["name"])

Listing endpoints

Every collection exposes an /items listing endpoint that returns a consistent envelope: an items array plus a nextToken for pagination.

In V2, listing endpoints wrap results in a key named after the resource, such as results. In V3 the key is always items, on every listing endpoint.

GET /api/v3/container/items?sort=modifiedAt:desc&pageSize=2

Every object carries a __typename, which identifies its concrete type. This matters wherever a field can hold more than one kind of object: parentStorage on a container may be a Box, Plate, or Location, and __typename is how you tell which one you received.

Pagination

Pass pageSize to control page length; it defaults to 50 and is capped at 100. Pass the nextToken from a response as the nextToken parameter of your next request to continue from where you left off.

Field selection

Listing and get endpoints accept two mutually exclusive parameters that control which top-level fields come back. Use them to cut response size when you only need a few fields:

  • returning: a comma-separated list of top-level fields to include.
  • omit: a comma-separated list of top-level fields to exclude.
Endpoint
GET /api/v3/container/items?returning=id,name,barcode

Filtering

V3 filters are typed and encode the operator in the parameter name rather than in the value, so they need no special escaping. The exact set varies by endpoint; the reference lists them per operation. Common shapes:

  • id.anyOf, name.anyOf: match any value in a comma-separated list.
  • createdAt.gt, createdAt.gte, createdAt.lt, createdAt.lte: timestamp comparisons. modifiedAt supports the same four.
  • parentStorage.eq: match a single referenced object by ID.
  • sort: createdAt or modifiedAt, with :asc or :desc. Defaults to modifiedAt:desc.

Writes

Single-object writes

Creates are a POST to the collection; updates are a PATCH to the individual resource:

Endpoint
POST /api/v3/container
PATCH /api/v3/container/con_dU8Qh1Wn

Batch and bulk writes

Write endpoints expose batch operations that act on many objects in one request, using a :action suffix on the collection:

Endpoint
POST /api/v3/container:batch-create
PATCH /api/v3/container:batch-update

Batch operations take their input inline as JSON, which makes them the right choice for most multi-object writes. Note that the method follows the operation: creates are POST, updates are PATCH. Some resources additionally support POST :batch-delete.

For data sets too large to send inline, the bulk operations POST :bulk-create and PATCH :bulk-update accept a file instead. Bulk is an asynchronous, file-based flow: upload a JSONL file of input objects through the scratch file endpoints, start the operation with that file’s ID, then poll for results:

Endpoint
GET /api/v3/tasks/bulk/{task_id}
GET /api/v3/tasks/bulk/{task_id}/successful-results
GET /api/v3/tasks/bulk/{task_id}/errors

Each line of the input file is one JSON object with a request_id you choose and an input_object shaped like the body of the resource’s single-object POST. Results and errors are keyed by your request_id. A single bulk request accepts up to 30,000 input objects or a 100 MB file, whichever is lower, and only one bulk mutation per type can run at a time. See Importing Data with the Bulk Import API for the full flow.

The same :action convention is used for operations that are neither plain creates nor updates, such as POST /api/v3/container:transfer and POST /api/v3/container/{container_id}:remove-content.

Nested listings

When a property is a list of other objects, V3 exposes it as a nested listing endpoint with the parent’s ID as a path parameter, rather than embedding the whole list in the parent response. This keeps parent payloads bounded and lets you paginate the children. For example:

Endpoint
GET /api/v3/project/{project_id}/collaborations/items
GET /api/v3/entry/{entry_id}/parts/items
GET /api/v3/aa-sequence/{aa_sequence_id}/annotations/items

Rate limits

Each V3 request draws from the calling user’s or app’s own budget and from a budget shared by the whole tenant. When a budget is exhausted, the API returns 429, sometimes with a Retry-After header saying how long to wait. See V3 Rate Limits for how budgets work and how to handle rejected requests.

What V3 adds

Beyond the platform-wide features above, some capabilities exist only in V3:

  • Collaboration and Policy APIs. Manage permissions programmatically through /collaboration and /policy, including per-project collaborations.
  • Notebook document APIs. Read and edit entry content. Currently beta; see Introduction to Documents.
  • Procedures APIs. Interact with BioProcess and Studies, including flowcharts and method execution.
  • Entity schema, results bulk write, and audit log APIs. Available as beta endpoints.
  • Bulk import and export. Write at scale from a file, or export entire data types as serialized JSON through an asynchronous task. See Bulk Import and Bulk Export.
  • V3 events. Webhook notifications for changes to V3 resources. See V3 Events. Beta.
  • Agents API. Send prompts to Benchling AI and poll for the result. See AI Agents API. Private beta.

Frequently asked questions

Can I use V2 and V3 at the same time?

Yes. Mixing the two is expected and supported, and both accept the same token. Use the highest-stability version of each endpoint you need: if an operation exists only in V3 beta, use it alongside stable V2 calls; if an operation is not in V3 yet, use V2.

Should I migrate an existing V2 integration?

There is no requirement to. V2 remains supported, and V2 endpoints are not being retired as part of the V3 rollout. Migrate when you want a specific V3 capability such as broader coverage, batch writes, or field selection, or when you are already changing the code for other reasons. Build anything new against V3.

How do I keep up with breaking changes?

Subscribe to the changelog RSS feed. Many teams pipe it into Slack or Teams with an RSS integration (Slack RSS app, Teams RSS app). Breaking changes to stable endpoints come with at least 90 days’ notice; beta endpoints can change without notice.