Skip to main content
PUT
/
api
/
v1
/
icsr
/
{icsr_id}
Update ICSR Case
curl --request PUT \
  --url https://api.example.com/api/v1/icsr/{icsr_id} \
  --header 'Content-Type: application/json' \
  --data '
{
  "estado": "<string>",
  "gravedad": "<string>",
  "ea_causalidad": "<string>",
  "ea_desenlace": "<string>",
  "qc_realizado_por": "<string>",
  "qc_fecha": "<string>",
  "lt_fecha_envio_digemid": "<string>",
  "revision_senales": "<string>",
  "comentarios_adicionales": "<string>",
  "productos": [
    {}
  ],
  "concomitantes": [
    {}
  ],
  "seguimientos": [
    {}
  ],
  "password": "<string>",
  "final": "<string>",
  "picked_id": 123
}
'
{
  "id": 123,
  "created_at": "<string>",
  "rs_catalog_map": {
    "laboratorio": "<string>",
    "rs_vencimiento": "<string>"
  },
  "paciente_iniciales": "<string>",
  "productos": [
    {}
  ],
  "concomitantes": [
    {}
  ],
  "seguimientos": [
    {}
  ],
  "eventos": [
    {}
  ]
}

Endpoints

Get Case Details

GET /api/v1/icsr/{icsr_id}
Retrieves complete case details with enriched product catalog data. Authentication: Requires permission icsr:read

Update Case (Partial)

PUT /api/v1/icsr/{icsr_id}
Updates only the fields provided in the request body. Nested arrays (productos, concomitantes, seguimientos) are only replaced if explicitly included. Authentication: Requires permission icsr:update

Update Case (Full Replace)

PUT /api/v1/icsr/{icsr_id}/full
Always replaces nested arrays (productos, concomitantes, seguimientos) even if not modified. Use this for complete form submissions. Authentication: Requires permission icsr:update

Path Parameters

icsr_id
integer
required
The unique identifier of the ICSR case to update

Request Body

All fields from the Create Case endpoint are supported. Only include fields you want to update.

Common Update Scenarios

estado
string
Update case status (e.g., from “Pendiente” to “En progreso” to “Cerrado”)
gravedad
string
Update severity classification after initial assessment
ea_causalidad
string
Update causality assessment (e.g., “Posible” → “Probable” → “Definitiva”)
ea_desenlace
string
Update event outcome as case progresses
qc_realizado_por
string
Record who performed quality control review
qc_fecha
string
Record when quality control was performed
lt_fecha_envio_digemid
string
Record actual DIGEMID submission date
revision_senales
string
Add signal detection notes
comentarios_adicionales
string
Add additional case notes or comments

Updating Nested Arrays

productos
array
Replace all suspected products. Must include complete product objects with all desired fields.
concomitantes
array
Replace all concomitant medications. Must include complete objects.
seguimientos
array
Replace all followup entries. Must include complete objects.

Response (GET)

Get Case Details Response

id
integer
Case identifier
created_at
string
Creation timestamp
rs_catalog_map
object
Map of sanitary registration numbers to enriched product data from the catalog. Key is normalized registration number.
paciente_iniciales
string
Patient initials
productos
array
Array of suspected products. Each product may include enriched laboratorio and rs_vencimiento fields from catalog if registro_sanitario matches.
concomitantes
array
Array of concomitant medications
seguimientos
array
Array of followup entries
eventos
array
Array of adverse events (see Events API)
All other fields from the create response are included.

Response (PUT)

Returns the complete updated ICSR object with the same schema as GET.

Behavior

Partial Update (PUT /icsr/)

  • Only updates fields that are explicitly included in the request
  • Omitted fields retain their current values
  • Nested arrays (productos, concomitantes, seguimientos) are only replaced if the array field is included in the request
  • If you include productos: [] (empty array), all products will be deleted

