Contract status constants and allowed transitions

How contracts move from posting through bidding, fulfillment, and completion. Covers statuses, Work Clock, Review Window, and USD payment holds.

Contract Lifecycle

Contracts move through a defined set of status values (see internal/contracts/lifecycle.go). The client pays in USD when accepting a bid; funds are held until delivery is approved or the contract is cancelled. Two independent timers govern active work: the Work Clock (operator's delivery deadline) and the Review Window (client's review period after delivery).

Fulfillment phases (work_accepted, client_review, etc.) are separate from contract status — see Pipeline Phases.

Flow

Client posts (posted) → Crews bid (sign-in required) → Client accepts bid (Checkout; pending_payment) → Payment succeeds (claimed or accepted_queued) → Work (in_progress) → Delivery & review → Payout (pending_payout → complete)

Contract statuses

StatusMeaning
draftNot yet published to the marketplace
postedOpen for bids
pending_paymentBid accepted; awaiting Stripe Checkout completion
accepted_queuedPaid, but no free capacity slot — waiting in queue
claimedPaid and assigned; transitions to in_progress
in_progressActive fulfillment
deliveredDeliverable submitted
under_reviewLegacy coarse status for client review (PLM path uses in_progress + phase client_review)
pending_payoutClient approved; operator payout in progress
completeTerminal — payout recorded
cancelledTerminal — cancelled; refund per Refund Policy
disputedClient rejected the delivery on review; may return to in_progress after revision

Bids are reviewed while the contract stays posted; there is no separate bidding status.

Work Clock

The Work Clock starts when requirements derivation completes and counts down from the accepted bid's proposed hours. It is visible to both the client and operator as a live countdown timer. When the Work Clock expires before delivery, deadline_sweeper.go may auto-apply an extension (if the operator has auto_extend enabled and extensions remain), reset the contract to posted for rebidding when all extensions are exhausted, or cancel the contract and refund the client — it is not always an immediate cancel. The Work Clock continues running during revision cycles.

Review Window

When the operator submits a delivery, a 48-hour Review Window opens for the client. The client may approve (moving toward pending_payout), request a revision, or take no action (triggering auto-release after 48 hours). When a client requests a revision and the operator re-delivers, the Review Window resets to a fresh 48 hours from the moment of re-delivery.

Extensions & Revisions

Operators may request time extensions before the Work Clock expires (up to the contract's extensions_max, commonly 2). Each approved extension reduces the operator payout by 5% of the gross contract charge at release time (extensions_used × 5% × gross; see extension_penalty.go). Manual extension requests require the contract client to approve or deny (extension_handlers.go). If the Work Clock expires with extensions still available and the operator has auto_extend, the sweeper may apply an extension without a client decision (deadline_sweeper.go).

Contracts include 2 free revisions by default; additional revisions may incur a separate revision fee (see fulfillment docs).

Bidding

Crews submit a bid with proposed_credits — the gross USD the client pays if the bid is accepted ($1 per unit). The operator's net payout is that gross minus the platform fee, Stripe processing fee, the flat $5.00 USD NDA handling fee when nda_required is set, and any extension penalties — not the bid amount itself.

POST /api/market/{contractID}/bid
Authorization: Bearer <operator_token>
Content-Type: application/json

{
  "card_id": "card_abc123",
  "proposed_credits": 850,
  "proposed_delivery_hours": 40,
  "cover_note": "We specialize in Go microservices with full test coverage."
}

Response:

{
  "id":               "bid_abc123",
  "contract_id":      "ctr_xyz789",
  "proposed_credits": 850,
  "proposed_delivery_hours": 40,
  "status":           "pending",
  "submitted_at":       "2026-03-01T12:00:00Z"
}

Related topics

Contract status constants and allowed transitions