mariozabala/cima-laravel-client

Laravel client for the Spanish AEMPS CIMA (Centro de Información Online de Medicamentos) REST API v1.23

Maintainers

Package info

github.com/mariozabala/cima-laravel-client

pkg:composer/mariozabala/cima-laravel-client

Transparency log

Statistics

Installs: 4

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-08-23 17:04 UTC

This package is auto-updated.

Last update: 2026-08-23 17:07:38 UTC


README

Latest Version on Packagist GitHub Tests Action Status Total Downloads License

A robust, modern Laravel client to interact with the Spanish AEMPS CIMA (Centro de Información Online de Medicamentos de la Agencia Española de Medicamentos y Productos Sanitarios) REST API v1.23.

Table of Contents

What is CIMA?

CIMA (Centro de Información Online de Medicamentos) is the official online medicine information registry provided by the Spanish Agency for Medicines and Medical Devices (AEMPS - Agencia Española de Medicamentos y Productos Sanitarios). It is the authoritative public source of regulatory data for human medicinal products authorized in Spain, providing details regarding active substances, pharmaceutical forms, indications, Summary of Product Characteristics (SmPC / Ficha Técnica), patient leaflets (Prospectos), safety warnings, supply disruptions, and risk minimization educational materials.

Features

  • Complete CIMA REST API v1.23 coverage: Full implementation of all endpoints, models, filters, and formats.
  • Fluent Query Builder: Clean, chainable API for search and multi-criteria filtering.
  • Full SmPC Search: Targeted section full-text inclusion/exclusion search (POST /buscarEnFichaTecnica).
  • Rich Typed DTO Models: Fully typed, null-safe objects mapping the entire CIMA response taxonomy.
  • Supply Shortages & Safety Tracking: Real-time supply disruption alerts and official AEMPS safety communications.
  • Segmented Document Support: Multi-format content retrieval (JSON, HTML, Plain Text) and static direct URL generation.
  • Laravel First: Auto-discovery ServiceProvider, customizable configuration publishing, and Cima Facade.
  • Defensive API Handling: POSIX millisecond timestamp conversion, fallback defaults, and automated error logging for malformed records.

Requirements

  • PHP: ^8.1 | ^8.2 | ^8.3
  • Laravel Framework: ^10.0 | ^11.0 | ^12.0
  • PHP Extensions:
    • ext-json
    • ext-curl

Installation

Install the package into your Laravel project via Composer:

composer require mariozabala/cima-laravel-client

The package includes Laravel package discovery, so the CimaServiceProvider and Cima facade will be registered automatically.

Configuration

Publish the configuration file using Artisan:

php artisan vendor:publish --tag=cima-config

This creates the config/cima.php file in your application:

return [
    /*
    |--------------------------------------------------------------------------
    | CIMA API Base URL
    |--------------------------------------------------------------------------
    |
    | Base URL for the official AEMPS CIMA REST API v1.23.
    |
    */
    'base_url' => env('CIMA_BASE_URL', 'https://cima.aemps.es/cima/rest'),

    /*
    |--------------------------------------------------------------------------
    | Request Timeout
    |--------------------------------------------------------------------------
    |
    | Timeout in seconds for HTTP requests sent to the CIMA REST API.
    |
    */
    'timeout' => env('CIMA_TIMEOUT', 10.0),

    /*
    |--------------------------------------------------------------------------
    | Logging Channel
    |--------------------------------------------------------------------------
    |
    | Specify the log channel to use when skipping corrupted or malformed
    | API records. Set to null to use the default application log channel.
    |
    */
    'log_channel' => env('CIMA_LOG_CHANNEL', null),
];

You can optionally configure environment variables in your .env file:

CIMA_BASE_URL=https://cima.aemps.es/cima/rest
CIMA_TIMEOUT=15.0
CIMA_LOG_CHANNEL=stack

Usage Guide

You can access the client via the Cima Facade or by injecting MarioZabala\Cima\CimaClientInterface.

1. Resolving Medications

Retrieve a single medication by its official Spanish Registration Number (Número de Registro) or National Code (Código Nacional):

use MarioZabala\Cima\Facades\Cima;

// By Spanish Registration Number (nregistro)
$medication = Cima::findByRegistrationNumber('51347');

// Or by National Code (Código Nacional - cn)
$medication = Cima::findByNationalCode('712729');

// Access medication properties
echo $medication->getName();                         // e.g. PARACETAMOL KERN PHARMA 1 g COMPRIMIDOS EFG
echo $medication->getLaboratory();                   // e.g. KERN PHARMA, S.L.
echo $medication->getStatus()->getFormattedDate();   // e.g. 15/03/1996
echo $medication->getStatus()->isAuthorized();       // true
echo $medication->isCommercialized();                // true
echo $medication->requiresPrescription();            // false