Full Update (PUT /icsr//full)

  • Updates all provided scalar fields
  • Always replaces productos, concomitantes, and seguimientos arrays, even if not modified
  • Recommended for frontend form submissions where the complete state is always known

Audit Trail

  • All updates are logged with field-level change tracking
  • The audit log captures:
    • User who made the change
    • Timestamp
    • Before/after values for each changed field
    • Nested array changes (additions/removals)

Auto-Processing

When a case is updated:
  1. Missing Data Check: If required fields are now complete, no further auto-reply is sent. If new fields are missing, an auto-reply may be triggered.
  2. Status Progression: If a followup message is sent or evaluation is created, status automatically changes from “Pendiente” to “En progreso”.
  3. Catalog Enrichment: Product data is automatically enriched from the product catalog based on registro_sanitario matching.

Example Requests

Update Case Status Only

PUT /api/v1/icsr/1234

{
  "estado": "Cerrado",
  "comentarios_adicionales": "Caso cerrado tras evaluación completa. Causalidad confirmada como Probable."
}

Update Causality Assessment

PUT /api/v1/icsr/1234

{
  "ea_causalidad": "Probable",
  "ea_desenlace": "Recuperado",
  "qc_realizado_por": "Dr. Juan Perez",
  "qc_fecha": "2024-01-25"
}

Add Quality Control Data

PUT /api/v1/icsr/1234

{
  "qc_realizado_por": "Maria Garcia",
  "qc_fecha": "2024-01-22",
  "revision_senales": "No se identificaron señales nuevas. Evento conocido para amoxicilina.",
  "comentarios_adicionales": "Documentación completa. Listo para envío a DIGEMID."
}

Update Products Array

PUT /api/v1/icsr/1234

{
  "productos": [
    {
      "nombre_producto": "Amoxicilina",
      "ifa": "Amoxicilina trihidratada",
      "forma_farmaceutica": "Cápsula",
      "laboratorio_pais": "Laboratorio XYZ - Perú",
      "registro_sanitario": "EE-123456",
      "nro_lote": "LOT2024-002",
      "via_administracion": "Oral",
      "dosis_frecuencia": "500mg cada 8 horas",
      "fecha_inicio": "2024-01-12",
      "fecha_fin": "2024-01-16",
      "desaparecio_al_suspender": "si"
    },
    {
      "nombre_producto": "Amoxicilina + Ácido clavulánico",
      "ifa": "Amoxicilina trihidratada + Clavulanato de potasio",
      "forma_farmaceutica": "Tableta",
      "via_administracion": "Oral",
      "dosis_frecuencia": "875/125mg cada 12 horas",
      "fecha_inicio": "2024-01-16"
    }
  ]
}

Complete Form Submission (Full Update)

PUT /api/v1/icsr/1234/full

{
  "paciente_iniciales": "JD",
  "paciente_edad": 45,
  "paciente_sexo": "M",
  "paciente_peso": 72.5,
  "reportante_nombre": "Dr. Maria Garcia",
  "reportante_email": "[email protected]",
  "producto_sospechoso": "Amoxicilina 500mg",
  "descripcion_evento": "Paciente desarrolló rash eritematoso generalizado 3 días después de iniciar tratamiento con amoxicilina. El rash fue pruriginoso y se resolvió tras suspender el medicamento.",
  "fecha_inicio_evento": "2024-01-15",
  "fecha_fin_evento": "2024-01-18",
  "gravedad": "No grave",
  "ea_causalidad": "Probable",
  "ea_desenlace": "Recuperado",
  "estado": "Cerrado",
  "productos": [
    {
      "nombre_producto": "Amoxicilina",
      "ifa": "Amoxicilina trihidratada",
      "registro_sanitario": "EE-123456",
      "nro_lote": "LOT2024-001",
      "via_administracion": "Oral",
      "dosis_frecuencia": "500mg cada 8 horas",
      "fecha_inicio": "2024-01-12",
      "fecha_fin": "2024-01-16",
      "desaparecio_al_suspender": "si"
    }
  ],
  "concomitantes": [],
  "seguimientos": []
}

Example Response (GET)

{
  "id": 1234,
  "created_at": "2024-01-20T10:30:00Z",
  "paciente_iniciales": "JD",
  "paciente_edad": 45,
  "paciente_sexo": "M",
  "paciente_peso": 72.5,
  "reportante_nombre": "Dr. Maria Garcia",
  "reportante_email": "[email protected]",
  "producto_sospechoso": "Amoxicilina 500mg",
  "descripcion_evento": "Paciente desarrolló rash eritematoso generalizado...",
  "fecha_inicio_evento": "2024-01-15",
  "fecha_fin_evento": "2024-01-18",
  "gravedad": "No grave",
  "ea_causalidad": "Probable",
  "ea_desenlace": "Recuperado",
  "estado": "Cerrado",
  "qc_realizado_por": "Dr. Juan Perez",
  "qc_fecha": "2024-01-25",
  "rs_catalog_map": {
    "EE123456": {
      "laboratorio": "Laboratorio ABC S.A.",
      "rs_vencimiento": "2026-12-31"
    }
  },
  "productos": [
    {
      "id": 5678,
      "nombre_producto": "Amoxicilina",
      "ifa": "Amoxicilina trihidratada",
      "forma_farmaceutica": "Tableta",
      "laboratorio_pais": "Laboratorio ABC - Perú",
      "registro_sanitario": "EE-123456",
      "nro_lote": "LOT2024-001",
      "via_administracion": "Oral",
      "dosis_frecuencia": "500mg cada 8 horas",
      "fecha_inicio": "2024-01-12",
      "fecha_fin": "2024-01-16",
      "desaparecio_al_suspender": "si",
      "reaparecio_reexposicion": "no_aplica",
      "laboratorio": "Laboratorio ABC S.A.",
      "rs_vencimiento": "2026-12-31"
    }
  ],
  "concomitantes": [
    {
      "id": 9012,
      "nombre_producto": "Paracetamol",
      "dosis_frecuencia": "500mg PRN",
      "via_administracion": "Oral",
      "motivo_prescripcion": "Fiebre"
    }
  ],
  "seguimientos": [],
  "eventos": [
    {
      "id": 3456,
      "icsr_id": 1234,
      "texto": "Rash eritematoso generalizado",
      "tipo_notificacion": "Inicial",
      "fecha_inicio": "2024-01-15",
      "fecha_fin": "2024-01-18",
      "gravedad": "No grave",
      "causalidad": "Probable",
      "desenlace": "Recuperado",
      "meddra_pt_code": "10037844",
      "meddra_pt_term": "Rash",
      "is_from_narrative": true
    }
  ]
}

Delete Case

DELETE /api/v1/icsr/{icsr_id}
POST /api/v1/icsr/{icsr_id}:delete
Authentication: Requires permission icsr:delete and password confirmation

Request Body (Delete)

password
string
required
Current user’s password for confirmation

Delete Summary

Before deleting, check what will be removed:
GET /api/v1/icsr/{icsr_id}/delete-summary
Response:
{
  "followups": 5,
  "snapshots": 3
}

Delete Behavior

  • Requires password confirmation for security
  • Cascades to delete all related records:
    • Adverse events (icsr_eventos)
    • Products (icsr_productos)
    • Concomitant medications (icsr_concomitantes)
    • Followup tracking (icsr_seguimientos)
    • Followup messages (followup_messages)
    • Case snapshots (icsr_detail_snapshots)
  • Cannot be undone
  • Audit log entry is created before deletion

Example Delete Request

DELETE /api/v1/icsr/1234

{
  "password": "my_secure_password"
}

Delete Response

{
  "ok": true,
  "deleted_id": 1234
}

Error Responses

400 Bad Request

{
  "detail": [
    {
      "loc": ["body", "paciente_edad"],
      "msg": "value is not a valid integer",
      "type": "type_error.integer"
    }
  ]
}

401 Unauthorized (Delete)

{
  "detail": "Credenciales inválidas"
}

404 Not Found

{
  "detail": "ICSR no encontrado"
}

409 Conflict (Delete)

{
  "detail": "No se puede eliminar por otras restricciones. Considera soft-delete o ON DELETE CASCADE."
}

Validation

The API validates:
  • Case exists before updating
  • User has appropriate permissions
  • Data types match schema
  • Nested objects contain required fields
  • Date formats are valid ISO-8601
  • Referenced products exist in catalog (optional validation)

Best Practices

When to Use Partial Update

  • Updating case status or workflow fields
  • Adding QC review data
  • Updating timeline dates
  • Making small corrections

When to Use Full Update

  • Form submissions from frontend
  • Bulk data imports
  • When you always have the complete case state
  • Ensuring consistency across related fields

Updating Nested Arrays

  1. Get current state: Always GET the case first to retrieve current productos/concomitantes/seguimientos
  2. Modify locally: Make changes to the array in your application
  3. Send complete array: Send the full modified array in the update request
  4. Never send partial arrays: Sending [{"nombre_producto": "X"}] will delete all other products

Duplicate Detection

Check Duplicates for One Case

GET /api/v1/icsr/{icsr_id}/duplicates?days_window=60
Parameters:
  • days_window (integer, 1-365, default 60): Time window in days to search for duplicates based on event date
Response:
{
  "status": "review",
  "label": "Revisar",
  "color": "warning",
  "score": 0.65,
  "best_id": 1200,
  "matches": [
    {
      "id": 1200,
      "score": 0.65,
      "reasons": [
        "Iniciales iguales",
        "Fecha de nacimiento igual",
        "Producto sospechoso igual",
        "Narrativa similar (35%)"
      ],
      "fecha": "2024-01-14",
      "producto": "Amoxicilina 500mg",
      "iniciales": "JD",
      "narrativa": "Paciente desarrolló rash eritematoso..."
    }
  ]
}
Score Interpretation:
  • >= 0.80: Likely duplicate (status: “dup”, color: “danger”)
  • 0.45 - 0.79: Review recommended (status: “review”, color: “warning”)
  • < 0.45: Likely unique (status: “unique”, color: “success”)

Set Duplicate Decision

PUT /api/v1/icsr/{icsr_id}/dup
Request Body:
final
string
Manual decision: “unico” or “duplicado”. Set to null to clear override.
picked_id
integer
If final: "duplicado", the ID of the master case. Required when marking as duplicate.
Example:
{
  "final": "duplicado",
  "picked_id": 1200
}
Response:
{
  "ok": true,
  "dup_override": "duplicado",
  "dup_of_id": 1200
}

Bulk Duplicate Check

GET /api/v1/icsr/duplicates?ids=1234&ids=1235&ids=1236
or
GET /api/v1/icsr/duplicates?ids=1234,1235,1236
Response: Object keyed by case ID with duplicate detection results for each.

Build docs developers (and LLMs) love