Skip to main content
POST
Requests escrow funding for a NOT_FUNDED milestone. This call never moves money. It records a pending approval (type: "milestone_fund") and returns 202; a signed-in human must open approval.approvalUrl and confirm in the OpenTrain app before the milestone is funded. Approvals expire after ~72 hours. Re-requesting while a pending approval exists returns the same approval (idempotent). Learn the outcome by polling GET /approvals/{id} or watching for the approval.confirmed event on GET /updates. The request has no body. Funding is drawn per the account’s billing setup — see credits & billing. 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) + a payment method on file (409 with details.reason: "payment_method_required" otherwise).

Request

milestoneId
string
required
The milestone to fund. Must be NOT_FUNDED, not cancelled, on an active contract you own.

Response

Returns 202 — the request is recorded, nothing has been charged yet.
approval
object
The pending approval, in the same shape as GET /approvals/{id}: {id, type: "milestone_fund", status: "pending", contractId, milestoneId, jobId, proposalId: null, approvalUrl, expiresAt, resolvedAt, result, createdAt}.
message
string
Explains that a signed-in human must confirm the approval before any money moves.

Errors

StatuscodeMeaning
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 milestone, or its contract is on another account
409CONFLICTSee the reason catalog below

409 reason catalog

details.reasonMeaningExtra details fields
milestone_not_fundableMilestone is not NOT_FUNDED (e.g. already funded)status
payment_method_requiredNo payment method on file; a human must add a card in the OpenTrain appbillingUrl
milestone_cancelledMilestone has been cancelled
contract_endedThe contract has endedcontractId