VitrinaAPI

Laboratorio de la clínica

Los laboratorios de la clínica, su lista de precios por tipo de trabajo y los pedidos que se les envían, con el estado de cada pedido.

Beta
Puede cambiar en cualquier momento, con una entrada en el changelog y aviso a quienes la llamaron recientemente — ver versionado.

Descarga la proyección completa de la API pública: openapi.json.

MétodoRutaQué hace
GET/clinic/lab-ordersList lab orders
POST/clinic/lab-ordersSend work to a lab for a treatment
GET/clinic/lab-orders/{id}One lab order
PATCH/clinic/lab-orders/{id}Move a lab order along, or correct it
GET/clinic/lab-work-typesList the labs' price lists
POST/clinic/lab-work-typesAdd a line to a lab's price list
PATCH/clinic/lab-work-types/{id}Re-price or retire a line of a lab's price list
POST/clinic/labsAdd a laboratorio
PATCH/clinic/labs/{id}Edit or deactivate a laboratorio

GET /clinic/lab-orders

List lab orders

Every order with its lab, patient, treatment and professional. Filter by lab_id, status, or open=true (to send + sent — the work still in flight); treatment_plan_item_id, treatment_plan_id and patient_id narrow to one treatment, plan or ficha. Work in flight sorts first, oldest first. counts carries the per-status totals for the same lab/patient filter, ignoring status.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

ParámetroEnTipoObligatorioRestricciones
lab_idqueryuuidno
statusqueryto_send \sent \received \
openquerytrue \falseno
treatment_plan_item_idqueryuuidno
treatment_plan_idqueryuuidno
patient_idqueryuuidno
pagequeryintegerno≥ 1, por defecto 1
limitqueryintegerno≥ 1, ≤ 200, por defecto 50
curl https://api.vitrinadev.com/api/v1/clinic/lab-orders \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": {
    "items": [
      {
        "id": "c0e57121-0000-4000-8000-0000000003ab",
        "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
        "source": "native",
        "external_id": null,
        "treatment_plan_item_id": "b7b7b7b7-0000-4000-8000-000000000011",
        "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
        "work_type_id": "c0e57121-0000-4000-8000-0000000002ab",
        "work_type": "Corona de zirconio",
        "cost_clp": 95000,
        "status": "sent",
        "sent_on": "2026-09-29",
        "received_on": null,
        "notes": "Color A2",
        "created_by": "5e5e5e5e-0000-4000-8000-000000000001",
        "created_at": "2026-09-29T13:05:00.000Z",
        "updated_at": "2026-09-29T15:20:00.000Z",
        "lab_name": "Laboratorio Ejemplo",
        "treatment_plan_id": "b7b7b7b7-0000-4000-8000-000000000001",
        "treatment_plan_name": "Rehabilitación sector posterior",
        "clinic_patient_id": "b1b0b8de-0000-4000-8000-000000000001",
        "patient_name": "María José Fuentes Lagos",
        "service_name": "Corona cerámica",
        "professional_name": "Camila Rojas"
      }
    ],
    "total": 1,
    "page": 1,
    "limit": 50,
    "counts": {
      "to_send": 0,
      "sent": 1,
      "received": 0,
      "cancelled": 0
    }
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

POST /clinic/lab-orders

Send work to a lab for a treatment

Created from a treatment-plan item. With work_type_id (a line of the lab's price list) the name and cost default from the list; work_type / cost_clp override them, and are required without it. status defaults to to_send; sent / received without a date are stamped with today in the clinic's calendar. A cancelled treatment or a deactivated lab answers 400.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

Cuerpo

CampoTipoObligatorioRestricciones
treatment_plan_item_iduuidsí
clinic_lab_iduuidsí
work_type_idstring | null—
work_typestring | null—mín. 1, máx. 160
cost_clpinteger | null—≥ 0, ≤ 1000000000
statusto_send \sent \received \
sent_onstring | null—patrón ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
received_onstring | null—patrón ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
notesstring | null—máx. 1000
curl -X POST https://api.vitrinadev.com/api/v1/clinic/lab-orders \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "treatment_plan_item_id": "b7b7b7b7-0000-4000-8000-000000000011",
    "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
    "work_type_id": "c0e57121-0000-4000-8000-0000000002ab",
    "notes": "Color A2"
  }'

Ejemplo de respuesta (201)