// Active substances and excipients
foreach ($medication->getActiveIngredients() as $substance) {
    echo "{$substance->getName()}: {$substance->getAmount()} {$substance->getUnit()}\n";
}

// Convert DTO to an associative array
$arrayData = $medication->toArray();

2. Searching & Fluent Filtering

Search the registry using chainable filter conditions:

use MarioZabala\Cima\Facades\Cima;

$results = Cima::filterByName('paracetamol')
    ->filterByCommercialized(true)
    ->filterByPrescription(false)
    ->filterByAuthorized(true)
    ->page(1)
    ->search();

echo "Total items found: {$results->total}\n";

foreach ($results->medications as $med) {
    echo "[{$med->getRegistrationNumber()}] {$med->getName()}\n";
}

Available Filters:

  • filterByName(string $name)
  • filterByLaboratory(string $lab)
  • filterByActiveIngredient1(string $name)
  • filterByActiveIngredient2(string $name)
  • filterByActiveIngredientId1(string $id)
  • filterByActiveIngredientId2(string $id)
  • filterByActiveIngredientCount(int $count)
  • filterByNationalCode(string $cn)
  • filterByAtcCode(string $atc)
  • filterByRegistrationNumber(string $nregistro)
  • filterByCommercialized(bool $bool)
  • filterByAuthorized(bool $bool)
  • filterByPrescription(bool $bool)
  • filterByTriangle(bool $bool) (Black triangle monitoring)
  • filterByOrphan(bool $bool) (Orphan drug)
  • filterByBiosimilar(bool $bool)
  • filterByNarcotic(bool $bool)
  • filterByPsychotropic(bool $bool)
  • filterByNarcoticOrPsychotropic(bool $bool)
  • filterByRegulationType(int $type) (1: Non-substitutable biologic, 2: Respiratory, etc.)
  • filterByVmpId(string $vmpId)
  • page(int $page)
  • resetFilters()

3. Full-Text Search in SmPC (Ficha Técnica)

Perform full-text search queries within specific sections of the Summary of Product Characteristics:

use MarioZabala\Cima\Facades\Cima;

$criteria = [
    [
        'seccion' => '4.1', // 4.1: Therapeutic Indications
        'texto' => 'artritis reumatoide',
        'contiene' => 1,    // 1: Must contain, 0: Must NOT contain
    ],
];

$results = Cima::searchInTechnicalSheet($criteria);

foreach ($results->medications as $med) {
    echo $med->getName() . PHP_EOL;
}

4. Commercial Presentations & Packaging

Query authorized presentations and trade packages:

use MarioZabala\Cima\Facades\Cima;

// Find specific presentation by National Code (cn)
$presentation = Cima::findPresentation('712729');

echo $presentation->getName();
echo $presentation->isCommercialized() ? 'Commercialized' : 'Not Marketed';

// Search presentations with filters
$list = Cima::searchPresentations([
    'nombre' => 'ibuprofeno',
    'comerc' => 1,
]);

5. Supply Shortages (Problemas de Suministro)

Query active and historical supply disruptions:

use MarioZabala\Cima\Facades\Cima;

// Get all active supply disruptions in Spain
$shortages = Cima::getSupplyShortages();

// Query shortage history for a specific product by National Code
$productShortages = Cima::getSupplyShortage('659843');

foreach ($productShortages as $shortage) {
    echo "Shortage: {$shortage->getName()}\n";
    echo "Start: {$shortage->getFormattedStartDate()} | End: {$shortage->getFormattedEndDate()}\n";
    echo "Status: " . ($shortage->isActive() ? 'Active Shortage' : 'Resolved') . "\n";
}

6. Clinical Concepts (VMP / VMPP)

Search clinical concepts based on the Spanish Virtual Medicinal Product (VMP) and Virtual Medicinal Product Package (VMPP) models:

use MarioZabala\Cima\Facades\Cima;

$concepts = Cima::searchClinicalDescriptions([
    'nombre' => 'aspirina',
]);

foreach ($concepts as $concept) {
    echo "VMP: [{$concept->getVmp()}] {$concept->getVmpDescription()}\n";
    echo "Commercial presentations count: {$concept->getMarketedPresentationsCount()}\n";
}

7. Safety Notes & Educational Materials

Retrieve official AEMPS safety warnings and risk-minimization educational guides:

use MarioZabala\Cima\Facades\Cima;

// Official AEMPS safety warning communications
$safetyNotes = Cima::getSafetyNotes('51347');
foreach ($safetyNotes as $note) {
    echo "[{$note->getReference()}] {$note->getSubject()} ({$note->getUrl()})\n";
}

