Price approvals
Authority over a below-reference price: the asker and the decider must be different people.
Download the full API pública projection: openapi.json.
Sell a unit explains this resource in prose, with runnable examples.
| Method | Path | What it does |
|---|---|---|
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
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.
| Parameter | In | Type | Required | Constraints |
|---|---|---|---|---|
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"Example response (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
}
}Answers: 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. The requester is the authenticated principal, never a body field.
Body
| Field | Type | Required | Constraints |
|---|---|---|---|
quote_id | any | — | |
reservation_id | any | — | |
sale_note_id | any | — | |
requested_price_clp | integer | yes | ≥ 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
}'Example response (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"
}
}Answers: 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.
| Parameter | In | Type | Required | Constraints |
|---|---|---|---|---|
id | path | uuid | yes |
curl https://api.vitrinadev.com/api/v1/price-approvals/<id> \
-H "Authorization: Bearer $VITRINA_KEY"Example response (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"
}
}Answers: 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.
| Parameter | In | Type | Required | Constraints |
|---|---|---|---|---|
id | path | uuid | yes |
Body
| Field | Type | Required | Constraints |
|---|---|---|---|
decision | approved \ | rejected | yes |
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"
}'Example response (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"
}
}Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429