# /ema/medicines/search

`POST /api/ema/medicines/search`

Price: 20 credits

Search the EU register of centrally authorised medicines. Narrows by trade name, active substance, INN, human or veterinary register, regulatory status, ATC code prefix, MeSH therapeutic area, pharmacotherapeutic group, marketing authorisation holder, target species, the text of the therapeutic indication, the nine regulatory flags, and the authorisation and last-update dates. Returns the full register record for every match, newest publication first.

## How to use it

The register covers only EU centrally authorised medicines, so a product authorised nationally in one member state is absent however it is spelled. Text filters match a substring anywhere in the field and are case-insensitive; `atc_code` is the one prefix filter, so `L01` keeps a whole ATC class. Withdrawn, refused and lapsed products stay on the register, and `status` is what separates them from the live ones — search without it and roughly a third of the answer is historical. `atcvet_code`, `pharmacotherapeutic_group_veterinary` and `species` are veterinary-only and the human records leave them empty, but the register fills them unevenly — the group on about seven in eight veterinary records and the ATCvet code and species on about one in six — so filtering on `species` returns a fraction of the veterinary register rather than all of it, and `category` is what selects the whole of it. Feed `url` to ema/medicines for the assessment overview and the published PDFs.

## Parameters

- `access-token` (string, required)

## Request body

- `timeout` (integer) — Max scrapping execution timeout (in seconds) (default: 300; min: 20; max: 1500)
- `name` (string, nullable) — Substring of the medicine's trade name (examples: "keytruda", "insulin"; minLength: 1)
- `active_substance` (string, nullable) — Substring of the active substance (examples: "pembrolizumab"; minLength: 1)
- `inn` (string, nullable) — Substring of the international non-proprietary or common name (examples: "adalimumab"; minLength: 1)
- `category` (string, nullable) — Human or veterinary register. Unset returns both (one of: "Human", "Veterinary")
- `status` (string, nullable) — Regulatory status of the medicine on the register (one of: "Authorised", "Withdrawn", "Application withdrawn", "Refused", "Lapsed", "Opinion", "Expired", "Revoked", "Suspended", "Opinion under re-examination", "Withdrawn from rolling review")
- `atc_code` (string, nullable) — ATC code, matched as a prefix, so L01 keeps every antineoplastic agent (examples: "L01FF02", "L01"; minLength: 1)
- `therapeutic_area` (string, nullable) — Substring of a MeSH therapeutic area (examples: "Melanoma"; minLength: 1)
- `pharmacotherapeutic_group` (string, nullable) — Substring of the pharmacotherapeutic group (examples: "Antineoplastic agents"; minLength: 1)
- `marketing_authorisation_holder` (string, nullable) — Substring of the authorisation holder's name (examples: "Novartis"; minLength: 1)
- `indication` (string, nullable) — Substring of the therapeutic indication text (examples: "melanoma"; minLength: 1)
- `species` (string, nullable) — Target species of a veterinary medicine (examples: "Dogs"; minLength: 1)
- `accelerated_assessment` (boolean, nullable) — Assessed under the accelerated timetable
- `additional_monitoring` (boolean, nullable) — Subject to additional safety monitoring
- `advanced_therapy` (boolean, nullable) — Advanced therapy medicinal product
- `biosimilar` (boolean, nullable) — Authorised as a biosimilar
- `conditional_approval` (boolean, nullable) — Holds a conditional marketing authorisation
- `exceptional_circumstances` (boolean, nullable) — Authorised under exceptional circumstances
- `generic` (boolean, nullable) — Authorised as a generic
- `orphan_medicine` (boolean, nullable) — Carries an orphan designation
- `prime_priority_medicine` (boolean, nullable) — Supported under the PRIME scheme
- `authorised_from` (string, nullable) — Keep medicines authorised on or after this date, YYYY-MM-DD (examples: "2020-01-01")
- `authorised_to` (string, nullable) — Keep medicines authorised on or before this date, YYYY-MM-DD (examples: "2024-12-31")
- `updated_from` (string, nullable) — Keep records the register updated on or after this date, YYYY-MM-DD (examples: "2026-09-01")
- `count` (integer, required) — Max number of medicines to return (min: 1; max: 3000)

