Documentación Mercado Libre
Descubre toda la información que debes conocer sobre las APIs de Mercado Libre.
Documentación
Pharma - Medicamentos Recetados
Esta documentación cubre los endpoints disponibles para la gestión de recetas médicas en pedidos Pharma de Mercado Libre.
Flujo de validación de recetas en orders Pharma
El flujo de validación de recetas sigue tres etapas:
- Identificar las orders de pharma a partir de notificaciones de orders.
- Verificar, mediante la API de items, si el item de la order requiere receta médica.
- Continuar con la validación de las recetas a través de los endpoints descritos en las próximas secciones.
Identificar orders Pharma
Filtre las orders recibidas en el tópico de orders a través de las notificaciones para identificar los pedidos de tipo Pharma.
Identificación actual
Una order se considera Pharma cuando posee static_tags con el valor "pharma".
Próxima actualización
Hay una migración en curso: en los próximos meses dejaremos de utilizar static_tags = "pharma" y la identificación de orders Pharma pasará a realizarse únicamente mediante flow.pharma.
Comparación entre la estructura actual y la nueva:
| Estructura actual | Nueva estructura |
|---|---|
|
|
Verificar si el item requiere receta médica
Para cada order Pharma, consulte la API de items correspondiente al item de la order. Dentro del array attributes del payload, busque el atributo con id "IS_ELIGIBLE_FOR_PRESCRIPTION". El item requiere receta médica cuando este atributo esté presente con value_id igual a "242085" (value_name = "Sí").
Ejemplo del atributo relevante en el payload de /items:
"attributes": [
{
"id": "IS_ELIGIBLE_FOR_PRESCRIPTION",
"name": "Es elegible para receta",
"value_id": "242085",
"value_name": "Sí",
"value_type": "boolean",
"attribute_group_id": "OTHERS",
"attribute_group_name": "Otros"
}
]
Validar la receta médica
Una vez confirmado que el item requiere receta, utilice los endpoints documentados en las secciones siguientes para completar el flujo de validación, comenzando por el listado de recetas pendientes.
Sellers con sucursales
La API soporta dos tipos de seller:
- Seller sin sucursales → opera con una única tienda. El alcance de la solicitud se identifica únicamente por el seller_id.
- Seller con sucursales → opera con múltiples tiendas, cada una identificada por un store_id. El alcance se identifica por el par (seller_id, store_id).
El campo store_id es opcional en todos los endpoints (list, accept, reject, download y bulk download). Su presencia o ausencia indica el conjunto de recetas que se desea consultar o gestionar:
- Sin store_id → opera sobre recetas de sellers sin sucursales.
- Con store_id → opera sobre recetas de la sucursal indicada.
Los dos conjuntos están aislados: no se mezclan en un mismo resultado y no pueden ser accedidos de forma cruzada.
Cómo obtener el store_id
El store_id se obtiene del response del endpoint /orders. Cuando el pedido proviene de un seller con múltiples sucursales, el response incluye el campo stock.store_id.
- Seller con sucursales → response incluye stock.store_id. El alcance se identifica por el par (seller_id, store_id).
- Seller con sucursales (pedidos Turbo) → response sin store_id. El alcance se identifica únicamente por seller_id.
Reglas para accept, reject y download
| Escenario | store_id en la solicitud | Resultado |
|---|---|---|
| Seller sin sucursales | omitido | 200 — operación permitida |
| Seller con sucursales | omitido | 403 Forbidden |
| Seller con sucursales, pedido Turbo | omitido (no disponible en /orders) | 200 — operación permitida |
| Seller con sucursales, store_id correcto | igual al de la sucursal | 200 — operación permitida |
| Seller con sucursales, store_id diferente | diferente al de la sucursal | 403 Forbidden |
| Seller con sucursales | omitido | 403 Forbidden |
Reglas para el listado
- Con store_id → retorna únicamente recetas de la sucursal indicada.
- Sin store_id → retorna únicamente recetas de sellers sin sucursales.
En ningún escenario la respuesta mezcla ambos conjuntos. Enviar store_id para un seller sin sucursales, u omitirlo para un seller con sucursales, retorna 403 Forbidden.
Endpoints
En todos los endpoints, el path param {flow} debe ser prescription.
1. Listar recetas pendientes
curl -L -X GET \
https://api.mercadolibre.com/v1/prescription/attachments \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer $ACCESS_TOKEN'
Lista las recetas pendientes de validación para el seller. Permite consultar qué pedidos tienen recetas pendientes sin necesidad de conocer los order_ids previamente.
Parámetros de query
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
store_id |
string | No | Identificador de la sucursal. Obligatorio para sellers con múltiples sucursales. Cuando se omite, retorna únicamente recetas de pedidos sin sucursal. |
order_id |
string | No | Filtra por un pedido específico |
status |
string | No (default: WAITING_VALIDATION) | Filtra por status de la receta. Ver tabla de valores permitidos. |
page |
integer | No (default: 1) | |
per_page |
integer | No (default: 20, máx: 100) | |
created_after |
string | No | Filtra registros creados después de la fecha indicada |
sort |
string | No (default: created_at:asc) | Valores: created_at:asc, created_at:desc |
| Valores del parámetro status | Descripción |
|---|---|
WAITING_VALIDATION |
Receta pendiente de validación. |
ACCEPTED |
Receta aceptada. |
REJECTED |
Receta rechazada. El archivo permanece disponible para descarga por hasta 7 días tras el rechazo. |
Ejemplo de request:
curl -L -X GET \
https://api.mercadolibre.com/v1/prescription/attachments?store_id=12345678&page=1&per_page=20 \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer APP_USR-123467899999.....'
Response
| Status | Descripción | Respuesta |
|---|---|---|
| 200 | Éxito |
Una lista vacía retorna 200 con |
| 200 | Éxito — filtro REJECTED |
|
| 400 | Bad Request |
|
| 401 | No autorizado. Token ausente o inválido. |
|
| 429 | Rate limit excedido |
|
| 500 | Error interno |
|
| Motivos de rechazo (rejection_reason) | Descripción |
|---|---|
seller_reject_file_expired |
Receta vencida |
seller_reject_file_invalid_product |
El medicamento no corresponde al item del pedido |
seller_reject_file_quantity |
La cantidad no coincide con el pedido |
seller_reject_file_data |
Datos del médico inválidos |
seller_reject_file_already_used |
Receta ya utilizada en otro pedido |
seller_reject_file_invalid |
El archivo no es una receta o es ilegible |
2. Descargar receta
curl -L -X GET \
https://api.mercadolibre.com/v1/prescription/attachment/download \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer $ACCESS_TOKEN'
Descarga una receta específica mediante su attachment_id. Esta llamada registra la descarga del archivo, lo que es un requisito previo para poder aceptar o rechazar la receta.
Parámetros de query
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
attachment_id |
string | Sí | Identificador de la receta a descargar |
store_id |
string | No | Identificador de la sucursal. Obligatorio para sellers con múltiples sucursales. |
status |
string | No (default: WAITING_VALIDATION) | Valores: WAITING_VALIDATION, ACCEPTED |
Ejemplo de request:
curl -L -X GET \
https://api.mercadolibre.com/v1/prescription/attachment/download?attachment_id=MLM_112233466_0123ab3430000.pdf&store_id=12345 \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer APP_USR-123467899999.....'
Response
| Status | Descripción | Respuesta |
|---|---|---|
| 200 | Éxito | Retorna el contenido binario de la receta (PDF). Habilita las operaciones de accept/reject para este attachment_id. |
| 400 | Bad Request |
|
| 401 | No autorizado. Token ausente o inválido. |
|
| 403 | Forbidden. El store_id no coincide con el del attachment. |
|
| 404 | Receta no encontrada |
|
| 410 | Attachment gone |
|
| 429 | Rate limit excedido |
|
| 500 | Error interno |
|
3. Aceptar receta
curl -L -X POST \
https://api.mercadolibre.com/v1/prescription/attachment/accept \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer' \
--data '{
"attachment_id": "$ATTACHMENT_ID",
"store_id": "$STORE_ID"
}'
Acepta una receta específica mediante su attachment_id. Requiere que la receta haya sido descargada previamente y que su status sea WAITING_VALIDATION.
Parámetros del body
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
attachment_id |
string | Sí | Identificador de la receta a aceptar |
store_id |
string | No | Identificador de la sucursal. Obligatorio para sellers con múltiples sucursales. Enviar store_id para un seller sin sucursales retorna 403. |
Ejemplo de request:
curl --location 'https://api.mercadolibre.com/v1/prescription/attachment/accept' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer APP_USR-123467899999.....' \
--data '{
"attachment_id": "MLM_112233466_0123ab3430000.pdf",
"store_id": "123456789"
}
'
Response
| Status | Descripción | Respuesta |
|---|---|---|
| 200 | Éxito |
|
| 400 | JSON inválido en el body |
|
| 400 | Error de validación |
|
| 401 | No autorizado. Token ausente o inválido. |
|
| 403 | Forbidden. El store_id no coincide. |
|
| 404 | Receta no encontrada |
|
| 422 | Receta no descargada previamente |
|
| 422 | Receta ya aceptada |
|
| 422 | Receta ya rechazada |
|
| 422 | Receta no está en estado WAITING_VALIDATION |
|
| 429 | Rate limit excedido |
|
| 500 | Error interno |
|
4. Rechazar receta
curl -L -X POST \
https://api.mercadolibre.com/v1/prescription/attachment/reject \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer' \
--data '{
"attachment_id": "$ATTACHMENT_ID",
"store_id": "$STORE_ID",
"reason": "$REASON"
}'
Rechaza una receta. Requiere que la receta haya sido descargada previamente y que se indique un motivo de rechazo válido.
Parámetros del body
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
attachment_id |
string | Sí | Identificador de la receta a rechazar |
reason |
string | Sí | Motivo de rechazo. Ver tabla de valores permitidos. |
store_id |
string | No | Identificador de la sucursal. Obligatorio para sellers con múltiples sucursales. Enviar store_id para un seller sin sucursales retorna 403. |
| Valores del parámetro reason | Descripción |
|---|---|
seller_reject_file_expired |
Receta vencida |
seller_reject_file_invalid_product |
El medicamento no corresponde al item del pedido |
seller_reject_file_quantity |
La cantidad no coincide con el pedido |
seller_reject_file_data |
Datos del médico inválidos |
seller_reject_file_already_used |
Receta ya utilizada en otro pedido |
seller_reject_file_invalid |
El archivo no es una receta o es ilegible |
Ejemplo de request:
curl -L -X POST \
https://api.mercadolibre.com/v1/prescription/attachment/reject \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer APP_USR-123467899999.....' \
--data '{
"attachment_id": "MLA_423423_4324324ad325.pdf",
"store_id": "123456789",
"reason": "seller_reject_file_expired"
}'
Response
| Status | Descripción | Respuesta |
|---|---|---|
| 200 | Éxito |
|
| 400 | Motivo de rechazo inválido |
|
| 400 | JSON inválido en el body |
|
| 401 | No autorizado. Token ausente o inválido. |
|
| 403 | Forbidden. El store_id no coincide. |
|
| 404 | Receta no encontrada |
|
| 404 | Pedido no encontrado |
|
| 422 | Receta no descargada previamente |
|
| 422 | Receta ya aceptada |
|
| 422 | Receta ya rechazada |
|
| 422 | Receta no está en estado WAITING_VALIDATION |
|
| 422 | Saldo insuficiente del seller |
|
| 429 | Rate limit excedido |
|
| 500 | Error interno |
|
5. Descarga masiva de recetas
curl -L -X POST \
https://api.mercadolibre.com/v1/prescription/attachments/download \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer' \
--data '{
"attachment_ids": [
$ATTACHMENT_ID_1,
$ATTACHMENT_ID_2,
$ATTACHMENT_ID_3,
],
"store_id": "$STORE_ID"
}
'
Descarga múltiples recetas en una única llamada. Retorna un archivo ZIP con todos los PDFs solicitados.
Parámetros del body
| Parámetro | Tipo | Requerido | Descripción |
|---|---|---|---|
attachment_ids |
array<string> (máx: 50) | Sí | Lista de identificadores de recetas a descargar |
store_id |
string | No | Identificador de la sucursal |
status |
string | No (default: WAITING_VALIDATION) | Valores: WAITING_VALIDATION, ACCEPTED |
Ejemplo de request:
curl -L -X POST \
https://api.mercadolibre.com/v1/prescription/attachments/download \
-H 'Content-Type: application/json' \
-H 'Accept: application/json' \
-H 'Authorization: Bearer APP_USR-123467899999.....' \
--data '{
"attachment_ids": [
"MLM_112233466_0123ab3430001.pdf",
"MLM_112233466_0123ab3430002.pdf",
"MLM_112233466_0123ab3430003.pdf"
],
"store_id": "123456789"
}
'
Response
| Status | Descripción | Respuesta |
|---|---|---|
| 200 | Éxito. Retorna un archivo ZIP con todas las recetas solicitadas. |
|
| 207 | Éxito parcial. El ZIP incluye las recetas disponibles y un manifest.json con el detalle de las que no pudieron descargarse. |
Contenido del manifest.json:
|
| 400 | Bad Request |
|
| 401 | No autorizado. Token ausente o inválido. |
|
| 410 | Attachment gone |
|
| 429 | Rate limit excedido |
|
| 500 | Error interno |
|
| Motivos de error en el manifest.json | Descripción |
|---|---|
omitted |
El attachment fue excluido porque no pertenece al seller, el store_id no coincide, o el status no corresponde al filtro aplicado. |
fetch_error |
Error al recuperar el archivo de la receta. |
file_too_large |
El archivo excede el tamaño máximo permitido por ítem. |
Errores
Todos los endpoints retornan un body JSON estructurado en respuestas no-2xx. El campo error_code utiliza el formato ERROR_RX_INTEGRATOR_NNN.
Estructura:
{
"code": "bad_request",
"message": "attachment_not_found",
"error_code": "ERROR_RX_INTEGRATOR_001",
"errors": [
{ "field": "attachment_id", "reason": "is required" }
]
}
- code — texto del status HTTP en snake_case (siempre presente)
- message — clave legible del error (siempre presente)
- error_code — código catalogado (siempre presente en errores)
- errors[] — detalle por campo (presente únicamente en respuestas ERROR_RX_INTEGRATOR_012)
4xx — Reglas de negocio, autorización e input
| Código | error_code | HTTP | message | Causa |
|---|---|---|---|---|
| 001 | ERROR_RX_INTEGRATOR_001 |
404 | attachment_not_found |
El attachment_id no existe o pertenece a otro seller/sucursal. |
| 002 | ERROR_RX_INTEGRATOR_002 |
403 | attachment_store_mismatch |
El store_id de la solicitud no coincide con el del attachment. |
| 003 | ERROR_RX_INTEGRATOR_003 |
422 | attachment_not_downloaded |
Se intentó aceptar o rechazar una receta que no fue descargada previamente. |
| 004 | ERROR_RX_INTEGRATOR_004 |
422 | attachment_already_accepted |
El attachment ya está en estado ACCEPTED. |
| 005 | ERROR_RX_INTEGRATOR_005 |
422 | attachment_already_rejected |
El attachment ya está en estado REJECTED. |
| 006 | ERROR_RX_INTEGRATOR_006 |
422 | attachment_not_waiting_validation |
El attachment no está en estado WAITING_VALIDATION. |
| 007 | ERROR_RX_INTEGRATOR_007 |
400 | (dinámico, incluye el límite) | Se solicitaron más de 50 attachment_ids en un bulk download. |
| 008 | ERROR_RX_INTEGRATOR_008 |
400 | attachment archive exceeds maximum allowed size |
El archivo ZIP generado excede el tamaño máximo permitido. |
| 009 | ERROR_RX_INTEGRATOR_009 |
404 | order_not_found |
El pedido asociado al attachment no fue encontrado. |
| 010 | ERROR_RX_INTEGRATOR_010 |
400 | invalid_reject_reason |
El motivo de rechazo no es uno de los valores permitidos. |
| 011 | ERROR_RX_INTEGRATOR_011 |
422 | insufficient_seller_balance |
El seller no tiene saldo suficiente para completar la operación. |
| 012 | ERROR_RX_INTEGRATOR_012 |
400 | (join de mensajes de campo) | Uno o más campos de la solicitud fallaron la validación estructural. El array errors[] detalla los campos afectados. |
| 013 | ERROR_RX_INTEGRATOR_013 |
400 | invalid request body |
El body de la solicitud no es un JSON válido. El array errors[] está ausente. |
| 014 | ERROR_RX_INTEGRATOR_014 |
403 | payment_refund_not_authorized |
El reembolso del pedido no pudo procesarse porque el pago del seller no está autorizado para esta operación. Reintentar no resolverá el problema. |
| 015 | ERROR_RX_INTEGRATOR_015 |
409 | order_conflict |
El pedido no pudo actualizarse debido a una modificación concurrente. Reintente después de un breve intervalo. |
| 016 | ERROR_RX_INTEGRATOR_016 |
409 | order_already_locked |
El pedido está temporalmente bloqueado por otra operación en curso. Reintente después de un breve intervalo. |
| 019 | ERROR_RX_INTEGRATOR_019 |
410 | attachment_gone |
El attachment fue eliminado permanentemente de la base de datos y ya no está disponible. |
5xx — Errores internos
| Código | error_code | HTTP | message | Causa |
|---|---|---|---|---|
| 900 | ERROR_RX_INTEGRATOR_900 |
500 | internal error | Error al recuperar el archivo de la receta. |
| 901 | ERROR_RX_INTEGRATOR_901 |
500 | internal error | Error al registrar la descarga del archivo. |
| 902 | ERROR_RX_INTEGRATOR_902 |
500 | internal error | El attachment no tiene un pedido asociado. |
| 903 | ERROR_RX_INTEGRATOR_903 |
500 | internal error | Error inesperado en la consulta de datos. |
| 904 | ERROR_RX_INTEGRATOR_904 |
500 | internal error | Error de configuración interna del servicio. |
| 905 | ERROR_RX_INTEGRATOR_905 |
500 | failed to list attachments | Error al procesar el listado de recetas. |
| 906 | ERROR_RX_INTEGRATOR_906 |
500 | failed to build attachment archive | Error al generar el archivo comprimido en la descarga masiva. |
| 907 | ERROR_RX_INTEGRATOR_907 |
500 | internal error | Error interno al procesar la descarga. |
| 999 | ERROR_RX_INTEGRATOR_999 |
500 | internal error | Error interno inesperado. |