Skip to main content
POST
/
api
/
partner
/
v1
/
project-links
curl -sS -X POST https://app.opentrain.ai/api/partner/v1/project-links \
  -H "Authorization: Bearer $OT_PARTNER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "externalProjectId": "42",
    "externalProjectName": "Traffic signs batch 3",
    "externalProjectUrl": "https://your-platform.example.com/projects/42",
    "jobId": "<OPENTRAIN_JOB_ID>",
    "provisioningMode": "PARTNER_WEBHOOK"
  }'
{
  "projectLink": {
    "id": "<LINK_ID>",
    "jobId": "<OPENTRAIN_JOB_ID>",
    "externalProjectId": "42",
    "externalProjectName": "Traffic signs batch 3",
    "externalProjectUrl": "https://your-platform.example.com/projects/42",
    "provisioningMode": "PARTNER_WEBHOOK",
    "createdAt": "2026-06-12T10:00:00.000Z"
  }
}
Creates a project link mapping one of your projects to an OpenTrain job. Contract lifecycle events are emitted only for linked jobs, so this is the routing step of the integration. Emits a project_link.created event. Requirements: project-links:write scope.

Request

externalProjectId
string
required
Your project’s identifier (max 200 chars). Unique per install — reusing one returns 409.
externalProjectName
string
Human-readable project name (max 300 chars).
externalProjectUrl
string
Deep link to the project in your platform (max 2048 chars).
jobId
string
The OpenTrain job to link. Must be a job owned by the installing employer — anything else returns 404. A link without a job receives no contract events until it points at one.
provisioningMode
string
default:"PARTNER_WEBHOOK"
PARTNER_WEBHOOK (you provision workspace members from webhook events — recommended) or MANAGED_ADAPTER (the OpenTrain managed-credential path). See provisioning modes.

Response

The created link: {id, jobId, externalProjectId, externalProjectName, externalProjectUrl, provisioningMode, createdAt}.

Errors

StatuscodeMeaning
400BAD_REQUESTBody not valid JSON, externalProjectId missing, or a field exceeds its length limit
401UNAUTHORIZEDMissing, invalid, or revoked token
403FORBIDDENToken lacks project-links:write
404NOT_FOUNDjobId does not reference a job owned by the installing employer
409CONFLICTDuplicate externalProjectId for this install, or the install’s link limit is reached
curl -sS -X POST https://app.opentrain.ai/api/partner/v1/project-links \
  -H "Authorization: Bearer $OT_PARTNER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "externalProjectId": "42",
    "externalProjectName": "Traffic signs batch 3",
    "externalProjectUrl": "https://your-platform.example.com/projects/42",
    "jobId": "<OPENTRAIN_JOB_ID>",
    "provisioningMode": "PARTNER_WEBHOOK"
  }'
{
  "projectLink": {
    "id": "<LINK_ID>",
    "jobId": "<OPENTRAIN_JOB_ID>",
    "externalProjectId": "42",
    "externalProjectName": "Traffic signs batch 3",
    "externalProjectUrl": "https://your-platform.example.com/projects/42",
    "provisioningMode": "PARTNER_WEBHOOK",
    "createdAt": "2026-06-12T10:00:00.000Z"
  }
}