{
  "data": {
    "id": "c0e57121-0000-4000-8000-0000000003ab",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "source": "native",
    "external_id": null,
    "treatment_plan_item_id": "b7b7b7b7-0000-4000-8000-000000000011",
    "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
    "work_type_id": "c0e57121-0000-4000-8000-0000000002ab",
    "work_type": "Corona de zirconio",
    "cost_clp": 95000,
    "status": "to_send",
    "sent_on": null,
    "received_on": null,
    "notes": "Color A2",
    "created_by": "5e5e5e5e-0000-4000-8000-000000000001",
    "created_at": "2026-09-29T13:05:00.000Z",
    "updated_at": "2026-09-29T15:20:00.000Z",
    "lab_name": "Laboratorio Ejemplo",
    "treatment_plan_id": "b7b7b7b7-0000-4000-8000-000000000001",
    "treatment_plan_name": "Rehabilitación sector posterior",
    "clinic_patient_id": "b1b0b8de-0000-4000-8000-000000000001",
    "patient_name": "María José Fuentes Lagos",
    "service_name": "Corona cerámica",
    "professional_name": "Camila Rojas"
  }
}

Responde: 201 · 400 · 401 · 403 · 404 · 409 · 429

GET /clinic/lab-orders/{id}

One lab order

The order with the same names the list carries.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

ParámetroEnTipoObligatorioRestricciones
idpathuuidsí
curl https://api.vitrinadev.com/api/v1/clinic/lab-orders/<id> \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": {
    "id": "c0e57121-0000-4000-8000-0000000003ab",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "source": "native",
    "external_id": null,
    "treatment_plan_item_id": "b7b7b7b7-0000-4000-8000-000000000011",
    "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
    "work_type_id": "c0e57121-0000-4000-8000-0000000002ab",
    "work_type": "Corona de zirconio",
    "cost_clp": 95000,
    "status": "sent",
    "sent_on": "2026-09-29",
    "received_on": null,
    "notes": "Color A2",
    "created_by": "5e5e5e5e-0000-4000-8000-000000000001",
    "created_at": "2026-09-29T13:05:00.000Z",
    "updated_at": "2026-09-29T15:20:00.000Z",
    "lab_name": "Laboratorio Ejemplo",
    "treatment_plan_id": "b7b7b7b7-0000-4000-8000-000000000001",
    "treatment_plan_name": "Rehabilitación sector posterior",
    "clinic_patient_id": "b1b0b8de-0000-4000-8000-000000000001",
    "patient_name": "María José Fuentes Lagos",
    "service_name": "Corona cerámica",
    "professional_name": "Camila Rojas"
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

PATCH /clinic/lab-orders/{id}

Move a lab order along, or correct it

status: "sent" / "received" stamps today when no date is given; "to_send" clears both dates; "cancelled" keeps them and stops the order counting toward the treatment's lab cost. Choosing another work_type_id re-defaults the name and cost unless the same request sends its own. A received date before the sent date answers 400.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

ParámetroEnTipoObligatorioRestricciones
idpathuuidsí

Cuerpo

CampoTipoObligatorioRestricciones
clinic_lab_iduuid—
work_type_idstring | null—
work_typestring—mín. 1, máx. 160
cost_clpinteger—≥ 0, ≤ 1000000000
statusto_send \sent \received \
sent_onstring | null—patrón ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
received_onstring | null—patrón ^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
notesstring | null—máx. 1000
curl -X PATCH https://api.vitrinadev.com/api/v1/clinic/lab-orders/<id> \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "sent"
  }'

Ejemplo de respuesta (200)