// Risk-minimization educational guides (videos, patient cards, HCP guides)
$materials = Cima::getSafetyMaterials('51347');
if ($materials) {
    if ($materials->hasVideo()) {
        echo "Video: {$materials->getVideo()}\n";
    }

    foreach ($materials->getPatientDocuments() as $doc) {
        echo "Patient Document: {$doc->getNom()} -> {$doc->getUrl()}\n";
    }
}

8. Segmented Documents & HTML URLs

Access structured sections of Summary of Product Characteristics (SmPC) or Patient Leaflets, or generate direct URLs:

use MarioZabala\Cima\Facades\Cima;
use MarioZabala\Cima\Models\Document;

// List section index metadata (1: SmPC, 2: Leaflet)
$sections = Cima::getDocumentSections(Document::TYPE_SMPC, '51347');

// Fetch section content with content negotiation ('json', 'html', or 'text')
$htmlSection = Cima::getDocumentSectionContent(
    Document::TYPE_SMPC,
    '51347',
    '4.1',     // Section 4.1: Indications
    'html'     // Format
);

// Generate direct official AEMPS HTML viewing URLs
$smpcUrl = Cima::getSmPCHtmlUrl('51347');                       // Full SmPC
$sectionUrl = Cima::getSmPCHtmlUrl('51347', '4.1');            // Section 4.1 SmPC
$leafletUrl = Cima::getLeafletHtmlUrl('51347');                // Full Leaflet

9. Classification Catalogs (Maestras)

Retrieve master reference taxonomies:

use MarioZabala\Cima\Facades\Cima;

// 1: Active substances, 3: Dosage forms, 4: Routes of administration, 6: Laboratories, 7: ATCs
$laboratories = Cima::getMasterData(6, ['nombre' => 'bayer']);

foreach ($laboratories as $lab) {
    echo "ID: {$lab->getId()} | Name: {$lab->getName()}\n";
}

10. Audit Changelog (Registro de Cambios)

Track new authorizations, revocations, and modifications since a given date:

use MarioZabala\Cima\Facades\Cima;

$changelog = Cima::getChangeLog('01/01/2024');

foreach ($changelog->entries as $entry) {
    echo "Medication [{$entry->getRegistrationNumber()}]: {$entry->getProcess()} on {$entry->getFormattedDate()}\n";
}

Error Handling

The package provides a clean exception hierarchy for handling network, API, and resource resolution failures:

\Throwable
 └── MarioZabala\Cima\Exceptions\CimaException (interface)
      └── MarioZabala\Cima\Exceptions\HttpException
           └── MarioZabala\Cima\Exceptions\CimaApiException
                └── MarioZabala\Cima\Exceptions\CimaNotFoundException (HTTP 404)

Catching Exceptions:

use MarioZabala\Cima\Facades\Cima;
use MarioZabala\Cima\Exceptions\CimaException;
use MarioZabala\Cima\Exceptions\CimaNotFoundException;
use MarioZabala\Cima\Exceptions\CimaApiException;

try {
    $medication = Cima::findByRegistrationNumber('9999999');
} catch (CimaNotFoundException $e) {
    // 404 Not Found or empty result
    logger()->warning("Medication not found: " . $e->getMessage());
} catch (CimaApiException $e) {
    // Other API errors (500, 503, timeout, etc.)
    logger()->error("CIMA API Error [{$e->getStatusCode()}]: " . $e->getMessage());
} catch (CimaException $e) {
    // Catch-all for any CIMA package exception
    logger()->error("CIMA Client error: " . $e->getMessage());
}

Testing

Run the PHPUnit test suite:

composer test
# or
./vendor/bin/phpunit

To run code styling checks:

./fixer.sh

Disclaimer & Legal Notice

Important

Unofficial Community Package: This software is an independent, open-source community package and is NOT affiliated with, endorsed by, sponsored by, or officially connected to the Spanish Agency for Medicines and Medical Devices (AEMPS - Agencia Española de Medicamentos y Productos Sanitarios) or the Spanish Ministry of Health (Ministerio de Sanidad).

  • Data Proxy & Integrity: This package acts strictly as an HTTP client and data abstraction layer to consume the publicly accessible AEMPS CIMA REST API v1.23. It does not alter, falsify, or modify the clinical or regulatory content served by official government endpoints.
  • Medical Disclaimer: The data retrieved via this library is intended for technical, educational, and informational integration purposes only. It does not constitute medical advice, diagnosis, treatment, or formal prescription guidance. Healthcare professionals must exercise independent clinical judgment and consult official authoritative publications and regulatory SmPC documents directly before making clinical decisions.
  • Availability: Neither the authors of this package nor AEMPS guarantee uninterrupted availability or real-time correctness of third-party public API endpoints.

License

This project is open-sourced software licensed under the MIT License.

Copyright (c) 2021-2026 Mario Zabala