ImportOS · Docs
API reference

POST /v1/deals/{id}/stage

Move a deal to another stage

Move a deal to another stage

Applies the transition through the deal state machine (required fields, automatic tasks, client notifications and the stage_changed event for webhooks). A blocked transition is 409 transition_blocked with missing[]. With dry_run=true nothing is changed and the response says what is missing and shows the client message preview. Supports Idempotency-Key. The key acts with the manager role: stages reserved for other roles (e.g. accountant, logistics) are blocked. Requires scope write:deals.

  • Authentication: header Authorization: Bearer rv_live_... (API keys and scopes)
  • Required scope: write:deals
Descriptions of the operation, parameters and fields come from the OpenAPI specification (openapi.json).

Parameters

FieldInTypeRequiredDescription
idpathstring (uuid)yesResource id (UUID).
dry_runquery"true" | "false"notrue: do not change anything, return what is missing and the client message preview (always 200).
idempotency-keyheaderstringnoMakes a retry of this POST safe for 24 hours: the same key and body returns the stored response (Idempotent-Replay: true).

Request body

FieldTypeRequiredDescription
notestring | nullno
fieldsobjectno
fields.vehicleobjectno
fields.vehicle.vinstring | nullno
fields.vehicle.makestring | nullno
fields.vehicle.modelstring | nullno
fields.vehicle.trimstring | nullno
fields.vehicle.yearinteger | nullno
fields.vehicle.body"sedan" | "hatchback" | "wagon" | "suv" | "crossover" | "coupe" | "convertible" | "minivan" | "van" | "pickup" | "truck" | "motorcycle" | "other" | nullno
fields.vehicle.fuel"petrol" | "diesel" | "hybrid" | "phev" | "ev" | "lpg" | "cng" | "hydrogen" | "other" | nullno
fields.vehicle.enginestring | nullno
fields.vehicle.engineCcinteger | nullno
fields.vehicle.powerKwinteger | nullno
fields.vehicle.gearbox"manual" | "automatic" | "cvt" | "robot" | "other" | nullno
fields.vehicle.mileageKminteger | nullno
fields.vehicle.colorstring | nullno
fields.vehicle.sourcestringno
fields.vehicle.sourceUrlstring | null (uri)no
fields.vehicle.lotIdstring | nullno
fields.vehicle.titleStatus"clean" | "salvage" | "rebuilt" | "flood" | "junk" | "parts_only" | "certificate" | "unknown" | nullno
fields.itemsobject[]no
fields.items[].idstring (uuid)no
fields.items[].kind"lot_price" | "auction_fee" | "broker_fee" | "inland_us" | "ocean" | "port" | "inland_eu" | "customs_duty" | "excise" | "vat" | "broker_customs" | "certification" | "pension_fund" | "registration" | "repair" | "detailing" | "insurance" | "our_fee" | "other"no
fields.items[].labelstring | nullno
fields.items[].plannednumber | string | nullno
fields.items[].actualnumber | string | nullno
fields.items[].currency"UAH" | "USD" | "EUR" | "PLN" | "GEL"no
fields.items[].paidBy"client" | "company"no
fields.items[].paidAtstring | null (date-time)no
fields.items[].documentIdstring | null (uuid)no
fields.items[].notestring | nullno
fields.items[].sortintegerno
fields.shipmentobjectno
fields.shipment.mode"container" | "roro" | "truck"no
fields.shipment.carrierstring | nullno
fields.shipment.containerNostring | nullno
fields.shipment.billOfLadingstring | nullno
fields.shipment.bookingNostring | nullno
fields.shipment.vesselstring | nullno
fields.shipment.voyagestring | nullno
fields.shipment.portFromstring | nullno
fields.shipment.portTostring | nullno
fields.shipment.warehousestring | nullno
fields.shipment.etdstring | null (date-time)no
fields.shipment.etastring | null (date-time)no
fields.shipment.atdstring | null (date-time)no
fields.shipment.atastring | null (date-time)no
fields.shipment.pickupAtstring | null (date-time)no
fields.shipment.deliveredAtstring | null (date-time)no
fields.shipment.status"planned" | "booked" | "loaded" | "in_transit" | "at_port" | "discharged" | "released" | "delivered"no
fields.customsobjectno
fields.customs.status"draft" | "documents_sent" | "declared" | "paid" | "cleared" | "rejected"no
fields.customs.declarantstring | nullno
fields.customs.declarationNostring | nullno
fields.customs.dutynumber | string | nullno
fields.customs.excisenumber | string | nullno
fields.customs.vatnumber | string | nullno
fields.customs.pensionFundnumber | string | nullno
fields.customs.currency"UAH" | "USD" | "EUR" | "PLN" | "GEL"no
fields.customs.paidAtstring | null (date-time)no
fields.customs.clearedAtstring | null (date-time)no
fields.customs.notesstring | nullno
fields.etaDeliverystring | null (date-time)no
fields.route"sea" | "land"no
fields.destinationCountrystring | nullno
fields.destinationCitystring | nullno
fields.lostReasonstring | nullno
attachmentsstring (uuid)[]no
notifyClientbooleanno
messageOverridestring | nullno
channel"telegram" | "viber" | "email" | "sms" | "webhook" | "in_app"no
to"lead" | "consult" | "contract_signed" | "deposit_paid" | "searching" | "bid_approved" | "won" | "paid_to_auction" | "pickup_scheduled" | "at_us_warehouse" | "loaded" | "in_transit_sea" | "at_eu_port" | "inland_to_border" | "customs_clearing" | "customs_cleared" | "certification" | "registration" | "ready_for_handover" | "handed_over" | "closed" | "lost" | "cancelled" | "on_hold" | "dispute"yesTarget stage.

