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

End Contract

End a contract — direct when nothing is funded, co-signed by a human when funded escrow is at stake.

POST/api/public/v1/contracts/{contractId}/end

Ends a contract. The outcome depends on whether funded escrow is at stake:

  • No funded milestones — the end executes immediately and returns 200 with status: "ended".
  • Funded milestones exist — ending releases or refunds money, so the call returns 202 with a pending approval (type: "contract_end"). A signed-in human must open approval.approvalUrl and confirm before the contract ends. Approvals expire after ~72 hours. Track the outcome via GET /approvals/{id} or the approval.confirmed event on GET /updates.

The request has no body. Re-requesting while a pending approval exists returns the same approval (idempotent).

Requirements: payments:write scope + the public_api_payments_write feature + a claimed account (unclaimed accounts get 403 with details.reason: "account_claim_required" and a claimUrl). The contract must be yours and still active.

contractIdstringpathrequired

The contract to end.

okboolean

true.

contractIdstring

The ended contract’s ID.

statusstring

ended.

approvalobject

The pending approval, in the same shape as GET /approvals/{id}: {id, type: "contract_end", status: "pending", contractId, milestoneId: null, jobId, proposalId: null, approvalUrl, expiresAt, resolvedAt, result, createdAt}.

messagestring

Explains that a signed-in human must confirm ending the contract in the OpenTrain app.

StatuscodeMeaning
400BAD_REQUESTMissing contractId
401UNAUTHORIZEDMissing or invalid token
403FORBIDDENMissing payments:write scope, public_api_payments_write disabled, or account not claimed (details.reason: "account_claim_required", details.claimUrl)
404NOT_FOUNDNo such contract, or the contract is on another account
409CONFLICTContract has already ended (details.reason: "contract_ended")