VitrinaAPI

Price approvals

Authority over a below-reference price: the asker and the decider must be different people.

Beta
This may change at any time, with a changelog entry and a notice to recent callers — see versioning.

Download the full API pública projection: openapi.json.

Sell a unit explains this resource in prose, with runnable examples.

MethodPathWhat it does
GET/price-approvalsThe approval queue
POST/price-approvalsRequest approval for a below-reference price
GET/price-approvals/{id}Fetch one price approval
POST/price-approvals/{id}/decisionDecide 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.

ParameterInTypeRequiredConstraints
statusquerypending \approved \rejected
subject_kindqueryquote \reservation \sale_note
subject_idquerystringnomín. 1, máx. 80
limitqueryintegerno≥ 1, ≤ 200, por defecto 50
offsetqueryinteger | nullno≥ 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

FieldTypeRequiredConstraints
quote_idany—
reservation_idany—
sale_note_idany—
requested_price_clpintegeryes≥ 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.

ParameterInTypeRequiredConstraints
idpathuuidyes
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.

ParameterInTypeRequiredConstraints
idpathuuidyes

Body

FieldTypeRequiredConstraints
decisionapproved \rejectedyes
decision_notestring | 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

On this page