Aprobaciones de precio
La autoridad sobre un precio bajo el de referencia: quien pide y quien decide deben ser personas distintas.
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 | /price-approvals | The approval queue |
POST | /price-approvals | Request approval for a below-reference price |
GET | /price-approvals/{id} | Fetch one price approval |
POST | /price-approvals/{id}/decision | Decide a price approval |
GET | /price-approvals/evaluate | Would this price need approval? |
GET /price-approvals
The approval queue
Oldest-first. Cost fields (e.g. floor_price_snapshot_clp) are ABSENT from the response unless the caller also holds dealership_economics:read.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
status | query | pending \ | approved \ | rejected |
subject_kind | query | quote \ | reservation \ | sale_note |
subject_id | query | string | no | mín. 1, máx. 80 |
limit | query | integer | no | ≥ 1, ≤ 200, por defecto 50 |
offset | query | integer | null | no | ≥ 0, por defecto 0 |
curl https://api.vitrinadev.com/api/v1/price-approvals \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": [
{
"id": "dbdbdbdb-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"quote_id": null,
"reservation_id": null,
"sale_note_id": "d4d4d4d4-0000-4000-8000-000000000001",
"requested_price_clp": 10900000,
"list_price_snapshot_clp": 11900000,
"floor_price_snapshot_clp": 11200000,
"requester_user_id": "11111111-0000-4000-8000-000000000002",
"status": "pending",
"decider_user_id": null,
"decided_at": null,
"decision_note": null,
"created_at": "2026-09-19T12:40:00.000Z",
"updated_at": "2026-09-19T12:40:00.000Z"
}
],
"meta": {
"total": 1
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /price-approvals
Request approval for a below-reference price
Names exactly one of quote_id / reservation_id / sale_note_id. requested_price_clp is the price the buyer pays for the car — IVA included on an afecto sale — the same terms as the published price and the precio piso it is measured against (ADR 0114 §2.2). A sale note is approved when what its buyer pays is at or above an approved request. The requester is the authenticated principal, never a body field.
Cuerpo
| Campo | Tipo | Obligatorio | Restricciones |
|---|---|---|---|
quote_id | any | — | |
reservation_id | any | — | |
sale_note_id | any | — | |
requested_price_clp | integer | sí | ≥ 0, ≤ 999999999999 |
curl -X POST https://api.vitrinadev.com/api/v1/price-approvals \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"sale_note_id": "d4d4d4d4-0000-4000-8000-000000000001",
"requested_price_clp": 10900000
}'Ejemplo de respuesta (201)
{
"data": {
"id": "dbdbdbdb-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"quote_id": null,
"reservation_id": null,
"sale_note_id": "d4d4d4d4-0000-4000-8000-000000000001",
"requested_price_clp": 10900000,
"list_price_snapshot_clp": 11900000,
"floor_price_snapshot_clp": 11200000,
"requester_user_id": "11111111-0000-4000-8000-000000000002",
"status": "pending",
"decider_user_id": null,
"decided_at": null,
"decision_note": null,
"created_at": "2026-09-19T12:40:00.000Z",
"updated_at": "2026-09-19T12:40:00.000Z"
}
}Responde: 201 · 400 · 401 · 403 · 404 · 409 · 429
GET /price-approvals/{id}
Fetch one price approval
The approval as stored, whatever its status (pending | approved | rejected). Cost fields (list_price_snapshot_clp, floor_price_snapshot_clp) are ABSENT from the response — never null — unless the caller also holds dealership_economics:read, the same gate GET /price-approvals applies. An approval belonging to another workspace is a 404, indistinguishable from one that does not exist.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | uuid | sí |
curl https://api.vitrinadev.com/api/v1/price-approvals/<id> \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"id": "dbdbdbdb-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"quote_id": null,
"reservation_id": null,
"sale_note_id": "d4d4d4d4-0000-4000-8000-000000000001",
"requested_price_clp": 10900000,
"list_price_snapshot_clp": 11900000,
"floor_price_snapshot_clp": 11200000,
"requester_user_id": "11111111-0000-4000-8000-000000000002",
"status": "pending",
"decider_user_id": null,
"decided_at": null,
"decision_note": null,
"created_at": "2026-09-19T12:40:00.000Z",
"updated_at": "2026-09-19T12:40:00.000Z"
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
POST /price-approvals/{id}/decision
Decide a price approval
Terminal — no PUT/PATCH and no second decision. price_approval:approve is a single, non-OR’d scope: holding the requesting scope never grants the deciding authority.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
id | path | uuid | sí |
Cuerpo
| Campo | Tipo | Obligatorio | Restricciones |
|---|---|---|---|
decision | approved \ | rejected | sí |
decision_note | string | null | — | máx. 2000 |
curl -X POST https://api.vitrinadev.com/api/v1/price-approvals/<id>/decision \
-H "Authorization: Bearer $VITRINA_KEY" \
-H "Content-Type: application/json" \
-d '{
"decision": "approved",
"decision_note": "autorizado por gerencia dado el tiempo en stock"
}'Ejemplo de respuesta (200)
{
"data": {
"id": "dbdbdbdb-0000-4000-8000-000000000001",
"tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
"quote_id": null,
"reservation_id": null,
"sale_note_id": "d4d4d4d4-0000-4000-8000-000000000001",
"requested_price_clp": 10900000,
"list_price_snapshot_clp": 11900000,
"floor_price_snapshot_clp": 11200000,
"requester_user_id": "11111111-0000-4000-8000-000000000002",
"status": "approved",
"decider_user_id": "11111111-0000-4000-8000-000000000001",
"decided_at": "2026-09-19T16:05:00.000Z",
"decision_note": "autorizado por gerencia dado el tiempo en stock",
"created_at": "2026-09-19T12:40:00.000Z",
"updated_at": "2026-09-19T12:40:00.000Z"
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429
GET /price-approvals/evaluate
Would this price need approval?
Evaluates price_clp — what the buyer pays for the car, IVA included on an afecto sale, the same terms as the published price and the precio piso (ADR 0114 §2.2) — against the unit named by exactly one of vehicle_id / quote_id / reservation_id / sale_note_id (UUID or folio), with the same policy POST /price-approvals enforces — so a screen that hides «Pedir aprobación» on needs_approval: false hides exactly the request the POST would refuse. reason is the stable code (below_reference | within_tolerance | at_or_above_reference | no_reference); message is a ready-to-show Spanish sentence. When the reference is the unit floor, reference_clp and shortfall_clp are ABSENT unless the caller holds dealership_economics:read. Requires price_approval:read or price_approval:request.
| Parámetro | En | Tipo | Obligatorio | Restricciones |
|---|---|---|---|---|
vehicle_id | query | uuid | no | |
quote_id | query | any | no | |
reservation_id | query | any | no | |
sale_note_id | query | any | no | |
price_clp | query | string | sí | patrón ^\d{1,12}$ |
curl https://api.vitrinadev.com/api/v1/price-approvals/evaluate \
-H "Authorization: Bearer $VITRINA_KEY"Ejemplo de respuesta (200)
{
"data": {
"needs_approval": true,
"reason": "below_reference",
"message": "El precio está $500.000 bajo el precio publicado ($12.990.000). Requiere la aprobación de otra persona.",
"reference_kind": "list",
"reference_clp": 12990000,
"shortfall_clp": 500000,
"tolerance_clp": 0,
"vehicle_id": "5b0c7a7e-2f3d-4c1e-9a4b-7d2e8f1c3a60"
}
}Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429