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

Create Milestone

Add an unfunded milestone to an active contract. No money moves at creation.

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

Adds a new milestone to an active contract. The milestone is created unfunded (NOT_FUNDED) — no money moves at creation. To put money behind it, request funding afterwards; a signed-in human must confirm that step (see human approvals).

The amount must fit the contract’s payment model: fixed-price contracts require amountUsd; hourly and per-label contracts require volume, and when both amountUsd and volume are given the amount must equal the contract rate × volume.

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 add the milestone to.

descriptionstringbodyrequired

Description of the work to deliver. Must be non-empty.

namestringbody

Optional short milestone name.

amountUsdnumberbody

Milestone amount in USD. Must be positive. Required for fixed-price contracts.

volumenumberbody

Unit volume (e.g. label count or hours). Must be positive. Required for hourly and per-label contracts.

dueDatestringbody

Optional due date (ISO 8601).

Returns 201 with the created milestone.

milestoneobject
milestone
idstring

Milestone ID — pass to POST /milestones/{id}/fund to request escrow funding.

namestring | null

Milestone name.

descriptionstring | null

Work to deliver.

statusstring | null

NOT_FUNDED on creation.

amountUsdnumber | null

Milestone amount in USD.

volumenumber | null

Unit volume.

milestoneNumbernumber | null

Position in the contract’s milestone sequence.

dueDatestring | null

ISO due date.

pendingApprovalboolean

false on creation.

needsReviewboolean

false on creation.

invoiceIdstring | null

null until funded.

createdAtstring

ISO creation timestamp.

StatuscodeMeaning
400BAD_REQUESTInvalid JSON, or field errors (details.field names the offender): description missing/empty, amountUsd required for fixed-price contracts, volume required for hourly and per-label contracts, or the amount does not match the contract rate and volume
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
409CONFLICTdetails.reason: "contract_ended" (contract already ended) or "contract_rate_missing" (contract has no rate to validate against)