Overview
What is M2M Integration?
Machine-to-Machine (M2M) integration lets your backend systems call Trialbee
APIs without a human user session. Authentication uses the OAuth 2.0
Client Credentials flow: your service exchanges a clientId + clientSecret
for a short-lived JWT access token, and uses that token as a Bearer credential
on each API request.
When to use M2M
Use M2M integration when you need to:
- Read or write Trialbee data from a backend service or scheduled job.
- Integrate a CRM, ETL pipeline, or analytics system with Trialbee.
- Build customer-side automation that doesn't involve a human signed in.
What you receive from Trialbee
Your Trialbee Project Manager provisions an OAuth client for your integration and shares the following over a secure channel:
| Item | Description |
|---|---|
clientId | Public identifier for your OAuth client. |
clientSecret | Secret credential. Treat it like a password — store it securely. If lost, contact Trialbee for rotation. |
| API endpoint | The omniapi GraphQL URL for the target environment (see Calling the API below). |
| Token endpoint | The Trialbee OAuth token endpoint URL for the target environment (see Authentication below). |
| Configured permissions | A summary of the actions you can perform and the studies / sites the integration is scoped to. |
| OAuth scope (if required) | Use the scope value provided by Trialbee, if required. |
Authentication
Your service exchanges the clientId + clientSecret for a JWT using the
OAuth 2.0 Client Credentials grant. Most API clients (Bruno, Insomnia,
Postman, …) support this flow natively under the request's Auth tab —
choose OAuth 2.0 → Client Credentials and the client will fetch the
token for you.
Token request parameters
| Field | Value |
|---|---|
| Grant type | client_credentials |
| Token endpoint | provided by Trialbee per environment |
| Client ID | from the credentials Trialbee shared with you |
| Client Secret | from the credentials Trialbee shared with you |
| Scope | use the scope value provided by Trialbee, if required |
| Credentials placement | request body |
cURL example
curl --request POST \
--url 'https://<token-endpoint>/oauth2/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'grant_type=client_credentials' \
--data 'client_id=<clientId>' \
--data 'client_secret=<clientSecret>'
Response:
{
"access_token": "<jwt>",
"expires_in": 3600,
"token_type": "Bearer"
}
Include the returned token on every API request:
Authorization: Bearer <jwt>
The token is valid for the duration returned in expires_in. Most API
clients handle token reuse automatically.
Calling the API
Send GraphQL requests to the omniapi endpoint for your target environment:
| Environment | URL |
|---|---|
| Stage | https://omniapi.stage.trialbee.xyz/graphql/v1 |
| Prod | Provided by Trialbee |
Sample request
The example below uses the Dev endpoint. Replace it with the endpoint provided by Trialbee for your environment.
curl --request POST \
--url 'https://omniapi.stage.trialbee.xyz/graphql/v1' \
--header 'Authorization: Bearer <jwt>' \
--header 'Content-Type: application/json' \
--data '{
"query": "query GetStudy($id: ID!) { study(id: $id) { id studyName status } }",
"variables": { "id": "study_001" }
}'
Variables
{ "id": "study_001" }
Example response
{
"data": {
"study": {
"id": "study_001",
"studyName": "Example Study",
"status": "ACTIVE"
}
}
}
Permissions and scope
Your OAuth client's access is constrained by two things Trialbee provisions for you:
- Policies — what actions the client can perform (e.g. read studies, list candidates).
- Scope — where those actions apply (which studies, sites, referrers).
Both are configured by your Trialbee Project Manager based on the integration agreement. You don't manage them yourself; they're communicated to you when the credential is shared.
V1 does not support partial permissions. If a single field in your GraphQL request requires an action or scope that isn't permitted, the entire request fails — there is no partial response.
Only request fields covered by your assigned policies and scope. If you need access to additional fields or studies, contact your Project Manager to extend your client's permissions.
Error behaviour
The API surfaces failures in two ways:
- HTTP-level — when the gateway can't accept your request:
401— the JWT is missing, malformed, or expired. Refetch a token and retry.
- GraphQL-level — returned in the response body alongside HTTP
200:- The request requires an action or scope your client doesn't have (see Permissions and scope).
- The request is otherwise rejected by Trialbee's authorization layer.
Always inspect both the HTTP status code and the GraphQL errors array
when handling responses.