Consignaciones
El contrato bajo el cual una automotora vende el auto de otra persona: crear, editar, devolver y vender con su liquidación.
Descarga la proyección completa de la API pública: openapi.json.
Vender una unidad explica este recurso en prosa, con ejemplos ejecutables.
| Método | Ruta | Qué hace |
|---|---|---|
GET | /consignments | List consignment contracts |
POST | /consignments | Create a contract |
GET | /consignments/{id} | Fetch one contract |
PATCH | /consignments/{id} | Update a contract |
GET | /consignments/{id}/liquidacion | Fetch the settlement record |
POST | /consignments/{id}/return | Return the car to its owner |
POST | /consignments/{id}/sell | Sell the car and settle with the owner |
GET | /consignments/by-vehicle/{vehicleId} | The active contract for one vehicle |
GET /consignments
List consignment contracts
Filter by vehicle_id and/or estado, with limit / offset. No total is returned — the response carries the rows and nothing else.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
vehicle_id | query | uuid | no | |
estado | query | activo \ | vendido \ | devuelto \ |
limit | query | integer | no | ≥ 1, ≤ 200 |
offset | query | integer | null | no | ≥ 0 |
curl https://api.vitrinadev.com/api/v1/consignments \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": [
{
"id": "d7d7d7d7-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"dueno_contact_id": "22222222-0000-4000-8000-000000000004",
"modalidad": "en_local",
"contract_structure": "mandato_con_representacion",
"comision_type": "percentage",
"comision_value": 10,
"minimo_clp": 8000000,
"vencimiento": "2026-12-31",
"estado": "activo",
"vencimiento_reminded_at": null,
"liquidacion_due_notified_at": null,
"created_at": "2026-08-20T10:00:00.000Z",
"updated_at": "2026-08-20T10:00:00.000Z",
"sale_iva_regime": "exento",
"not_on_lot": false
}
],
"meta": {
"total": 1
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /consignments
Create a contract
Creates it already activo — there is no draft state — and ACTIVATION HAS SIDE EFFECTS on the vehicle: its tenencia becomes consignacion, and minimo_clp, if given, is written through as the vehicle’s floor_price_clp. That floor is load-bearing: the pricing watch clamps every suggestion up to it and refuses to apply below it, so the owner’s minimum is what stops an automated recommendation undercutting them. WITHOUT a minimo_clp the vehicle’s existing floor is left exactly as it was — a contract that names no minimum never clears one the dealer set by hand.
Only vehicle_id and modalidad are required. dueno_contact_id, the comision_type/comision_value pair, minimo_clp and vencimiento are all completable later through PATCH /consignments/\{id\} — this is the contrato mínimo, the shape a dealer can actually produce while classifying stock at the counter. It is a real, active contract and it imposes the tenencia like any other; what is deferred is the terms. Until they are recorded the contract cannot be sold (no commission means no split to settle — 409) and its mandato cannot be printed, and GET /consignments/\{id\}/documentation reports exactly which fields are missing with documentationComplete: false. Completing them clears all three by itself; there is no flag to set.
comision_type and comision_value go together or not at all: a value with no type is unreadable (is 5 five percent or five pesos?).
One active contract per vehicle. A second is a 409, enforced both in the service and by a partial unique index, so the race loses too. The vehicle, and the owner contact when one is given, must belong to the workspace.
comision_type decides how comision_value is read (a percentage or a fixed amount), which is what the Liquidación later subtracts. Answers 201.
Cuerpo
| Campo | Tipo | Obligatorio | Restricciones |
|---|---|---|---|
vehicle_id | uuid | sí | |
dueno_contact_id | string | null | — | |
modalidad | en_local \ | virtual | sí |
comision_type | percentage \ | fixed | — |
comision_value | number | null | — | ≥ 0 |
minimo_clp | integer | null | — | > 0 |
minimo_effective_on | string | — | patrón ^\d{4}-\d{2}-\d{2}$ |
vencimiento | string | null | — | patrón ^\d{4}-\d{2}-\d{2}$ |
sale_iva_regime | afecto \ | exento | — |
curl -X POST https://api.vitrinadev.com/api/v1/consignments \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"dueno_contact_id": "22222222-0000-4000-8000-000000000004",
"modalidad": "en_local",
"comision_type": "percentage",
"comision_value": 10,
"minimo_clp": 8000000
}'Ejemplo de respuesta (201)
{
"data": {
"id": "d7d7d7d7-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"dueno_contact_id": "22222222-0000-4000-8000-000000000004",
"modalidad": "en_local",
"contract_structure": "mandato_con_representacion",
"comision_type": "percentage",
"comision_value": 10,
"minimo_clp": 8000000,
"vencimiento": "2026-12-31",
"estado": "activo",
"vencimiento_reminded_at": null,
"liquidacion_due_notified_at": null,
"created_at": "2026-08-20T10:00:00.000Z",
"updated_at": "2026-08-20T10:00:00.000Z",
"sale_iva_regime": "exento",
"not_on_lot": false
}
}Responde: 201 · 400 · 401 · 403 · 404 · 409 · 429
GET /consignments/{id}
Fetch one contract
The contract as stored, whatever its state.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | uuid | sí |
curl https://api.vitrinadev.com/api/v1/consignments/<id> \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"id": "d7d7d7d7-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"dueno_contact_id": "22222222-0000-4000-8000-000000000004",
"modalidad": "en_local",
"contract_structure": "mandato_con_representacion",
"comision_type": "percentage",
"comision_value": 10,
"minimo_clp": 8000000,
"vencimiento": "2026-12-31",
"estado": "activo",
"vencimiento_reminded_at": null,
"liquidacion_due_notified_at": null,
"created_at": "2026-08-20T10:00:00.000Z",
"updated_at": "2026-08-20T10:00:00.000Z",
"sale_iva_regime": "exento",
"not_on_lot": false
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
PATCH /consignments/{id}
Update a contract
Edits the terms, and can move estado — except to vendido, which is a 409 directing you to the sell action, so a sale can never be recorded without producing its Liquidación. Other transitions are checked against the state machine and an illegal one is also a 409.
Moving vencimiento RE-ARMS the expiry reminder: the "already reminded" stamp is cleared, so a pushed-out date produces a fresh nudge rather than staying silent.
Supplying minimo_clp RENEGOTIATES the mínimo rather than editing a column: it appends an immutable revision to the contract’s terms history (GET /consignments/\{id\}/terms), dated minimo_effective_on or today. The new value must DIFFER from the one currently governing — repeating it is a 409, as is a second revision on a date already taken.
A raised minimo_clp writes through to the vehicle’s floor while the contract is active — but clearing it never clears the floor, and neither does the contract ending. The vehicle has one floor column with no record of who set it, so removing it here could silently wipe a floor the dealer set by hand. Clear the vehicle’s floor deliberately if that is what you want.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | uuid | sí |
Cuerpo
| Campo | Tipo | Obligatorio | Restricciones |
|---|---|---|---|
dueno_contact_id | uuid | — | |
modalidad | en_local \ | virtual | — |
comision_type | percentage \ | fixed | — |
comision_value | number | — | ≥ 0 |
minimo_clp | integer | null | — | > 0 |
minimo_effective_on | string | — | patrón ^\d{4}-\d{2}-\d{2}$ |
vencimiento | string | null | — | patrón ^\d{4}-\d{2}-\d{2}$ |
estado | activo \ | vendido \ | devuelto \ |
sale_iva_regime | afecto \ | exento | — |
curl -X PATCH https://api.vitrinadev.com/api/v1/consignments/<id> \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"minimo_clp": 8300000
}'Ejemplo de respuesta (200)
{
"data": {
"id": "d7d7d7d7-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"dueno_contact_id": "22222222-0000-4000-8000-000000000004",
"modalidad": "en_local",
"contract_structure": "mandato_con_representacion",
"comision_type": "percentage",
"comision_value": 10,
"minimo_clp": 8300000,
"vencimiento": "2026-12-31",
"estado": "activo",
"vencimiento_reminded_at": null,
"liquidacion_due_notified_at": null,
"created_at": "2026-08-20T10:00:00.000Z",
"updated_at": "2026-08-20T10:00:00.000Z",
"sale_iva_regime": "exento",
"not_on_lot": false
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /consignments/{id}/liquidacion
Fetch the settlement record
The persisted Liquidación for a contract. It only exists once the contract has been sold — this is a read of a record, not a projection computed on demand, so the figures are what was agreed at settlement even if the terms changed afterwards.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | uuid | sí |
curl https://api.vitrinadev.com/api/v1/consignments/<id>/liquidacion \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"id": "d8d8d8d8-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"consignment_contract_id": "d7d7d7d7-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"settlement_mode": "stated_commission",
"amount_venta_clp": 8900000,
"comision_type": "percentage",
"comision_value": 10,
"comision_amount_clp": 890000,
"monto_owner_clp": 8010000,
"owner_floor_clp": null,
"deducciones_clp": 0,
"retiro_motivo": null,
"retiro_by": null,
"paid_at": "2026-09-18T15:00:00.000Z",
"created_at": "2026-09-18T15:00:05.000Z",
"updated_at": "2026-09-18T15:00:05.000Z"
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /consignments/{id}/return
Return the car to its owner
Moves the contract to devuelto and flips the vehicle’s tenencia back to propio. Exactly equivalent to PATCH \{ estado: "devuelto" \} — it exists so the intent reads as a verb rather than a state assignment.
devuelto is the only terminal state that restores propio: a sold or expired contract KEEPS tenencia: consignacion, because the car was sold on consignment and the history should say so.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | uuid | sí |
curl -X POST https://api.vitrinadev.com/api/v1/consignments/<id>/return \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"id": "d7d7d7d7-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"dueno_contact_id": "22222222-0000-4000-8000-000000000004",
"modalidad": "en_local",
"contract_structure": "mandato_con_representacion",
"comision_type": "percentage",
"comision_value": 10,
"minimo_clp": 8000000,
"vencimiento": "2026-12-31",
"estado": "devuelto",
"vencimiento_reminded_at": null,
"liquidacion_due_notified_at": null,
"created_at": "2026-08-20T10:00:00.000Z",
"updated_at": "2026-09-15T09:00:00.000Z",
"sale_iva_regime": "exento",
"not_on_lot": false
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /consignments/{id}/sell
Sell the car and settle with the owner
One atomic action doing two things: moves the contract to vendido, and produces the Liquidación — sale price minus commission equals the amount owed to the owner, plus the payment record. Requires amount_venta_clp; paid_at records when the owner was actually paid.
Legal only from activo; anything else is a 409. Answers 201 with the contract and the Liquidación.
It does NOT close the vehicle’s side — the estadía close belongs to the vehicle lifecycle, so mark the vehicle sold separately.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | uuid | sí |
Cuerpo
| Campo | Tipo | Obligatorio | Restricciones |
|---|---|---|---|
amount_venta_clp | integer | sí | > 0 |
paid_at | string | — | date-time |
curl -X POST https://api.vitrinadev.com/api/v1/consignments/<id>/sell \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount_venta_clp": 8900000,
"paid_at": "2026-09-18T15:00:00.000Z"
}'Ejemplo de respuesta (201)
{
"data": {
"contract": {
"id": "d7d7d7d7-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"dueno_contact_id": "22222222-0000-4000-8000-000000000004",
"modalidad": "en_local",
"contract_structure": "mandato_con_representacion",
"comision_type": "percentage",
"comision_value": 10,
"minimo_clp": 8000000,
"vencimiento": "2026-12-31",
"estado": "vendido",
"vencimiento_reminded_at": null,
"liquidacion_due_notified_at": null,
"created_at": "2026-08-20T10:00:00.000Z",
"updated_at": "2026-08-20T10:00:00.000Z",
"sale_iva_regime": "exento",
"not_on_lot": false
},
"liquidacion": {
"id": "d8d8d8d8-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"consignment_contract_id": "d7d7d7d7-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"settlement_mode": "stated_commission",
"amount_venta_clp": 8900000,
"comision_type": "percentage",
"comision_value": 10,
"comision_amount_clp": 890000,
"monto_owner_clp": 8010000,
"owner_floor_clp": null,
"deducciones_clp": 0,
"retiro_motivo": null,
"retiro_by": null,
"paid_at": "2026-09-18T15:00:00.000Z",
"created_at": "2026-09-18T15:00:05.000Z",
"updated_at": "2026-09-18T15:00:05.000Z"
}
}
}Responde: 201 · 400 · 401 · 403 · 404 · 409 · 429
GET /consignments/by-vehicle/{vehicleId}
The active contract for one vehicle
Answers the question the agent and the test-drive flow actually ask: is this car ours to hand over? Returns the ACTIVE contract (or null) plus a not_on_lot flag.
Use this rather than filtering the list by vehicle_id: a vehicle can have several historical contracts and only ever one active, and this endpoint is the one that resolves that.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
vehicleId | path | uuid | sí |
curl https://api.vitrinadev.com/api/v1/consignments/by-vehicle/<id> \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"contract": {
"id": "d7d7d7d7-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"vehicle_id": "e1e1e1e1-0000-4000-8000-000000000001",
"dueno_contact_id": "22222222-0000-4000-8000-000000000004",
"modalidad": "en_local",
"contract_structure": "mandato_con_representacion",
"comision_type": "percentage",
"comision_value": 10,
"minimo_clp": 8000000,
"vencimiento": "2026-12-31",
"estado": "activo",
"vencimiento_reminded_at": null,
"liquidacion_due_notified_at": null,
"created_at": "2026-08-20T10:00:00.000Z",
"updated_at": "2026-08-20T10:00:00.000Z",
"sale_iva_regime": "exento",
"not_on_lot": false
},
"not_on_lot": false
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429