## Response

### 200 — Successful Response

- `@type` (string) (default: "EmaMedicine")
- `id` (string, required)
- `name` (string) (default: "")
- `category` (string) (default: "")
- `status` (string) (default: "")
- `url` (string) (default: "")
- `active_substance` (string, nullable)
- `inn_or_common_name` (array) (default: [])
- `therapeutic_areas` (array) (default: [])
- `atc_code` (string, nullable)
- `atcvet_code` (string, nullable)
- `pharmacotherapeutic_group` (string, nullable)
- `pharmacotherapeutic_group_veterinary` (string, nullable)
- `species` (array) (default: [])
- `marketing_authorisation_holder` (string, nullable)
- `therapeutic_indication` (string, nullable)
- `revision_number` (string, nullable)
- `opinion_status` (string, nullable)
- `latest_procedure_affecting_product_information` (string, nullable)
- `is_accelerated_assessment` (boolean, nullable)
- `is_under_additional_monitoring` (boolean, nullable)
- `is_advanced_therapy` (boolean, nullable)
- `is_biosimilar` (boolean, nullable)
- `is_conditional_approval` (boolean, nullable)
- `is_exceptional_circumstances` (boolean, nullable)
- `is_generic` (boolean, nullable)
- `is_orphan_medicine` (boolean, nullable)
- `is_prime_priority_medicine` (boolean, nullable)
- `is_patient_safety_flagged` (boolean, nullable)
- `published_date` (string, nullable)
- `updated_date` (string, nullable)
- `marketing_authorisation_date` (string, nullable)
- `european_commission_decision_date` (string, nullable)
- `opinion_adopted_date` (string, nullable)
- `start_of_evaluation_date` (string, nullable)
- `start_of_rolling_review_date` (string, nullable)
- `withdrawal_of_application_date` (string, nullable)
- `withdrawal_expiry_revocation_lapse_date` (string, nullable)
- `refusal_of_marketing_authorisation_date` (string, nullable)
- `suspension_of_marketing_authorisation_date` (string, nullable)

## Errors

### 422 — Validation Error

A date field was not YYYY-MM-DD.

What to do: Check the fields against this schema. A URN with the wrong prefix is the most common cause.

- `detail` (array)
  - `loc` (array, required)
  - `msg` (string, required)
  - `type` (string, required)
  - `input` (any)
  - `ctx` (object)

### 408

The request ran past its time limit

What to do: Raise `timeout` in the request body, up to the maximum this endpoint documents. Lowering `count` or turning off the `with_*` flags also helps, because less work finishes sooner.

### 412

Nothing on the register matched those filters.

What to do: Retrying will not help: either the entity does not exist, or the input points at a different one.

### 429

Too many requests: a rate limit or a usage window is exhausted

What to do: When the response carries an X-Retry-After header, wait that many seconds and retry: the same number is in the body as `detail.retry_after`, and the limit clears once that window passes. The message in the body names the limit that was hit.

### 500

Something broke on our side

What to do: Retrying will not help. If it keeps happening, send us the X-Request-ID from the response headers.

### 529

Rate limit reached, or the endpoint is overloaded

What to do: Wait at least 30 seconds, then retry.

## Response envelope

Success: Array of objects (may be empty if no results)

Error: Error may coexist with partial results if it occurs mid-execution. Check X-Error header and status code.

Every response carries these headers:

- `X-Error` — Error message text (present only on error)
- `X-Request-ID` — Unique request identifier
- `X-Execution-Time` — Execution time in seconds
- `X-Result-Count` — How many records the body carries. 0 means an empty result, which is a normal answer and not by itself an error. A non-zero count can come back together with X-Error when the failure happened partway through — read this header and X-Error independently.
- `X-Total-Available-Results` — How many records exist for this query, when the endpoint can say. On a `dry_run` request this is the answer and the body is empty. It saturates: the endpoint's documented maximum means 'at least that many', any smaller number is exact.
- `X-Warning` — Present when the request body carried keys this endpoint does not document. They were ignored, so any filter you meant to apply through them did not apply. Check the spelling against this schema and retry.
- `X-Retry-After` — Seconds to wait before retrying. Present only on 429.

