Transition the engagement state
Módulo Opportunities
POST/engagements/{id}/transitionsengagements.transition
Moves the engagement state machine through its transition RPC, which writes its ledger. Active is refused until every blocking onboarding item passes. Complete narrows external access to money and documents. Requires `Idempotency-Key`; a replay returns the original response. A rule that refuses the request returns 422 with `refusal` and `reason`.
- Requiere la capacidad opportunities.engagement.write.
- Alcances de OAuth: opportunities.
- Envía el encabezado Idempotency-Key. Una repetición con la misma clave devuelve la respuesta original.
- Estados de error: 400, 401, 404, 409, 422, 429. Los errores son detalles de problema RFC 9457.
Parámetros de ruta y de consulta
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| id | string (uuid) | Sí | Identifier of the engagement. |
Cuerpo de la solicitud: EngagementTransitionRequest
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| expected_state | "Onboarding" | "Blocked" | "Active" | "Closing" | "Complete" | "Canceled" | Sí | The state the caller believes the row is in (compare-and-set). |
| to_state | "Onboarding" | "Blocked" | "Active" | "Closing" | "Complete" | "Canceled" | Sí | Target state. |
| reason | string | No | Reason, required by some transitions.Restricciones: length 1 to any |
{
"expected_state": "Onboarding",
"to_state": "Active",
"reason": "Client approved the revised scope."
}Respuesta 200: Engagement
| Campo | Tipo | Obligatorio | Descripción |
|---|---|---|---|
| id | string (uuid) | Sí | Identifier of the engagement. |
| org_id | string (uuid) | Sí | Identifier of the owning organization, derived from the parent row and never accepted from the caller. |
| created_at | string (date-time) | Sí | When the row was created. |
| created_by | string (uuid) | null | Sí | Identifier of the person who created the row; null when a seed, platform or system process created it. |
| updated_at | string (date-time) | Sí | When the row was last updated. |
| updated_by | string (uuid) | null | Sí | Identifier of the person who last updated the row; null when a seed, platform or system process updated it. |
| person_id | string (uuid) | null | Sí | Identifier of the engaged person. |
| organization_id | string (uuid) | null | Sí | Identifier of the engaged external account. |
| project_id | string (uuid) | null | Sí | Identifier of the project. |
| offer_id | string (uuid) | null | Sí | Identifier of the accepted offer. |
| role_type | ExternalRoleType | Sí | External role type (Section 4.4.2).Restricciones: one of "Client", "Vendor", "Contractor", "Crew", "Staff", "Artist", "Artist Representative", "Sponsor" |
| engagement_state | EngagementState | Sí | Engagement lifecycle state. Active requires every blocking onboarding item to pass.Restricciones: one of "Onboarding", "Blocked", "Active", "Closing", "Complete", "Canceled" |
| activated_at | string (date-time) | null | Sí | When it became Active. |
| completed_at | string (date-time) | null | Sí | When it became Complete. |
| application_id | string (uuid) | null | Sí | Identifier of the accepted application the engagement came from. |
| worker_classification | string | null | Sí | Worker classification, from xpms.worker_classification; null for Client and Sponsor engagements.Restricciones: pattern ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ |
| pay_basis | string | null | Sí | Pay basis; with the arrangement a permitted canon pair.Restricciones: length 1 to 300 |
| arrangement | string | null | Sí | Arrangement; with the pay basis a permitted canon pair.Restricciones: length 1 to 300 |
| start_date | string (date) | Sí | First day of the engagement; defaults to the offer's or the opportunity's. |
| end_date | string (date) | null | Sí | Last day of the engagement; defaults to the offer's or the opportunity's. |
| counterparty_id | string (uuid) | null | Sí | Identifier of the counterparty (vendor) the holder is engaged through; null when direct. |
{
"id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"org_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"created_at": "2026-10-08T14:30:00Z",
"created_by": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"updated_at": "2026-10-08T14:30:00Z",
"updated_by": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"person_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"organization_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"project_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"offer_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"role_type": "Crew",
"engagement_state": "Onboarding",
"activated_at": "2026-10-08T14:30:00Z",
"completed_at": "2026-10-08T14:30:00Z",
"application_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f",
"worker_classification": "INDEPENDENT_CONTRACTOR",
"pay_basis": "Day Rate",
"arrangement": "Per Engagement",
"start_date": "2026-10-08",
"end_date": "2026-10-08",
"counterparty_id": "0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f"
}Ejemplos de código
curl -X POST "$XOS_BASE_URL/engagements/0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f/transitions" \
-H "Authorization: Bearer $XOS_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"expected_state":"Onboarding","to_state":"Active","reason":"Client approved the revised scope."}'const { data } = await xos.engagements.transition("0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f", {
"expected_state": "Onboarding",
"to_state": "Active",
"reason": "Client approved the revised scope."
});response = xos.engagements.transition("0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f", {"expected_state": "Onboarding", "to_state": "Active", "reason": "Client approved the revised scope."})xos engagements transition 0192f1e2-7c3a-7b4d-9e8f-1a2b3c4d5e6f --data '{"expected_state":"Onboarding","to_state":"Active","reason":"Client approved the revised scope."}'