Skip to content
OpenTrain AIOpenTrain AIOpenTrain AIDocs

Ask OpenTrain

Answers from the documentation, with sources.

What would you like to do with OpenTrain?

AI answers can be mistaken. Check the linked sources. Don’t include private account information.

Open app

DEVELOPER DOCUMENTATION

Consent and Installs

Learn how customers connect OpenTrain to your platform with consent links, scopes, PII consent, one-time tokens, reconnects, and revocation.

An install is one customer’s grant of access to your platform app: which scopes they approved, whether they consented to Work Email sharing, and the tokens minted under that grant. Every Platform API token (ot_ptk_…) belongs to exactly one install.

Send your customer (an OpenTrain employer — specifically the organization owner) to:

https://app.opentrain.ai/integrations/{partnerSlug}/connect?external_project_id=<id>&redirect_uri=<url>&state=<opaque>
Query parameterRequiredPurpose
external_project_idNoYour project identifier. Echoed back on the return redirect so you know which of your projects initiated the connection.
redirect_uriNoWhere to send the customer after consent. Must be http(s) and match a redirect URI registered for your app: same origin, and its path must start with the registered base path (so dynamic sub-paths under a registered base work).
stateNoOpaque value echoed back unchanged on the return redirect — use it to correlate the flow on your side.

On the consent screen the customer sees your app’s name, the scopes you requested, and — if you requested participants:email — a separate, explicit PII consent checkbox for Work Email sharing. They can approve or decline.

When the customer approves, OpenTrain mints an install-scoped ot_ptk_… token and displays it once, on the consent screen only. The customer copies it into your platform’s integration settings.

Your app requests a subset of these seven scopes when you register it; the customer sees each one described on the consent screen:

ScopeGrants
project-links:readRead links between your projects and OpenTrain jobs
project-links:writeCreate and remove project links (implies project-links:read)
contracts:readRead contracts (status, dates, budget) on linked jobs
participants:readRead hired participants on linked contracts: OpenTrain user ID, display name, profile URL, country
participants:emailRead the participant’s @opentrain.work Work Email. Requires the explicit PII consent checkbox at install time; personal email addresses are never shared
usage:writeReport cumulative per-day work usage (time, tasks, labels) for contracts on linked jobs
webhooks:manageCreate, list, update, and delete webhook endpoints

participants:email is double-gated: the scope must be granted and the install must have piiConsent: true. If the customer granted the scope but left the consent box unchecked, requests that would return Work Email are refused with 403 at request time — and webhook payloads simply omit the workEmail field.

GET /installs/current returns the install your token belongs to — useful as a connectivity check and to confirm which scopes and consent you actually have:

Terminal window
curl -sS https://app.opentrain.ai/api/partner/v1/installs/current \
-H "Authorization: Bearer $OT_PARTNER_TOKEN"
{
"install": {
"id": "<INSTALL_ID>",
"status": "ACTIVE",
"scopes": [
"project-links:read",
"project-links:write",
"contracts:read",
"participants:read",
"participants:email",
"webhooks:manage"
],
"piiConsent": true,
"organizationId": "<ORG_ID>",
"createdAt": "2026-06-12T10:00:00.000Z",
"partnerApp": { "id": "<APP_ID>", "slug": "your-app", "name": "Your App" },
"token": { "id": "<TOKEN_ID>", "name": "Your App connection", "scopes": ["..."] }
}
}

Beyond the right scope, every Platform API request checks four things. Any of them failing yields 401 or 403:

  1. A live token — not revoked or expired
  2. An ACTIVE install
  3. An ACTIVE platform app
  4. The annotation-platform feature enabled for the granting employer’s account

If a customer runs the consent flow again for an app they already installed, OpenTrain revokes all previous tokens for that install before minting the fresh one. A scope reduction on reconnect therefore cannot be bypassed by holding on to an older, broader token. Treat any 401 as a signal to ask the customer to reconnect.

Customers can disconnect your app at any time from their OpenTrain integrations page. Disconnecting immediately:

  1. Flips the install to REVOKED
  2. Revokes every access token — your next request returns 401
  3. Emits an install.revoked event to webhook deliveries already queued
  4. Stops all new event fan-out for that install

Handle install.revoked by ceasing work for that customer and marking the connection as disconnected in your UI.