Skip to content

Publicación de DiagnosticReport

Esta sección describe cómo realizar la publicación de un informe de diagnóstico.

Solicitud

La publicación se realiza enviando un recurso FHIR de tipo Parameters. A continuación se detallan los recursos principales.

Recursos

1. Paciente (Recurso FHIR R4 Patient)

Se envían todos los datos que permitan identificar al paciente:

  • Nombre y Apellido
  • Tipo de identificación: Se utiliza la URI correspondiente del Registro Nacional de las Personas (RENAPER) para indicar si es DNI o de HL7 (http://hl7.org/fhir/sid/{CÓDIGO_ALFA_ISO_3166}) para Pasaporte, indicando:
    • Código de país alpha-2 según se indica en la norma ISO 3166-1.
    • Tipo de documento 'PPN' (Pasaporte) según la codificación de FHIR.
  • Número de identificación: Número de documento (del DNI o Pasaporte).
  • Datos de contacto: Email y teléfono del paciente.
  • Sexo:
    • Si es Masculino: male
    • Si es Femenino: female
    • Si es Otro: other
  • Fecha de nacimiento: Formato YYYY-MM-DD (sin hora).

2. Organización (Recurso FHIR R4 Organization)

Información de la organización que envía el estudio:

  • Nombre de la organización
  • Identificador: UUID de la organización en Quralo.

3. Informe (Recurso FHIR R4 DiagnosticReport)

El recurso principal que contiene:

  • Estado: Indica si el informe se encuentra en curso o finalizado.
  • Identificador: Identificador único del informe en el sistema del integrador. La plataforma requiere exactamente un (1) elemento en DiagnosticReport.identifier, con los campos system y value obligatorios. La combinación de organización autenticada (tenant) + system + value determina la unicidad del recurso (ver más).
  • Categoría: Categoría a la que pertenece el informe. Puede haber más de 1. (ver más).
  • Código: Nombre/código del informe (ver más).
  • Paciente: Referencia al paciente al que pertenece el informe.
  • Organización: Referencia a la organización que envía el informe.
  • Fecha y hora efectiva: Fecha y hora al que corresponden los valores observados.
  • Fecha y hora de emisión: Fecha y hora en que se emite el informe.
  • Conclusión: Texto breve con el resultado o interpretación.
  • Documento adjunto: Se incluye el archivo original codificado en Base64. Puede haber más de un archivo.

Identificadores

El recurso DiagnosticReport debe incluir exactamente un elemento en el campo identifier que identifique de forma única al informe dentro del sistema del integrador. La plataforma utiliza este identificador para prevenir registros duplicados y garantizar la idempotencia del endpoint.

Campos obligatorios

  • system (obligatorio): URI que define el namespace del identificador. Debe ser una URI que represente el sistema de identificación utilizado por el integrador.
    • Ejemplo: https://misistema.com/laboratorio/informes
  • value (obligatorio): Identificador único del informe dentro del namespace definido por system.
    • Ejemplo: INF-2024-000123

Regla de unicidad

La unicidad de un DiagnosticReport está determinada por la combinación de los siguientes tres elementos:

  • Tenant: Organización autenticada mediante OAuth 2.0 (se determina automáticamente a partir del token de acceso).
  • identifier.system: URI del sistema de identificación.
  • identifier.value: Identificador único del informe dentro del sistema.

Esta combinación es utilizada por la plataforma para prevenir registros duplicados. La misma combinación de system + value puede existir para distintas organizaciones, ya que el tenant las diferencia automáticamente y las aísla en espacios de nombres separados.

Importante – El tenant se obtiene del contexto de autenticación

El organizationId no debe incluirse como parte del identifier.system. El tenant se determina automáticamente a partir del contexto de autenticación OAuth 2.0 y no debe ser parte del identificador del recurso.

Incorrecto:

json
"identifier": [
  {
    "system": "https://misistema.com/organizations/c94deab2-37fa-436e-b5ab-9d5d41f1b271/informes",
    "value": "INF-2024-000123"
  }
]

Correcto:

json
"identifier": [
  {
    "system": "https://misistema.com/laboratorio/informes",
    "value": "INF-2024-000123"
  }
]

Validaciones

La plataforma valida el campo identifier del recurso DiagnosticReport de la siguiente manera:

  • Identifier: El recurso DiagnosticReport debe contener el campo identifier. Si está ausente, la plataforma responde con 400 Bad Request.
  • Cantidad exacta: Debe haber exactamente un (1) elemento en identifier. Si hay cero o más de uno, la plataforma responde con 400 Bad Request.
  • Campos obligatorios: Cada identifier debe incluir system y value. Si falta alguno, la plataforma responde con 400 Bad Request.

Ejemplo de respuesta de error (400 Bad Request):

json
{
  "resourceType": "OperationOutcome",
  "issue": [
    {
      "severity": "error",
      "code": "invalid",
      "diagnostics": "DiagnosticReport.identifier is required"
    }
  ]
}

Idempotencia

El endpoint POST /fhir/r4/DiagnosticReport/$register es idempotente: múltiples envíos del mismo recurso DiagnosticReport con la misma combinación de identificadores (tenant + identifier.system + identifier.value) no generan nuevos recursos.

La respuesta es siempre 201 Created, tanto para creación inicial como para reenvío. La idempotencia es transparente para el cliente.

Ver Idempotencia en endpoints FHIR para el detalle completo del comportamiento, incluyendo el diagrama de flujo, reglas de unicidad y soporte del header If-None-Exist.

Headers

  • Content-Type: application/fhir+json

Estructura

El resourceType es Parameters y cada parámetro corresponde a un recurso FHIR.

  • patient (Recurso Patient)

    • resourceType: "Patient"

    • id: Identificador del paciente en el Payload.

    • name: Nombre y apellido del paciente.

      • family: Apellido del paciente.
      • given: Nombre/s del paciente.
    • identifier: Identificador del paciente.

    • telecom: Información de contacto del paciente.

      • system: Tipo de contacto del paciente.
        • Si es Email: email
        • Si es Teléfono: phone
      • value: Número de teléfono o email del paciente.
      • use: (Optativo) Uso del contacto del paciente.
        • Si es de su Domicilio: home
        • Si es de su Trabajo: work
        • Si es su Teléfono celular: mobile
    • gender: Sexo del paciente.

      • Si es Masculino: male
      • Si es Femenino: female
      • Si es Otro: other
    • birthDate: Fecha de nacimiento del paciente en formato YYYY-MM-DD (sin hora).

  • organization (Recurso Organization)

    • resourceType: "Organization"

    • id: Identificador de la organización en el Payload.

    • name: Nombre de la organización.

    • identifier: Identificador de la organización.

      • system: URI de identificación de la organización: http://quralo.com/organization
      • value: Identificador de la organización en Quralo (es de tipo UUID).
  • diagnosticReport (Recurso DiagnosticReport)

    • resourceType: "DiagnosticReport"

    • identifier: Identificador único del informe en el sistema del integrador (1..1).

      • system: (obligatorio) URI del namespace del identificador.
      • value: (obligatorio) Identificador único dentro del namespace.
    • status: Estado del informe (ver más).

      • registered: El informe ha sido registrado en el sistema, pero aún no está disponible para su visualización o uso clínico.
      • partial: El informe está en proceso de elaboración y puede contener datos incompletos o no verificados.
      • preliminary: El informe incluye los primeros resultados que han sido verificados, aunque no todos los resultados son definitivos.
      • final: El informe está completo y ha sido verificado por la persona autorizada.
      • unknown: El sistema de origen/autor desconoce cuál de los estados se aplica actualmente a esta observación. Nota: Este concepto no debe utilizarse para "otro": se presume que se aplica uno de los estados enumerados, pero el sistema de origen/autor desconoce cuál.
    • category: Categoría de servicio del informe (1..*). (ver más)

      • system: URI del sistema de terminología (http://terminology.hl7.org/CodeSystem/v2-0074).
      • code: Código de la categoría en el sistema de terminología elegido (obligatorio)
      • display: Descripción de la categoría (opcional, recomendado)
    • code: Código del informe (1..*). Se debe informar como un CodeableConcept, aceptando una de las siguientes opciones:

      • text: Descripción del informe (obligatorio).

      • coding: Lista de codificaciones (al menos una obligatoria si no se informa text)

        • system: URI del sistema de terminología (SNOMED, LOINC, etc).
        • code: Código del concepto en el sistema de terminología elegido (obligatorio)
        • display: Descripción del código (opcional, recomendado)
    • subject: Referencia en el Payload del recurso "Patient" al que pertenece el informe.

    • performer: Referencia en el Payload del recurso "Organization" que realizó el informe.

    • effectiveDateTime: Fecha y hora en la que la observación o el estudio fue efectivamente realizado. Se puede enviar en hora local o en UTC. Quralo la almacena en formato UTC.

    • issued: Fecha y hora de emisión de la versión actual del informe. Se puede enviar en hora local o en UTC. Quralo la almacena en formato UTC.

    • conclusion: Texto breve con el resultado o interpretación.

    • presentedForm: Documento adjunto (preferentemente un archivo PDF) (1..*).

      • contentType: Tipo de contenido del documento (preferentemente "application/pdf").
      • title: Título del documento.
      • data: Documento en base64 (máximo 5 MB).
      • hash: Hash del documento.
      • creation: Fecha de creación del documento. Se puede enviar en hora local o en UTC. Quralo la almacena en formato UTC.
POST/fhir/r4/DiagnosticReport/$register

Permite la publicación de un nuevo informe de resultados

Ejemplo de Payload

json
{
  "resourceType": "Parameters",
  "parameter": [
    {
      "name": "patient",
      "resource": {
        "resourceType": "Patient",
        "id": "subject-patient",
        "name": [
          {
            "family": "Perez",
            "given": ["Juan", "Carlos"]
          }
        ],
        "identifier": [
          {
            "system": "http://www.renaper.gob.ar/dni",
            "value": "34111113",
            "type": {
              "coding": [
                {
                  "system": "http://terminology.hl7.org/CodeSystem/v2-0203",
                  "code": "NI"
                }
              ]
            }
          }
        ],
        "telecom": [
          { "system": "email",
            "value": "juan.perez@email.com",
            "use": "home"
          },
          { "system": "phone",
            "value": "+541149723000",
            "use": "mobile"
          }
        ],
        "gender": "male",
        "birthDate": "2004-10-28"
      }
    },
    {
      "name": "organization",
      "resource": {
        "resourceType": "Organization",
        "id": "performer-organization",
        "name": "Clínica IMA",
        "identifier": [
          {
            "system": "https://quralo.com/organizations",
            "value": "c94deab2-37fa-436e-b5ab-9d5d41f1b271"
          }
        ]
      }
    },
    {
      "name": "diagnosticReport",
      "resource": {
        "resourceType": "DiagnosticReport",
        "identifier": [
          {
            "system": "https://misistema.com/laboratorio/informes",
            "value": "INF-2024-000123"
          }
        ],
        "status": "registered",
        "category": [
          {
            "coding": [
              {
                "system": "http://terminology.hl7.org/CodeSystem/v2-0074",
                "code": "LAB",
                "display": "Laboratory"
              }
            ]
          }
        ],
        "code": {
          "text": "Hemograma completo"
        },
        "subject": {
          "reference": "Patient/subject-patient"
        },
        "performer": [
          {
            "reference": "Organization/performer-organization"
          }
        ],
        "effectiveDateTime": "2024-07-09T10:00:00Z",
        "issued": "2024-07-09T12:00:00Z",
        "conclusion": "Valores dentro de rangos normales."
      },
      "presentedForm": [
        {
          "contentType": "application/pdf",
          "title": "Informe PDF",
          "data": "JVBERi0xLjMKJZOMi54gUmVwb3J0TGFiIEdlbmVyYXRlZCBQREYgZG9jdW1lbnQgaHR0cDovL3d3dy5yZXBvcnRsYWIuY29tCjEgMCBvYmoKPDwKL0YxIDIgMCBSCj4+CmVuZG9iagoyIDAgb2JqCjw8Ci9CYXNlRm9udCAvSGVsdmV0aWNhIC9FbmNvZGluZyAvV2luQW5zaUVuY29kaW5nIC9OYW1lIC9GMSAvU3VidHlwZSAvVHlwZTEgL1R5cGUgL0ZvbnQKPj4KZW5kb2JqCjMgMCBvYmoKPDwKL0NvbnRlbnRzIDcgMCBSIC9NZWRpYUJveCBbIDAgMCA1OTUuMjc1NiA4NDEuODg5OCBdIC9QYXJlbnQgNiAwIFIgL1Jlc291cmNlcyA8PAovRm9udCAxIDAgUiAvUHJvY1NldCBbIC9QREYgL1RleHQgL0ltYWdlQiAvSW1hZ2VDIC9JbWFnZUkgXQo+PiAvUm90YXRlIDAgL1RyYW5zIDw8Cgo+PiAKICAvVHlwZSAvUGFnZQo+PgplbmRvYmoKNCAwIG9iago8PAovUGFnZU1vZGUgL1VzZU5vbmUgL1BhZ2VzIDYgMCBSIC9UeXBlIC9DYXRhbG9nCj4+CmVuZG9iago1IDAgb2JqCjw8Ci9BdXRob3IgKFwoYW5vbnltb3VzXCkpIC9DcmVhdGlvbkRhdGUgKEQ6MjAyNjA0MjkwMDAyMTArMDAnMDAnKSAvQ3JlYXRvciAoXCh1bnNwZWNpZmllZFwpKSAvS2V5d29yZHMgKCkgL01vZERhdGUgKEQ6MjAyNjA0MjkwMDAyMTArMDAnMDAnKSAvUHJvZHVjZXIgKFJlcG9ydExhYiBQREYgTGlicmFyeSAtIHd3dy5yZXBvcnRsYWIuY29tKSAKICAvU3ViamVjdCAoXCh1bnNwZWNpZmllZFwpKSAvVGl0bGUgKFwoYW5vbnltb3VzXCkpIC9UcmFwcGVkIC9GYWxzZQo+PgplbmRvYmoKNiAwIG9iago8PAovQ291bnQgMSAvS2lkcyBbIDMgMCBSIF0gL1R5cGUgL1BhZ2VzCj4+CmVuZG9iago3IDAgb2JqCjw8Ci9GaWx0ZXIgWyAvQVNDSUk4NURlY29kZSAvRmxhdGVEZWNvZGUgXSAvTGVuZ3RoIDg1Cj4+CnN0cmVhbQpHYXBRaDBFPUYsMFVcSDNUXHBOWVReUUtrP3RjPklQLDtXI1UxXjIzaWhQRU1fSCJaZyNaWVNWVGpWYk1YQ2tzTUJgWmAiKCEqNWUiVFs9UyU/TH4+ZW5kc3RyZWFtCmVuZG9iagp4cmVmCjAgOAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwNzMgMDAwMDAgbiAKMDAwMDAwMDEwNCAwMDAwMCBuIAowMDAwMDAwMjExIDAwMDAwIG4gCjAwMDAwMDA0MTQgMDAwMDAgbiAKMDAwMDAwMDQ4MiAwMDAwMCBuIAowMDAwMDAwNzY1IDAwMDAwIG4gCjAwMDAwMDA4MjQgMDAwMDAgbiAKdHJhaWxlcgo8PAovSUQgCls8OGQ4NmExNzMyMDNkNzc3NTIyNTZlYTJiMDhjOTYxMjg+PDhkODZhMTczMjAzZDc3NzUyMjU2ZWEyYjA4Yzk2MTI4Pl0KJSBSZXBvcnRMYWIgZ2VuZXJhdGVkIFBERiBkb2N1bWVudCAtLSBkaWdlc3QgKGh0dHA6Ly93d3cucmVwb3J0bGFiLmNvbSkKCi9JbmZvIDUgMCBSCi9Sb290IDQgMCBSCi9TaXplIDgKPj4Kc3RhcnR4cmVmCjk5OAolJUVPRgo=",
  "hash": "ef98d6a05fb49226ec4b05b4d9f7db1b8aab624223166800680f328ad7812d66",
  "creation": "2024-07-09T10:00:00Z"
}
]
}

Respuestas

A continuación se listan las posibles respuestas.

Caso exitoso

Código: 201 Created

Siendo RESOURCE_ID el identificador del recurso DiagnosticReport en Quralo y RESOURCE_VERSION la versión del recurso DiagnosticReport en el historial.

Importante – Identificación del recurso creado

Al crear recursos mediante POST, el identificador del recurso se informa en el header HTTP Location, que constituye la fuente canónica en respuestas de creación (201 Created). Si bien el body puede incluir el recurso, esto no está garantizado en todos los casos. Se recomienda obtener el ID exclusivamente desde el header Location.

Headers

  • Location: https://connect.quralo.com/fhir/r4/DiagnosticReport/{RESOURCE_ID}/_history/{RESOURCE_VERSION}
  • Content-Type: application/fhir+json
  • ETag: W/"{RESOURCE_VERSION}"
  • Last-Modified: YYYY-MM-DDTHH:MM:SS.SSSZ

Parámetros

El resourceType es Parameters y cada parámetro corresponde a un recurso DiagnosticReport y OperationOutcome.

  • diagnosticReport (Recurso DiagnosticReport)

    • resourceType: "DiagnosticReport"

    • id: Identificador UUID del informe en Quralo.

    • meta: Metadatos del informe.

      • versionId: Versión del informe recién creado en Quralo.
      • lastUpdated: Fecha y hora de la última actualización del informe.
    • status: Estado actual del informe en Quralo.

  • operationOutcome (Recurso OperationOutcome)

    • resourceType: "OperationOutcome"

    • issue: Lista de issues asociados a la respuesta:

      • severity: Severidad del issue.
      • code: Código del issue.
      • diagnostics: Diagnóstico del issue.

Ejemplo de Respuesta

json
{
    "resourceType": "Parameters",
    "parameter": [
        {
            "name": "diagnosticReport",
            "resource": {
                "resourceType": "DiagnosticReport",
                "id": "ea58008d-d5cd-4023-a916-d242ea10f55b",
                "meta": {
                    "versionId": 1,
                    "lastUpdated": "2026-05-04T12:33:15.887Z"
                },
                "status": "final"
            }
        },
        {
            "name": "issues",
            "resource": {
                "resourceType": "OperationOutcome",
                "issue": [
                    {
                        "severity": "warning",
                        "code": "invalid",
                        "diagnostics": "Patient.identifier[0].type: Code \"NI\" (http://terminology.hl7.org/CodeSystem/v2-0203) not found in value set"
                    },
                    {
                        "severity": "info",
                        "code": "invalid",
                        "diagnostics": "DiagnosticReport.category[0]: Value set \"http://hl7.org/fhir/ValueSet/diagnostic-service-sections\" could not be found."
                    },
                    {
                        "severity": "warning",
                        "code": "invalid",
                        "diagnostics": "DiagnosticReport.category[0]: Code \"LAB\" (http://terminology.hl7.org/CodeSystem/v2-0074) not found in value set"
                    },
                    {
                        "severity": "info",
                        "code": "invalid",
                        "diagnostics": "DiagnosticReport.presentedForm[0].contentType: Value set \"http://hl7.org/fhir/ValueSet/mimetypes\" could not be found."
                    }
                ]
            }
        }
    ]
}

Casos de error

Código: 400 Bad Request

Headers

  • Content-Type: application/fhir+json

Parámetros

  • resourceType Tipo de recurso para indicar errores (siguiendo el estándar FHIR es de tipo OperationOutcome).

  • issue Listado de problemas detectados en la petición.

    • severity: Severidad del error (ej. "error").
    • code: Código de error (ej. "invalid").
    • diagnostics: Mensaje descriptivo con el problema detallado.

Ejemplo de Respuesta

json
{
  "resourceType": "OperationOutcome",
  "issue": [
      {
          "severity": "error",
          "code": "exception",
          "diagnostics": "code.text is required and must be a string"
      }
  ]
}

Código: 401 Unauthorized

Headers

  • Content-Type: application/fhir+json

Ejemplo de Respuesta

json
{
  "resourceType": "OperationOutcome",
  "issue": [
      {
          "severity": "error",
          "code": "security",
          "diagnostics": "Authentication is required to access this resource."
      }
  ]
}

Código: 413 Content Too Large

Headers

  • Content-Type: application/fhir+json

Ejemplo de Respuesta

json
{
  "resourceType": "OperationOutcome",
  "issue": [
      {
          "severity": "error",
          "code": "too-costly",
          "diagnostics": "Request body exceeds the allowed size limit."
      }
  ]
}

Código: 422 Unprocessable Entity

Si se envía un recurso con datos inválidos o que no cumplen con las reglas de validación del negocio.

Headers

  • Content-Type: application/fhir+json

Ejemplo de Respuesta

json
{
  "resourceType": "OperationOutcome",
  "issue": [
      {
          "severity": "error",
          "code": "business-rule",
          "diagnostics": "Validation failed: the provided data does not meet business rules."
      }
  ]
}

Documentación de Quralo