Responses

200

The transition was applied (or previewed with dry_run).

application/json · Schema: StageResult

FieldTypeRequiredDescription
dryRunbooleanyes
appliedbooleanyestrue: the deal was moved. false only for dry_run.
from"lead" | "consult" | "contract_signed" | "deposit_paid" | "searching" | "bid_approved" | "won" | "paid_to_auction" | "pickup_scheduled" | "at_us_warehouse" | "loaded" | "in_transit_sea" | "at_eu_port" | "inland_to_border" | "customs_clearing" | "customs_cleared" | "certification" | "registration" | "ready_for_handover" | "handed_over" | "closed" | "lost" | "cancelled" | "on_hold" | "dispute"yes
to"lead" | "consult" | "contract_signed" | "deposit_paid" | "searching" | "bid_approved" | "won" | "paid_to_auction" | "pickup_scheduled" | "at_us_warehouse" | "loaded" | "in_transit_sea" | "at_eu_port" | "inland_to_border" | "customs_clearing" | "customs_cleared" | "certification" | "registration" | "ready_for_handover" | "handed_over" | "closed" | "lost" | "cancelled" | "on_hold" | "dispute"yes
okbooleanyesThe transition is possible (always true when applied).
kindstring | nullyes
skipped"lead" | "consult" | "contract_signed" | "deposit_paid" | "searching" | "bid_approved" | "won" | "paid_to_auction" | "pickup_scheduled" | "at_us_warehouse" | "loaded" | "in_transit_sea" | "at_eu_port" | "inland_to_border" | "customs_clearing" | "customs_cleared" | "certification" | "registration" | "ready_for_handover" | "handed_over" | "closed" | "lost" | "cancelled" | "on_hold" | "dispute"[]yesStages skipped on the way (e.g. sea stages for a land route).
missingstring[]yes
reasonKeystring | nullyes
reasonRequiredbooleanyes
notificationsobject[]yes
notifications[].eventstringno
notifications[].tostringno
taskIdsstring (uuid)[]yes
clientMessageobjectyesPreview of the message the client gets (dry_run only).
clientMessage.channelstringyes
clientMessage.localestringyes
clientMessage.titlestring | nullyes
clientMessage.textstringyes
clientMessage.warningsstring[]yes
dealobjectyesThe updated deal (null for dry_run).
deal.idstring (uuid)yes
deal.numberstringyes
deal.status"lead" | "consult" | "contract_signed" | "deposit_paid" | "searching" | "bid_approved" | "won" | "paid_to_auction" | "pickup_scheduled" | "at_us_warehouse" | "loaded" | "in_transit_sea" | "at_eu_port" | "inland_to_border" | "customs_clearing" | "customs_cleared" | "certification" | "registration" | "ready_for_handover" | "handed_over" | "closed" | "lost" | "cancelled" | "on_hold" | "dispute"yes
deal.pausedFrom"lead" | "consult" | "contract_signed" | "deposit_paid" | "searching" | "bid_approved" | "won" | "paid_to_auction" | "pickup_scheduled" | "at_us_warehouse" | "loaded" | "in_transit_sea" | "at_eu_port" | "inland_to_border" | "customs_clearing" | "customs_cleared" | "certification" | "registration" | "ready_for_handover" | "handed_over" | "closed" | "lost" | "cancelled" | "on_hold" | "dispute" | nullyes
deal.type"full_service" | "auction_only" | "logistics_only" | "resale"yes
deal.route"sea" | "land"yes
deal.currency"UAH" | "USD" | "EUR" | "PLN" | "GEL"yes
deal.contactIdstring (uuid)yes
deal.managerIdstring | null (uuid)yes
deal.vehicleIdstring | null (uuid)yes
deal.destinationCountrystring | nullyes
deal.destinationCitystring | nullyes
deal.etaDeliverystring | nullyesISO 8601 date-time (UTC).
deal.stageDatesobjectyesstage -> time of entering it.
deal.trackingTokenstring (uuid)yesToken of the public tracking page (Track).
deal.trackingEnabledbooleanyes
deal.lostReasonstring | nullyes
deal.closedAtstring | nullyesISO 8601 date-time (UTC).
deal.createdAtstringyesISO 8601 date-time (UTC).
deal.updatedAtstringyesISO 8601 date-time (UTC).

400

Invalid request parameters or body (code validation_error).

application/problem+json · Schema: Problem

401

Missing, malformed, unknown, revoked or expired API key (code unauthorized).

application/problem+json · Schema: Problem

403

The API key lacks the scope required by this endpoint (code insufficient_scope).

application/problem+json · Schema: Problem

404

No such deal in this tenant.

application/problem+json · Schema: Problem

409

Conflict: duplicate contact (duplicate_ids), a request with this Idempotency-Key is still being processed, or the stage transition is blocked (missing[]).

application/problem+json · Schema: Problem

422

Well-formed but not acceptable data (unprocessable_input), or Idempotency-Key reused with a different request.

application/problem+json · Schema: Problem

429

Rate limit exceeded for the tenant plan (code rate_limited). Wait Retry-After seconds.

application/problem+json · Schema: Problem

On this page