{
  "data": {
    "id": "c0e57121-0000-4000-8000-0000000003ab",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "source": "native",
    "external_id": null,
    "treatment_plan_item_id": "b7b7b7b7-0000-4000-8000-000000000011",
    "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
    "work_type_id": "c0e57121-0000-4000-8000-0000000002ab",
    "work_type": "Corona de zirconio",
    "cost_clp": 95000,
    "status": "sent",
    "sent_on": "2026-09-29",
    "received_on": null,
    "notes": "Color A2",
    "created_by": "5e5e5e5e-0000-4000-8000-000000000001",
    "created_at": "2026-09-29T13:05:00.000Z",
    "updated_at": "2026-09-29T15:20:00.000Z",
    "lab_name": "Laboratorio Ejemplo",
    "treatment_plan_id": "b7b7b7b7-0000-4000-8000-000000000001",
    "treatment_plan_name": "Rehabilitación sector posterior",
    "clinic_patient_id": "b1b0b8de-0000-4000-8000-000000000001",
    "patient_name": "María José Fuentes Lagos",
    "service_name": "Corona cerámica",
    "professional_name": "Camila Rojas"
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

GET /clinic/lab-work-types

List the labs' price lists

What each lab charges per kind of work («Corona de zirconio», $95.000). ?lab_id= narrows to one lab; ?active=true is what the order form offers. The cost here is the DEFAULT a new order copies.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

ParámetroEnTipoObligatorioRestricciones
lab_idqueryuuidno
activequerytrue \falseno
curl https://api.vitrinadev.com/api/v1/clinic/lab-work-types \
  -H "Authorization: Bearer $VITRINA_KEY"

Ejemplo de respuesta (200)

{
  "data": [
    {
      "id": "c0e57121-0000-4000-8000-0000000002ab",
      "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
      "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
      "source": "native",
      "external_id": null,
      "name": "Corona de zirconio",
      "cost_clp": 95000,
      "active": true,
      "created_at": "2026-09-29T13:01:00.000Z",
      "updated_at": "2026-09-29T13:01:00.000Z"
    }
  ]
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

POST /clinic/lab-work-types

Add a line to a lab's price list

One name per lab, case-insensitive — a duplicate answers 409. Requires clinic_admin:write.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

Cuerpo

CampoTipoObligatorioRestricciones
clinic_lab_iduuidsí
namestringsímín. 1, máx. 160
cost_clpintegersí≥ 0, ≤ 1000000000
curl -X POST https://api.vitrinadev.com/api/v1/clinic/lab-work-types \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
    "name": "Corona de zirconio",
    "cost_clp": 95000
  }'

Ejemplo de respuesta (201)

{
  "data": {
    "id": "c0e57121-0000-4000-8000-0000000002ab",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
    "source": "native",
    "external_id": null,
    "name": "Corona de zirconio",
    "cost_clp": 95000,
    "active": true,
    "created_at": "2026-09-29T13:01:00.000Z",
    "updated_at": "2026-09-29T13:01:00.000Z"
  }
}

Responde: 201 · 400 · 401 · 403 · 404 · 409 · 429

PATCH /clinic/lab-work-types/{id}

Re-price or retire a line of a lab's price list

Changing cost_clp affects orders created FROM NOW ON; an order already created keeps the cost it was created with.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

ParámetroEnTipoObligatorioRestricciones
idpathuuidsí

Cuerpo

CampoTipoObligatorioRestricciones
namestring—mín. 1, máx. 160
cost_clpinteger—≥ 0, ≤ 1000000000
activeboolean—
curl -X PATCH https://api.vitrinadev.com/api/v1/clinic/lab-work-types/<id> \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "cost_clp": 98000
  }'

Ejemplo de respuesta (200)

{
  "data": {
    "id": "c0e57121-0000-4000-8000-0000000002ab",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "clinic_lab_id": "c0e57121-0000-4000-8000-0000000001ab",
    "source": "native",
    "external_id": null,
    "name": "Corona de zirconio",
    "cost_clp": 98000,
    "active": true,
    "created_at": "2026-09-29T13:01:00.000Z",
    "updated_at": "2026-09-29T13:01:00.000Z"
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

POST /clinic/labs

Add a laboratorio

A lab the clinic works with that did not arrive from the Dentalink import (source: "native"). contact is the lab's address and phone. Requires clinic_admin:write.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

Cuerpo

CampoTipoObligatorioRestricciones
namestringsímín. 1, máx. 160
contactobject—
curl -X POST https://api.vitrinadev.com/api/v1/clinic/labs \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Laboratorio Ejemplo",
    "contact": {
      "direccion": "Avenida Ejemplo 456",
      "telefono": "+56 9 0000 0200"
    }
  }'

Ejemplo de respuesta (201)

{
  "data": {
    "id": "c0e57121-0000-4000-8000-0000000001ab",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "source": "native",
    "external_id": null,
    "name": "Laboratorio Ejemplo",
    "contact": {
      "direccion": "Avenida Ejemplo 456",
      "telefono": "+56 9 0000 0200"
    },
    "active": true,
    "created_at": "2026-09-29T13:00:00.000Z",
    "updated_at": "2026-09-29T13:00:00.000Z"
  }
}

Responde: 201 · 400 · 401 · 403 · 404 · 409 · 429

PATCH /clinic/labs/{id}

Edit or deactivate a laboratorio

Rename it, change its contact, or active: false to hide it from the order form. A lab is deactivated, never deleted: its orders keep naming it.

Connected apps: every patient and contact in the response is a Seudónimo de paciente — initials plus a stable number, "M.F. · #1001" — unless the clinic allowed patient names, with RUT, phone and email masked in free text and meta.patient_privacy saying so. Clinical alerts (flags) are withheld in both modes, and a non-JSON body (an export, a file) is refused with 403 CONNECTED_APP_SENSITIVE_DATA.

ParámetroEnTipoObligatorioRestricciones
idpathuuidsí

Cuerpo

CampoTipoObligatorioRestricciones
namestring—mín. 1, máx. 160
contactobject—
activeboolean—
curl -X PATCH https://api.vitrinadev.com/api/v1/clinic/labs/<id> \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "active": false
  }'

Ejemplo de respuesta (200)

{
  "data": {
    "id": "c0e57121-0000-4000-8000-0000000001ab",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "source": "native",
    "external_id": null,
    "name": "Laboratorio Ejemplo",
    "contact": {
      "direccion": "Avenida Ejemplo 456",
      "telefono": "+56 9 0000 0200"
    },
    "active": false,
    "created_at": "2026-09-29T13:00:00.000Z",
    "updated_at": "2026-09-29T13:00:00.000Z"
  }
}

Responde: 200 · 400 · 401 · 403 · 404 · 409 · 429

En esta página