Authentication
Learn which authentication methods the Benchling API supports for apps and automation, and when to use each one. This page covers app credentials, Delegated Auth, personal API keys, and the setup details needed to make secure requests to Benchling.
📘 Protecting your API credentialsKeep API credentials in a password manager or your organization's secrets manager. Never commit API keys or client secrets to source control — use environment variables or a secrets management service instead. If you leak a key, rotate it immediately: personal API keys can be rotated in Profile Settings; app client secrets can be rotated in the Developer Console.
Authentication Methods
This page covers authenticating to the Benchling public API. It does not cover how people sign in to the Benchling web application — username and password, SAML, and Google OAuth are configured by tenant administrators and are not covered here.
Every API call is tied to a user or an app. Anything a user can do in the Benchling UI, their API key can do via the API; apps follow the same model, and an app's OAuth token can do anything the app has been permissioned to do.
Benchling supports four API authentication methods. Jump to Which one should I use? if you want a quick recommendation.
| Method | Best for |
|---|---|
| OAuth Bearer (App credentials) | Apps and automation acting as themselves |
| Delegated Auth | Apps acting on behalf of the currently signed-in user |
| Basic Auth (API key) | Generally discouraged; available for temporary uses like trying out a new API |
| OIDC | Legacy — existing implementations only |
OAuth Bearer Authentication (App Credentials)
Benchling Apps authenticate using the OAuth 2.0 client credentials grant type. Request a token with your app's client ID and secret, then send it as a Bearer token on every subsequent call.
1. Request an access token
curl -X POST "https://{tenant_name}.benchling.com/oauth/token" \
-H "accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&\
client_id={client_id}&\
client_secret={client_secret}"from benchling_sdk.auth.client_credentials_oauth2 import ClientCredentialsOAuth2
from benchling_sdk.benchling import Benchling
auth_method = ClientCredentialsOAuth2(
client_id="{client_id}",
client_secret="{client_secret}",
)
benchling = Benchling(url="https://{tenant_name}.benchling.com", auth_method=auth_method)
# No explicit token request: the SDK fetches one on your first API callResponse from the raw endpoint:
{
"token_type": "Bearer",
"access_token": "<string>",
"expires_in": 900
}2. Use the access token
Send the access_token in the Authorization header on all subsequent calls:
curl -X GET "https://{tenant_name}.benchling.com/api/v3/entry/items?pageSize=5&sort=modifiedAt%3Adesc" \
-H "accept: application/json" \
-H "Authorization: Bearer {access_token}"curl -X GET "https://{tenant_name}.benchling.com/api/v2/entries?pageSize=5&sort=modifiedAt%3Adesc" \
-H "accept: application/json" \
-H "Authorization: Bearer {access_token}"from benchling_sdk.models import ListEntriesSort
# The SDK sets the Authorization header for you
exampleEntries = benchling.entries.list_entries(
sort=ListEntriesSort.MODIFIEDATDESC,
page_size=5,
)
print(next(exampleEntries)) # prints the first pageThe same token works against both API versions. Use V3 for new development; the Python SDK currently targets V2.
3. Request a new token when it expires
Access tokens expire after 15 minutes (expires_in, in seconds). The client credentials grant type does not issue a refresh token — request a new access token the same way as step 1.
The Python SDK handles token acquisition and refresh automatically. It defaults to /api/v2/token, which continues to work, but it accepts a token_url — pass /oauth/token so your integration isn't tied to a versioned path, as the app guides do. For a longer walkthrough, see Getting Started with Benchling Apps.
When to use app credentials:
- The app should act as itself, with its own identity and its own permissions. Actions should be attributed to the app in audit logs and
createdByfields - No user is present — scheduled syncs, background jobs, webhook handlers
When not to use app credentials:
- Actions should reflect the permissions of the signed-in user, or be attributed to that user in audit logs. Use Delegated Auth instead.
Managing app access
By default a new app has no access to any data. Grant access by adding the app to the relevant organizations, teams, and projects. See Granting an App Access.
Archiving an app immediately revokes its API access. Unarchiving restores access without needing to regenerate the client secret.
Apps are not tied to users and are not suspended when a user is, so if a suspended user had access to an app's client secret, rotate the secret in the Developer Console.
Delegated Auth (OAuth 2.0 Authorization Code Flow)
Delegated Auth allows a Benchling App to act on behalf of the user who is currently interacting with it. When a user authorizes your app, the app receives an access token scoped to that user's permissions. Actions taken by the app are attributed to the user in audit logs and createdBy fields, and the user's permission scope determines what the app can access — not the app's own permissions.
When to use Delegated Auth:
-
Your integration needs to reflect individual user permissions (e.g. a user can only access their own projects). Audit logs and
createdByfields should show the actual user rather than the app itself. -
You're building a user-facing external tool that connects to Benchling on behalf of the signed-in user — for example, a data entry app or equipment scheduling tool.
When not to use Delegated Auth:
- Headless bulk sync or background processes with no user interaction — the user needs to be present to complete the authorization flow. Use app credentials instead. You need the integration to access data the current user can't access, and you're comfortable enforcing appropriate user access within your app instead
How to configure an app for Delegated Auth
Delegated Auth requires a Benchling App created with the new (non-legacy) app format. Apps created from a manifest after May 2024 on continuous release tenants use the new format automatically.
1. Add redirect URIs to your app
In the Developer Console, navigate to your app's settings and add one or more redirect URIs — the URLs Benchling will redirect to after a user authorizes your app. For local development, http://localhost:{port} is permitted. All production redirect URIs must be HTTPS.
2. Direct the user to the authorization URL
Start the authorization flow by directing the user to the Benchling authorization endpoint. We recommend a "Sign in with Benchling" button in your app's UI to initiate this:
https://{tenant_name}.benchling.com/oauth/authorize?
client_id={client_id}&
redirect_uri={redirect_uri}&
response_type=code&
state={optional_state_value}This prompts the user to sign in (if not already) and consent to your app acting on their behalf. If the user already has an active Benchling session and has previously consented to your app, this step is invisible to them.
state is strongly recommended: generate a cryptographically random value tied to the user's session and verify it on return to prevent CSRF. Benchling returns it unchanged on the redirect, so you can also use it to carry opaque app state you need when the user comes back.
3. Exchange the authorization code for an access token
After the user consents, Benchling redirects to your redirect_uri with a code parameter. Exchange it for an access token:
curl -X POST "https://{tenant_name}.benchling.com/oauth/token" \
-H "accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code&\
client_id={client_id}&\
client_secret={client_secret}&\
redirect_uri={redirect_uri}&\
code={authorization_code}"Response:
{
"token_type": "Bearer",
"access_token": "<string>",
"expires_in": 900,
"refresh_token": "<string>",
"refresh_token_expires_in": 2592000
}Access tokens expire after 15 minutes (expires_in, in seconds). Rather than sending the user back through the authorization flow, have your app exchange the refresh_token for a new access token, as described in step 5. No user has to be present for that exchange, but it is not automatic — your app has to make the call itself.
4. Use the access token
Use the access_token in the Authorization header exactly as you would an app credential token:
curl -X GET "https://{tenant_name}.benchling.com/api/v3/entry/items?pageSize=5&sort=modifiedAt%3Adesc" \
-H "accept: application/json" \
-H "Authorization: Bearer {access_token}"Since each token represents a single Benchling user, store it in a way that associates it with that specific user — for example, in the user's session. Never use a token obtained for one user to make calls on behalf of another.
5. Refresh the access token before it expires
Access tokens last 15 minutes, so a long-lived session needs to refresh rather than re-prompt. Exchange the refresh_token from step 3 for a new access token using the refresh_token grant type:
curl -X POST "https://{tenant_name}.benchling.com/oauth/token" \
-H "accept: application/json" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token&\
client_id={client_id}&\
client_secret={client_secret}&\
refresh_token={refresh_token}"The response has the same shape as step 3, including a new refresh_token. Refresh tokens are single-use: each refresh invalidates the token you just sent and issues a replacement, so always persist the new one. Reusing a spent refresh token returns invalid_grant.
Refresh tokens are valid for 30 days (refresh_token_expires_in, in seconds). Because each refresh issues a fresh 30-day token, a session that refreshes regularly continues without further user interaction. Send the user back through the authorization flow only if the refresh token has expired or been invalidated — for example, after 30 days of inactivity, or if the app was uninstalled.
Using Delegated Auth with App Canvas
There is no built-in way to generate a delegated auth token directly from a canvas interaction. However, apps can work around this by managing the authorization flow outside the canvas:
1. When rendering the initial canvas, check if you have a valid access token for the current user (identified by userId in the webhook payload). If so, proceed normally.
2. If no token exists, render the canvas with a link to your app's authorization endpoint. Include the userId and the resource ID from the canvas payload in the state parameter (encrypted), so you can associate the resulting token with the correct user.
3. The user clicks the link and completes the consent flow, and Benchling redirects to your redirect URI with the authorization code.
4. Store the resulting access token server-side, associated with that user's ID.
5. Redirect the user back to https://{tenant}.benchling.com/editor to return them to where they started.
6. For subsequent canvas interactions, use the stored user access token for API calls that should reflect the user's permissions and be attributed to the user. Continue using app credentials for canvas update calls (POST/PATCH canvas).
This flow requires the user to leave the page and return during initial authorization. Benchling plans to add native support for delegated auth in canvas experiences in the future.
Suspended users
If a user is suspended in Benchling, the access tokens and refresh tokens issued for them stop working. Suspending a user in your IdP does not automatically suspend them in Benchling — you must suspend them explicitly in the Benchling admin console.
Known Limitations
- No SDK support. The Python SDK currently only supports the client credentials flow. Implement the authorization code flow in your app layer and pass the resulting access token to API calls directly — including the step 5 refresh exchange, which you have to manage yourself. Note the contrast with client credentials, where the SDK does renew tokens on its own, requesting a new one whenever the current one is close to expiring. Benchling plans to handle delegated auth tokens the same way once the SDK supports the flow; until then, trade in refresh tokens explicitly.
- No consent revocation UI. There is no interface for admins to view or revoke which users have consented to an app. To prevent an app from acting on behalf of users who have already consented, uninstall the app from the tenant. If the app is reinstalled, users will need to re-consent.
Basic Authentication (Personal API Key)
Personal API requests are authenticated with HTTP Basic auth. Use your API key as the username with an empty password:
curl -u sk_YOUR_API_KEY: https://{tenant_name}.benchling.com/api/v3/plate/items
# The colon after the key indicates an empty passwordAPI keys are tied to the user who generated them — calls made with an API key are attributed to that user in audit logs. Generate or rotate your API key in Profile Settings.
API keys created after August 7, 2026 expire 30 days after they are created. API keys created before that date do not expire.
If a user is suspended in Benchling, their API key stops working. Suspending a user in your IdP does not automatically suspend them in Benchling — you must suspend them explicitly in the Benchling admin console. Un-suspending a user restores their API key without needing to regenerate it, though the Warehouse does require un-suspended users to generate a new Warehouse login.
OpenID Connect (OIDC)
OIDC is a legacy authentication methodIt remains fully supported and Benchling has no current plans to remove it, but no active investment is being made in it. For new implementations, use Delegated Auth instead — it covers the same scenarios in a more modern and complete way.
OIDC allows your integration to authenticate to Benchling using tokens issued by an external identity provider (IdP) such as Okta or Azure Active Directory. The Benchling API verifies the token signature against your IdP's OpenID configuration endpoint and authenticates the request as the user associated with the token's email claim.
curl -H "Authorization: Bearer YOUR_ID_TOKEN" \
https://{tenant_name}.benchling.com/api/v3/plate/itemsRequirements:
An external IdP that supports OpenID Connect (Okta and Azure Active Directory are confirmed to work) The IdP must include email as a claim in the token
The user must already exist in Benchling — in most cases this means signing in to the Benchling web app at least once before making API calls OIDC setup requires Benchling Support — contact [email protected] to get started
Migrating from OIDC to Delegated Auth
The scenarios OIDC supports are fully covered by Delegated Auth. The technologies don't map 1:1, but the use cases do. OIDC will remain supported with significant advance notice before any removal. To migrate, reach out to your account team for guidance.
Which One Should I Use?
Should the app act as itself, with its own identity and permissions? → OAuth Bearer (App credentials).
Building a user-facing tool where actions should reflect individual user permissions and appear in audit logs under that user? → Delegated Auth.
Running a quick one-off script or personal test? → Basic Auth, though app credentials are the better long-term choice.
Already using OIDC? → Keep it for now; migrate to Delegated Auth when it makes sense for your team.
Warehouse Authentication
The Benchling Warehouse does not use these authentication methods. See Overview & Getting started for how to connect to it.
Updated about 10 hours ago
