Swagger UI openapi.json openapi.yaml
Guide

Contract Lifecycle

The ProfessionalContract status machine: from open to terminated, the three status-update endpoints, and the termination PDF attachment paths.

TL;DR

ProfessionalContract tracks the lifecycle of a professional's contract with a business. It flows from open → filling → approved → termination_requested → terminated. The termination PDF can be attached at different points depending on your workflow.
open
filling
approved
termination_requested
terminated

Status machine

A contract moves through these statuses:

open

Contract created, not yet filled. The professional hasn't started completing it.

filling

Contract is being filled by the professional. Digital signature pending.

in_approval

Contract submitted for approval. Waiting for the business to approve.

approved

Contract is active and valid. This is the steady state.

termination_requested

Termination has been requested. Waiting for the distrato PDF to be attached.

terminated

Contract is ended. The termination PDF is attached and the contract is closed.

Endpoints

MethodPathPurpose
GET/professional-contractsList all contracts for the current business.
POST/professional-contractsCreate a new contract.
GET/professional-contracts/{id}Get a single contract.
PATCH/professional-contracts/{id}Update contract data (mutable fields only).
PATCH/professional-contracts/{id}/update-statusTransition contract status. Supports termination PDF attachment.
PATCH/professional-contracts/update-statusBody-based variant — contract id in the request body.
PATCH/professional-contracts/{id}/in-approvalDeprecated — transition to in_approval status.
PATCH/professional-contracts/{id}/cancellation-requestDeprecated — request contract cancellation.
DELETE/professional-contracts/{id}Deprecated — soft-delete a contract.

Lifecycle flow

Creating a contract

A contract is typically created via a BusinessRequest (new_contract or new_contract_pdf). The system creates the contract and links it to the request.

Status transitions

1

open → filling

The professional starts filling the contract. Automatic transition when the contract data is partially submitted.

2

filling → in_approval

Contract is submitted for approval. The business reviews and approves or rejects.

3

in_approval → approved

Business approves the contract. The contract is now active.

4

approved → termination_requested

Termination is requested via BusinessRequest (terminate_contract) or direct status update. The contract enters the termination flow.

5

termination_requested → terminated

The distrato PDF is attached and the contract is terminated. The column is locked once set.

Termination PDF attachment paths

The distrato PDF can be attached in three ways:

  • On create with data.pdf_url — contract goes directly from approved → terminated (skips termination_requested). Use when the signed PDF is already available.
  • On status update to closed — pass a top-level termination_pdf_url in the status-update payload. The URL is written after the contract transitions to terminated.
  • On direct contract status update to terminated — pass termination_pdf_url in the payload. Same lock + precondition rules apply.
Locked once set. Any attempt to overwrite an existing termination_pdf_url errors with 422 TerminationPdfUrlAlreadySet.

Gotchas

  • The deprecated /in-approval and /cancellation-request endpoints should not be used for new integrations.
  • The body-based /professional-contracts/update-status requires contract_id in the request body.
  • The data JSON field on a BusinessRequest is immutable past draft/open status.
  • Termination PDF paths write only to the contract column, not to the BusinessRequest data.