Proposals
Hire From Proposal
Request a hire — records a pending approval a human must co-sign in the OpenTrain app before the contract is created and any money moves.
POST
Requests a hire of the candidate behind one of your proposals. This call never hires anyone or moves money. It records a pending approval (
type: "proposal_hire") and returns 202; a signed-in human must open approval.approvalUrl and confirm in the OpenTrain app. Approvals expire after ~72 hours.
When the human confirms, OpenTrain accepts the proposal, creates the contract, creates the first escrow milestone, and funds it — the milestone amount plus a 10% marketplace fee plus a $9.95 contract initiation fee (see credits & billing). The human chooses the payment source (card or credit balance) at confirm time. Funds are held, not paid out; payout happens when you approve the milestone later.
Re-requesting with the same milestone terms while a pending approval exists returns the same approval (idempotent). Re-requesting with different terms supersedes the old approval, so the human only ever sees one live hire request per proposal. Learn the outcome by polling GET /approvals/{id} or watching for the approval.confirmed event on GET /updates; once confirmed, the contract appears in GET /contracts with the post-hire job conversation. The AI trainer’s identity stays masked — first name + last initial, never an email (see privacy).
Requirements: proposals:write scope + the public_api_hiring feature + a claimed account (unclaimed accounts get 403 with details.reason: "account_claim_required" and a claimUrl) + a payment method on file or a credit balance covering the full charge (409 with details.reason: "payment_method_required" otherwise). The proposal must be on a job you own.
Request
string
required
The proposal to hire from.
object
required
The first escrow milestone for the new contract. At least one of
name or description must be non-empty.boolean
Set
true to confirm hiring a proposal you previously marked Not a fit, after receiving a 409 with details.reason: "not_fit_confirmation_required".Response
Returns202 — the request is recorded; nothing has been hired or charged yet.
object
The pending approval, in the same shape as
GET /approvals/{id}: {id, type: "proposal_hire", status: "pending", contractId: null, milestoneId: null, jobId, proposalId, approvalUrl, expiresAt, resolvedAt, result, createdAt}. contractId stays null until the human confirms and the contract is created.string
Explains that a signed-in human must confirm the approval before the freelancer is hired and any money moves.