Referencia · API de AccesPub 0.11.0

Generada desde el contrato OpenAPI 0.11.0. Descargar openapi.yaml

API de AccesPub

Remediación de accesibilidad de EPUB por lotes, con revisión humana.

Contrato v0.6 (20/10/2026). En api.accespub.app: organización y claves, personas, roles y sesiones, lotes, trabajos, informe, revisión (elementos, decisiones y propuestas de la IA), metadatos, finalización, salidas, subidas grandes y solicitudes de ayuda. Novedad de la v0.6: créditos por título según el número de imágenes (billing en Job, credits en Batch).

Guía de integración, ejemplos y esta referencia: https://api.accespub.app/docs.

Webhooks (v0.10, 01/11/2026): AccesPub avisa a vuestro sistema cuando cambia algo (título con revisión pendiente, listo, finalizado o con error; lote terminado; subida grande resuelta; respuesta de ab serveis; propuestas de la IA terminadas; pocos créditos). Ver /webhook-endpoints y la sección webhooks.

Propuestas masivas también para tablas (v0.11, 02/11/2026): POST /jobs/{job_id}/ai-prefill y defaults.ai_prefill preparan además un título para cada tabla pendiente. El estado indica cuántas son imágenes y cuántas tablas (images, tables).

Quién puede hacer qué (rol de la persona; una clave de administración actúa como admin y las demás claves como batch_manager):

Operación admin batch_manager reviewer external_reviewer
Personas, invitaciones, crear y revocar claves sí — — —
Crear y borrar lotes, subir, reprocesar, finalizar, subidas grandes sí sí — —
Ver lotes, títulos, informe y elementos de revisión sí sí sí solo su lote
Decidir, saltar revisión, pedir propuestas a la IA sí sí sí solo su lote
Descargar salidas, metadatos (cambiar), ayuda, lista de personas sí sí sí —

La API hace por lotes lo mismo que el dashboard de AccesPub hace con un EPUB: analizar, corregir todo lo automático, dejar para revisión humana lo que requiere criterio y entregar el EPUB final con su informe y su ONIX de accesibilidad.

Principios:

  • Criterio humano. La IA solo propone. Las decisiones (texto alternativo, tablas, idiomas) las toma una persona, y cada decisión registra quién y cuándo. Un EPUB solo declara conformidad con WCAG 2.1 AA (dcterms:conformsTo) si no queda nada pendiente y EPUBCheck no da errores.
  • El portal de AccesPub es un cliente más de esta API. No hay operaciones exclusivas del portal: lo que se hace en él se puede hacer aquí.
  • Asíncrona. Subir un EPUB devuelve 202 y un trabajo en cola. El estado se consulta con GET /jobs/{job_id} o se recibe un aviso (webhooks).

Fuera de esta API: la consola de superadministración de ab serveis (alta de organizaciones, planes, límites, aprobación de subidas grandes), que es interna.

Convenciones:

  • Errores en application/problem+json (RFC 9457).
  • Idempotency-Key en las operaciones que crean o cobran (borrador IETF).
  • Límite de peticiones con 429 y Retry-After.
  • Fechas en ISO 8601 UTC. Tamaños en bytes. Paginación por cursor.
  • Webhooks firmados según Standard Webhooks (HMAC-SHA256).

Servidor

https://api.accespub.app/v1

Un solo servidor. El modo lo decide la clave: ap_live_ (real, consume créditos) o ap_test_ (pruebas, sin coste, datos separados).

Autenticación

apiKey http · bearer

Authorization: Bearer ap_live_… (o ap_test_… para pruebas). ab serveis entrega la primera clave (de administración) al dar de alta la organización; con ella se crean las demás (POST /api-keys). Solo se guarda un resumen criptográfico (hash): la clave entera se ve una sola vez, al crearla.

session apiKey · cookie · ap_session

Sesión de una persona (portal), creada con POST /sessions o, para un revisor externo, con POST /sessions/link. Cookie HttpOnly, Secure y SameSite=Lax. Caduca tras 12 horas sin actividad (se renueva al usarla) y, como máximo, a los 7 días de iniciarla. En las peticiones que cambian algo hay que enviar además la cabecera X-CSRF-Token con el csrf_token recibido al iniciar sesión (si no, 403). El modo se elige con la cabecera AccesPub-Mode: live|test (live por defecto); un revisor externo trabaja en el modo de su lote.

Organización

Plan, créditos, espacio y límites de la cuenta.

Datos de la organización, créditos, espacio y límites

GET /organization

Respuestas

CódigoDescripciónTipo
200

Organización de la clave usada.

Organization
default

Error (RFC 9457).

Problem

Consumo de créditos por mes

GET /organization/usage

Parámetros

NombreDóndeTipoDescripción
monthsqueryinteger

Respuestas

CódigoDescripciónTipo
200

Consumo.

object
default

Error (RFC 9457).

Problem

Claves de la API (sin el secreto)

GET /api-keys

Respuestas

CódigoDescripciónTipo
200

Claves.

object
default

Error (RFC 9457).

Problem

Crear una clave (solo administradores; se muestra entera una sola vez)

POST /api-keys

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
mode (obligatorio)string (enum: live, test)
label (obligatorio)string

Respuestas

CódigoDescripciónTipo
201

Clave creada.

ApiKey + object
default

Error (RFC 9457).

Problem

Revocar una clave

DELETE /api-keys/{key_id}

Parámetros

NombreDóndeTipoDescripción
key_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
204

Clave revocada.

default

Error (RFC 9457).

Problem

Lotes

Un lote agrupa los EPUB que una editorial procesa juntos.

Lista de lotes, del más reciente al más antiguo

GET /batches

Parámetros

NombreDóndeTipoDescripción
cursorquerystring

Valor next_cursor de la página anterior.

limitqueryinteger
statusqueryBatchStatus

Respuestas

CódigoDescripciónTipo
200

Página de lotes.

Page + object
default

Error (RFC 9457).

Problem

Crear un lote

POST /batches

Crea un lote vacío. Después se sube cada EPUB con POST /batches/{batch_id}/jobs. Límites por defecto: 50 EPUB y 1 GB por lote, 50 MB por EPUB.

Parámetros

NombreDóndeTipoDescripción
Idempotency-Keyheaderstring

Identificador único de la operación (por ejemplo, un UUID). Si se repite la petición con la misma clave en 24 horas, se devuelve la respuesta original sin repetir la operación ni cobrar dos veces.

Cuerpo de la petición (obligatorio)

application/json · BatchCreate

Respuestas

CódigoDescripciónTipo
201

Lote creado.

Batch
default

Error (RFC 9457).

Problem

Estado de un lote

GET /batches/{batch_id}

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Lote.

Batch
default

Error (RFC 9457).

Problem

Cambiar nombre, revisores o qué hacer con lo pendiente

PATCH /batches/{batch_id}

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring

Cuerpo de la petición (obligatorio)

application/json · BatchUpdate

Respuestas

CódigoDescripciónTipo
200

Lote actualizado.

Batch
default

Error (RFC 9457).

Problem

Borrar un lote y todos sus ficheros

DELETE /batches/{batch_id}

Cancela lo que esté en cola y borra los ficheros. Las decisiones de revisión y los informes se conservan según el contrato (D4) salvo que se pida su borrado. No devuelve créditos ya consumidos.

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
204

Lote borrado.

default

Error (RFC 9457).

Problem

Finalizar todos los títulos listos del lote

POST /batches/{batch_id}/finalize

Finaliza los títulos sin pendientes (o todos, con allow_pending), o solo los indicados en job_ids. Consume los créditos de cada título finalizado por primera vez (billing.credits_required: uno hasta 150 imágenes y uno más por cada bloque adicional de 150).

Todo o nada: si no hay créditos para todos los títulos pedidos → 402 insufficient-credits con credits_required y credits_available, y no se finaliza ninguno. Para finalizar solo algunos, enviad job_ids.

  • Ningún título que cumpla la condición → 409 nothing-to-finalize.
  • Un job_ids que no es del lote → 404; uno que no se puede finalizar (pendientes sin allow_pending, en proceso) → 409.

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring
Idempotency-Keyheaderstring

Identificador único de la operación (por ejemplo, un UUID). Si se repite la petición con la misma clave en 24 horas, se devuelve la respuesta original sin repetir la operación ni cobrar dos veces.

Cuerpo de la petición

application/json · object

NombreTipoDescripción
allow_pendingboolean
job_idsarray<string>

Solo estos títulos. Por defecto, todos los que cumplan la condición.

Respuestas

CódigoDescripciónTipo
202

Finalización en cola.

Batch
402

Error (RFC 9457).

Problem
409

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Trabajos

Un trabajo es un EPUB dentro de un lote.

Trabajos (títulos) de un lote

GET /batches/{batch_id}/jobs

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring
cursorquerystring

Valor next_cursor de la página anterior.

limitqueryinteger
statusqueryJobStatus

Respuestas

CódigoDescripciónTipo
200

Página de trabajos.

Page + object
default

Error (RFC 9457).

Problem

Subir un EPUB al lote

POST /batches/{batch_id}/jobs

Un EPUB por petición. Se comprueba el tamaño mientras se recibe: si supera el límite, se corta la subida y responde 413 sin guardar nada.

Comprobaciones, por orden: 1. Tamaño del EPUB (50 MB, o el de una subida grande aprobada) → 413. 2. Límites del lote (50 EPUB, 1 GB) → 409 batch-limit-reached. 3. Espacio de la organización (5 GB) → 409 storage-quota-exceeded. 4. Espacio del servidor → 503 con Retry-After. 5. Que sea un EPUB válido como contenedor (ZIP seguro, ≤ 300 MB descomprimido, no de diseño fijo) → 422.

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring
Idempotency-Keyheaderstring

Identificador único de la operación (por ejemplo, un UUID). Si se repite la petición con la misma clave en 24 horas, se devuelve la respuesta original sin repetir la operación ni cobrar dos veces.

Cuerpo de la petición (obligatorio)

multipart/form-data · object

NombreTipoDescripción
file (obligatorio)string (binary)

El EPUB.

external_idstring

Identificador del título en la plataforma del cliente (se devuelve tal cual).

isbnstring

ISBN-13 si el EPUB no lo declara (se ignoran guiones y espacios). Se usa en el ONIX.

Respuestas

CódigoDescripciónTipo
202

EPUB recibido y en cola.

Job
409

Error (RFC 9457).

Problem
413

Error (RFC 9457).

Problem
415

El cuerpo no es multipart/form-data.

Problem
422

Error (RFC 9457).

Problem
503

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Estado de un trabajo

GET /jobs/{job_id}

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Trabajo.

Job
default

Error (RFC 9457).

Problem

Asignar revisores o corregir datos del título

PATCH /jobs/{job_id}

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
assignee_user_idsarray<string>

Revisores de este título (si no, los del lote).

external_idstring
isbnstring

Respuestas

CódigoDescripciónTipo
200

Trabajo actualizado.

Job
default

Error (RFC 9457).

Problem

Quitar un título del lote y borrar sus ficheros

DELETE /jobs/{job_id}

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
204

Trabajo borrado.

default

Error (RFC 9457).

Problem

Volver a procesar el EPUB original

POST /jobs/{job_id}/reprocess

Repite el análisis (por ejemplo, tras una mejora del motor). Las decisiones ya tomadas se conservan y se vuelven a aplicar a los elementos que sigan existiendo (se reconocen por su contenido aunque cambie su id). El historial de decisiones no cambia. No consume crédito; finalizar de nuevo un título ya cobrado tampoco.

  • En cola o en proceso → 409 job-not-ready.
  • Ficheros caducados → 410 files-expired.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring
Idempotency-Keyheaderstring

Identificador único de la operación (por ejemplo, un UUID). Si se repite la petición con la misma clave en 24 horas, se devuelve la respuesta original sin repetir la operación ni cobrar dos veces.

Respuestas

CódigoDescripciónTipo
202

En cola.

Job
409

Error (RFC 9457).

Problem
410

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Informe del análisis en JSON

GET /jobs/{job_id}/report

Mismo contenido que el informe del dashboard: correcciones automáticas, problemas que requieren atención, resultado de EPUBCheck y metadatos de accesibilidad. El esquema lleva versión (schema_version); el completo está en report.schema.json. Mientras se analiza → 409 job-not-ready con Retry-After.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Informe.

Report
409

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Metadatos del título y lo que conviene completar

GET /jobs/{job_id}/metadata

Campos Dublin Core del OPF (con su origen: el EPUB o un valor indicado aquí), resumen de accesibilidad propio, ISBN de la edición impresa y avisos (notices). Equivale a la pantalla de exportación y a los avisos del informe del dashboard. Mientras se analiza → 409 job-not-ready.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Metadatos.

Metadata
409

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Completar o corregir metadatos

PATCH /jobs/{job_id}/metadata

Solo se cambian los campos enviados; null quita el valor indicado y vuelve al del EPUB. Se guardan aparte y se aplican al finalizar (así sobreviven a reprocesar). No bloquean la finalización ni la conformidad.

  • dc.date: AAAA, AAAA-MM o AAAA-MM-DD (otras formas reconocibles se normalizan). Corrige también la fecha ambigua que avisa date_ambiguous.
  • page_source_isbn: ISBN de la edición impresa de la que proceden los números de página (pageBreakSource), 10 o 13 dígitos sin guiones.
  • accessibility_summary: sustituye el resumen de accesibilidad generado.
  • El idioma no se cambia aquí: es el elemento de revisión book_language.
  • subjects: materias del libro (thema, bisac, keywords). Sustituyen a todos los dc:subject del EPUB: Thema y BISAC se escriben con su refinamiento EPUB 3 (authority + term) y la etiqueta oficial como texto; las palabras clave, sin refinar. También van al ONIX de accesibilidad (Thema 93, BISAC 10, palabras clave 20). Los Thema se comprueban contra la lista oficial; BISAC = 3 letras + 6 cifras. null vuelve a las materias del EPUB. No se combina con dc.subject.

Todo o nada: con algún campo no válido → 422 y no se guarda nada. En un título finalizado, lo devuelve a ready (finalizar de nuevo no cuesta).

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Cuerpo de la petición (obligatorio)

application/json · MetadataUpdate

Respuestas

CódigoDescripciónTipo
200

Metadatos actualizados.

Metadata
409

Error (RFC 9457).

Problem
410

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Pedir a la IA descripción y materias

POST /jobs/{job_id}/metadata/suggestion

Propone una sinopsis, códigos Thema (todos comprobados contra la lista oficial de Thema 1.6, incluidos los calificadores), una pista BISAC en texto y palabras clave, a partir de unos 4.000 caracteres del inicio del cuerpo del libro (sin portada ni créditos) y del título. No se aplica: lo que se acepte se envía con PATCH /jobs/{job_id}/metadata (dc.description y subjects). No consume créditos.

  • Solo personas internas (o clave de API); no revisores externos.
  • Límite compartido con las propuestas de revisión: limits.ai_suggestions_per_minute → 429 con Retry-After.
  • Con una clave ap_test_ la propuesta es fija (provider: test) y no se llama a la IA.
  • Sin texto que leer (libro solo de imágenes) o filtros de contenido → 422 ai-blocked. IA saturada o no configurada → 503 ai-unavailable.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Propuesta.

MetadataSuggestion
409

Error (RFC 9457).

Problem
410

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
429

Error (RFC 9457).

Problem
502

Error (RFC 9457).

Problem
503

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Generar el EPUB final (consume un crédito)

POST /jobs/{job_id}/finalize

Aplica las decisiones y los metadatos completados (PATCH …/metadata), escribe los metadatos de accesibilidad, valida con EPUBCheck y genera las salidas. Consume un crédito la primera vez; finalizar de nuevo (tras cambiar decisiones o volver a procesar) no cuesta. Una versión nueva del EPUB, aunque tenga el mismo ISBN, es otro trabajo y otro crédito.

  • Si quedan pendientes y allow_pending es false → 409 pending-review.
  • Con allow_pending: true se entrega sin dcterms:conformsTo y el informe lista lo pendiente.
  • Sin créditos → 402.
  • En cola, en proceso o ya finalizándose → 409 job-not-ready.
  • Ficheros caducados → 410 files-expired.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring
Idempotency-Keyheaderstring

Identificador único de la operación (por ejemplo, un UUID). Si se repite la petición con la misma clave en 24 horas, se devuelve la respuesta original sin repetir la operación ni cobrar dos veces.

Cuerpo de la petición

application/json · object

NombreTipoDescripción
allow_pendingboolean

Respuestas

CódigoDescripciónTipo
202

Finalización en cola.

Job
402

Error (RFC 9457).

Problem
409

Error (RFC 9457).

Problem
410

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Revisión

Elementos que requieren criterio humano y decisiones.

Elementos que requieren criterio humano

GET /jobs/{job_id}/review-items

Imágenes sin texto alternativo aceptable, tablas, atributos de idioma en línea (language.scope: inline), el idioma de cada documento (language.scope: document) y el idioma principal del libro, con su orden en el OPF (language.scope: book, id: book_language; como el bloque «Idioma principal del epub» del dashboard). Un idioma de documento asignado automáticamente con alta confianza aparece como decidido, con decision.auto: true; también el idioma del libro cuando no hay nada que confirmar pero el libro tiene varios idiomas candidatos (se puede cambiar), o cuando el OPF no tiene un idioma válido y el lote trae defaults.fallback_language. Los decididos por la API llevan decided_by y decided_at. Mientras se analiza → 409 job-not-ready.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring
cursorquerystring

Valor next_cursor de la página anterior.

limitqueryinteger
statusquerystring (enum: pending, decided, all)
kindqueryReviewKind

Respuestas

CódigoDescripciónTipo
200

Página de elementos.

Page + object
default

Error (RFC 9457).

Problem

Imagen que se revisa (reducida a 1024 px como máximo)

GET /jobs/{job_id}/review-items/{item_id}/image

Las imágenes de más de 1024 px se devuelven reducidas (JPEG, o PNG si tienen transparencia). Los GIF y SVG se devuelven tal cual; los SVG, con una Content-Security-Policy que impide ejecutar scripts.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring
item_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

La imagen.

string (binary)
default

Error (RFC 9457).

Problem

Pedir una propuesta a la IA

POST /jobs/{job_id}/review-items/{item_id}/suggestion

Devuelve una propuesta: texto alternativo para una imagen o título para una tabla, escrito en el idioma de ese elemento. No se aplica: hay que enviarla como decisión, revisada por una persona (con from_suggestion: true si se parte de ella). Los idiomas no tienen propuesta (422).

  • Límite: limits.ai_suggestions_per_minute por organización → 429 con Retry-After.
  • Con una clave ap_test_ la propuesta es un texto fijo de prueba (provider: test) y no se llama a la IA.
  • La IA no puede leer la imagen (SVG) o sus filtros bloquean el texto → 422 ai-blocked: hay que escribirlo a mano.
  • IA saturada o no disponible → 503 ai-unavailable con Retry-After; error del proveedor → 502 ai-error.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring
item_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Propuesta.

Suggestion
409

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
429

Error (RFC 9457).

Problem
502

Error (RFC 9457).

Problem
503

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Estado de las propuestas de la IA del título

GET /jobs/{job_id}/ai-prefill

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Estado.

AiPrefill
default

Error (RFC 9457).

Problem

Preparar las propuestas de la IA de todas las imágenes y tablas

POST /jobs/{job_id}/ai-prefill

Propuestas masivas. Pone en cola una propuesta para cada imagen pendiente (texto alternativo; no se incluyen los SVG, que la IA no puede leer) y para cada tabla pendiente (título de la tabla) que aún no la tenga. Las propuestas llegan poco a poco: una cola común reparte el ritmo entre las organizaciones y las que se piden a mano pasan delante. Cada propuesta se lee como siempre (review-items con su propuesta) y no se aplica sola: hay que enviarla como decisión revisada por una persona.

Es idempotente: repetirla vuelve a intentar las que fallaron. Lo hace solo, al analizar, si el lote tiene defaults.ai_prefill: true. Con una clave ap_test_ las propuestas son un texto fijo de prueba y no se llama a la IA.

Cobro según la organización (lo fija ab serveis): incluido en el crédito del título (hace falta saldo para finalizarlo; si no, 402) o de pago (créditos por cada bloque de imágenes, cobrados al pedirlas; lo que no se genera se devuelve solo). Las tablas no cuentan en los bloques de pago. Si la función no está activada para la organización → 403.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
202

En cola. Estado actual.

AiPrefill
402

Error (RFC 9457).

Problem
403

Error (RFC 9457).

Problem
409

Error (RFC 9457).

Problem
410

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Saltar la revisión de lo que quede pendiente

POST /jobs/{job_id}/skip-review

Equivale a «Saltar revisión» del dashboard. Lo que quede pendiente de imágenes, tablas e idiomas en línea pasa a decorativo (alt=""), de maquetación (role="presentation") o se conserva (idiomas). Los idiomas de documento y el del libro no se tocan.

  • confirm_decorative: true: una persona confirma que lo restante es decorativo o de maquetación. Son decisiones con revisor (reviewer obligatorio), quedan en el historial y cuentan para la conformidad.
  • confirm_decorative: false (por defecto): saltado sin revisar. El EPUB sale igual, pero imágenes y tablas siguen pendientes: no se declara conformidad y hay que finalizar con allow_pending.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring
Idempotency-Keyheaderstring

Identificador único de la operación (por ejemplo, un UUID). Si se repite la petición con la misma clave en 24 horas, se devuelve la respuesta original sin repetir la operación ni cobrar dos veces.

Cuerpo de la petición

application/json · object

NombreTipoDescripción
confirm_decorativeboolean
reviewerReviewer

Respuestas

CódigoDescripciónTipo
200

Hecho.

SkipResult
409

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Historial de decisiones de un título

GET /jobs/{job_id}/decisions

Todas las decisiones enviadas, de la más antigua a la más reciente, con su revisor y su fecha (también las sustituidas). Se conserva aunque se borren los ficheros del título.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Historial.

object
default

Error (RFC 9457).

Problem

Enviar decisiones de revisión

POST /jobs/{job_id}/decisions

Una o varias decisiones a la vez (máximo 200 por petición). Se guardan al momento, con revisor y fecha: la revisión puede repartirse entre personas y durar semanas. Enviar otra decisión para el mismo elemento la sustituye (queda el historial).

Todo o nada: si alguna decisión no es válida → 422 invalid-decision con un error por decisión en errors (pointer = /decisions/N/…), y no se guarda ninguna.

Sin persona identificada no hay criterio humano: - Con sesión, el revisor es la persona de la sesión (reviewer se ignora). - Con clave de API, reviewer es obligatorio y su correo tiene que ser el de una persona activa de la organización (cualquier rol, o revisor externo de ese lote); si no, 422 reviewer-not-registered. Por contrato, el cliente responde de la identidad de sus revisores.

AccesPub señala patrones anómalos (decenas de decisiones en pocos segundos, o todas las propuestas de la IA aceptadas sin cambios) en review_flags del trabajo, en el informe y en la consola de ab serveis.

Solo con el trabajo en needs_review, ready o completed; en otro estado → 409 job-not-ready. Una decisión enviada después de finalizar devuelve el trabajo a ready: hay que finalizar de nuevo (sin coste). Si con la decisión ya no queda nada pendiente y el lote tiene auto_finalize, el título se finaliza solo (job_status: finalizing).

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring
Idempotency-Keyheaderstring

Identificador único de la operación (por ejemplo, un UUID). Si se repite la petición con la misma clave en 24 horas, se devuelve la respuesta original sin repetir la operación ni cobrar dos veces.

Cuerpo de la petición (obligatorio)

application/json · DecisionBatch

Respuestas

CódigoDescripciónTipo
200

Decisiones guardadas.

DecisionResult
409

Error (RFC 9457).

Problem
410

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Salidas

EPUB final, informe, ONIX de accesibilidad y manifiesto.

Descargar una salida de un título

GET /jobs/{job_id}/files/{kind}

original se puede descargar siempre que no haya caducado; el resto, solo con el título finalizado (si no, 409 job-not-finalized). Ficheros caducados (30 días tras finalizar) → 410 files-expired.

Con naming=isbn, el fichero se llama como el ISBN-13 del título (9788412345674.epub, 9788412345674-informe.html, 9788412345674-onix.xml), como piden las plataformas de distribución. Si el título no tiene un ISBN-13 válido → 409 isbn-missing.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring
kind (obligatorio)pathJobFileKind
langquerystring (enum: es, en, ca, fr)

Idioma del informe HTML.

namingquerystring (enum: filename, isbn)

Nombre de los ficheros descargados. filename (por defecto): el del EPUB subido (libro-accesible.epub). isbn: el ISBN-13 del título (9788412345674.epub). En los .zip del lote, los títulos sin ISBN-13 válido conservan el nombre de siempre.

Respuestas

CódigoDescripciónTipo
200

El fichero.

string (binary)
string
string
409

Error (RFC 9457).

Problem
410

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Manifiesto del lote (estado de cada título y cada salida)

GET /batches/{batch_id}/manifest

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring
formatquerystring (enum: json, csv)

json o csv. Si se omite, CSV cuando la cabecera Accept pide text/csv.

Respuestas

CódigoDescripciónTipo
200

Manifiesto. En CSV con ?format=csv o con la cabecera Accept: text/csv.

Manifest
string
default

Error (RFC 9457).

Problem

Descargar las salidas del lote de una vez

GET /batches/{batch_id}/files/{kind}

Solo incluye los títulos finalizados. - epubs: .zip con los EPUB finales. - reports: .zip con un informe HTML por título. - onix_a11y: un único mensaje ONIX 3.1 con un <Product> por título.

Sin ningún título finalizado → 409 job-not-finalized.

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring
kind (obligatorio)pathstring (enum: epubs, reports, onix_a11y, onix_full)
job_idsquerystring

Solo estos títulos (separados por comas). Por defecto, todos los finalizados.

langquerystring (enum: es, en, ca, fr)

Idioma del informe HTML.

namingquerystring (enum: filename, isbn)

Nombre de los ficheros descargados. filename (por defecto): el del EPUB subido (libro-accesible.epub). isbn: el ISBN-13 del título (9788412345674.epub). En los .zip del lote, los títulos sin ISBN-13 válido conservan el nombre de siempre.

Respuestas

CódigoDescripciónTipo
200

El fichero.

string (binary)
string
default

Error (RFC 9457).

Problem

ONIX comercial

ONIX 3.1 completo (precios por mercado, estado, sello, colección…) por título y lote.

Datos comerciales del título, comprobaciones y estado del ONIX comercial

GET /jobs/{job_id}/commercial

title: lo indicado para el título. batch: los valores comunes del lote. effective: lo que se usará (lo del título manda; un campo vacío toma el del lote; los mercados del título, si tiene, sustituyen a los del lote). issues: comprobaciones (level error impide generarlo: not_finalized, isbn_missing, publisher_missing, markets_missing, xsd_invalid; avisos: market_unpriced, date_missing, cover_missing). billing: modo de la organización y lo que costaría generarlo ahora.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Datos comerciales.

CommercialView
default

Error (RFC 9457).

Problem

Cambiar los datos comerciales del título

PATCH /jobs/{job_id}/commercial

Solo cambian los campos enviados; null (o vacío) quita el valor y vuelve al del lote. markets sustituye la lista entera. No obliga a finalizar de nuevo: el ONIX comercial se construye al descargarlo.

apply_to_batch: nombres de campos comunes que además se guardan como valores del lote (los mercados pasan sin price_amount, que es de cada título). Campos comunes: imprint, collection, pub_status, city, country, copyright_owner, audience, age_from, age_to, supplier_name, supplier_role, markets.

Los códigos se comprueban contra las listas ONIX del esquema oficial 3.1. Todo o nada: con algún campo no válido → 422 con errors y no se guarda nada.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Cuerpo de la petición (obligatorio)

application/json · Commercial + object

NombreTipoDescripción
apply_to_batcharray<string>

Respuestas

CódigoDescripciónTipo
200

Datos actualizados.

CommercialView
409

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Generar el ONIX comercial del título

POST /jobs/{job_id}/onix-full

Comprueba los datos (422 onix-incomplete con jobs[].issues si falta algo) y lo activa para el título. Según la organización puede consumir créditos (billing en GET), una sola vez por título; en modo prueba, nunca. Sin saldo → 402 insufficient-credits. Desactivado para la organización → 403. Volver a llamarlo no cobra de nuevo. Después se descarga con GET /jobs/{id}/files/onix_full, siempre con los datos al día.

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Generado.

OnixFullResult
402

Error (RFC 9457).

Problem
403

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Valores comerciales comunes del lote y estado de cada título

GET /batches/{batch_id}/commercial

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Valores del lote y títulos.

object
default

Error (RFC 9457).

Problem

Cambiar los valores comerciales comunes del lote

PATCH /batches/{batch_id}/commercial

Solo campos comunes (ver PATCH /jobs/{id}/commercial); null quita el valor. También se pueden indicar al crear el lote en defaults.commercial.

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring

Cuerpo de la petición (obligatorio)

application/json · Commercial

Respuestas

CódigoDescripciónTipo
200

Valores actualizados (misma forma que el GET).

422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Generar el ONIX comercial de los títulos terminados del lote

POST /batches/{batch_id}/onix-full

Todos los títulos terminados del lote, o solo los de job_ids. Todo o nada: si alguno no está listo (422 con jobs[].issues) o no hay saldo para todos (402), no se genera ninguno. Los ya generados no se cobran de nuevo.

Parámetros

NombreDóndeTipoDescripción
batch_id (obligatorio)pathstring

Cuerpo de la petición

application/json · object

NombreTipoDescripción
job_idsarray<string>

Respuestas

CódigoDescripciónTipo
200

Generado.

OnixFullResult
402

Error (RFC 9457).

Problem
403

Error (RFC 9457).

Problem
409

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Subidas grandes

Permiso temporal para EPUB de más de 50 MB.

Solicitudes de subida grande de la organización

GET /large-upload-requests

Respuestas

CódigoDescripciónTipo
200

Solicitudes.

object
default

Error (RFC 9457).

Problem

Pedir permiso para un EPUB de más de 50 MB

POST /large-upload-requests

La revisa ab serveis. Si se aprueba, el lote admite ese fichero (hasta 200 MB) durante 7 días, y cuenta contra el espacio de la organización. Solo administradores y gestores de lotes.

Cuerpo de la petición (obligatorio)

application/json · LargeUploadRequestCreate

Respuestas

CódigoDescripciónTipo
201

Solicitud registrada (estado pending).

LargeUploadRequest
default

Error (RFC 9457).

Problem

Ayuda

Solicitudes de ayuda a ab serveis (EPUB con errores que AccesPub no corrige).

Solicitudes de ayuda de un título

GET /jobs/{job_id}/support-requests

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Solicitudes.

object
default

Error (RFC 9457).

Problem

Pedir ayuda a ab serveis con un título

POST /jobs/{job_id}/support-requests

Para un EPUB con errores que AccesPub no puede corregir (aviso epubcheck_errors en el título) o que no se ha podido procesar (failed). Es opcional: la editorial puede corregir el EPUB por su cuenta y volver a subirlo.

ab serveis recibe el mensaje con el registro de EPUBCheck y responde en la solicitud (resolution): - fix_planned: es un caso que AccesPub debería contemplar y se incorporará; - publisher_fix: es un problema concreto del EPUB, a corregir por la editorial; - manual_fix_quote: ab serveis puede corregirlo, con presupuesto aparte; - fixed o closed.

Con share_epub: true la editorial autoriza a ab serveis a descargar el EPUB original para diagnosticarlo; si no, solo ve el registro de errores. Como máximo 3 solicitudes abiertas por título (409 too-many-open-requests).

Parámetros

NombreDóndeTipoDescripción
job_id (obligatorio)pathstring

Cuerpo de la petición (obligatorio)

application/json · SupportRequestCreate

Respuestas

CódigoDescripciónTipo
201

Solicitud registrada.

SupportRequest
409

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Solicitudes de ayuda de la organización

GET /support-requests

Parámetros

NombreDóndeTipoDescripción
statusquerystring (enum: open, answered, closed)

Respuestas

CódigoDescripciónTipo
200

Solicitudes, de la más reciente a la más antigua.

object
default

Error (RFC 9457).

Problem

Usuarios

Personas de la organización (las mismas del portal).

Personas de la organización (también invitadas y dadas de baja)

GET /users

Respuestas

CódigoDescripciónTipo
200

Usuarios e invitaciones pendientes.

object
default

Error (RFC 9457).

Problem

Invitar a una persona (solo administradores)

POST /invitations

  • admin, batch_manager, reviewer: enlace de un solo uso, válido 72 horas, para crear la contraseña (/invitacion?token=…).
  • external_reviewer (con batch_id): enlace de su lote, válido 30 días y reutilizable, sin contraseña (/revision?token=…). Solo ve y decide en ese lote. Se revoca dándolo de baja.

El enlace se envía por correo si el servidor tiene correo configurado (email_sent) y siempre se devuelve en access_url, para que el administrador pueda hacerlo llegar. Es personal. Un correo solo puede pertenecer a una persona activa o invitada (409 email-in-use).

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
email (obligatorio)string (email)
role (obligatorio)Role
namestring

Si no, la persona lo indica al aceptar.

batch_idstring

Solo para external_reviewer (obligatorio); limita el acceso a ese lote.

send_emailboolean

false: no se envía el correo con el enlace. Útil en el modelo mixto, cuando la persona entrará siempre desde vuestra aplicación con un enlace de acceso (POST /users/{user_id}/sign-in-link) y nunca necesitará contraseña.

Respuestas

CódigoDescripciónTipo
201

Invitación creada.

Invitation
409

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Aceptar una invitación (o restablecer la contraseña)

POST /invitations/accept

Con el token del enlace. Activa la cuenta con la contraseña (mínimo 10 caracteres) y el nombre, que figurará en las decisiones que firme. Sirve también para el enlace de restablecer la contraseña; en ese caso cierra las sesiones abiertas. Enlace usado o caducado → 400 invalid-token.

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
token (obligatorio)string
password (obligatorio)string
namestring

Respuestas

CódigoDescripciónTipo
200

Cuenta activa.

User
400

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Iniciar sesión con correo y contraseña

POST /sessions

Devuelve la cookie de sesión (ap_session) y el csrf_token. Correo o contraseña incorrectos → 401 (sin decir cuál). Tras 5 intentos fallidos en 15 minutos → 429 con Retry-After. Los revisores externos entran con POST /sessions/link. La sesión se renueva con la actividad: caduca tras 12 horas sin usarse y, como máximo, 7 días después de iniciarse.

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
email (obligatorio)string (email)
password (obligatorio)string

Respuestas

CódigoDescripciónTipo
201

Sesión iniciada (cabecera Set-Cookie).

Session
401

Error (RFC 9457).

Problem
429

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Entrar con el enlace de un lote (revisores externos)

POST /sessions/link

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
token (obligatorio)string

Respuestas

CódigoDescripciónTipo
201

Sesión iniciada, limitada al lote del enlace.

Session
400

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Cerrar la sesión

DELETE /sessions/current

Respuestas

CódigoDescripciónTipo
204

Sesión cerrada.

default

Error (RFC 9457).

Problem

Quién hace la petición (persona o clave), su rol y su modo

GET /me

Respuestas

CódigoDescripciónTipo
200

Identidad.

object
default

Error (RFC 9457).

Problem

Cambiar la propia contraseña (cierra las demás sesiones)

POST /me/password

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
current_password (obligatorio)string
new_password (obligatorio)string

Respuestas

CódigoDescripciónTipo
204

Contraseña cambiada.

403

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Cambiar el rol de una persona (solo administradores)

PATCH /users/{user_id}

admin, batch_manager o reviewer. Los revisores externos no cambian de rol (se invita a la persona de nuevo). No se puede degradar al último administrador (409 last-admin).

Parámetros

NombreDóndeTipoDescripción
user_id (obligatorio)pathstring

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
role (obligatorio)string (enum: admin, batch_manager, reviewer)

Respuestas

CódigoDescripciónTipo
200

Persona actualizada.

User
409

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Dar de baja a una persona (solo administradores)

DELETE /users/{user_id}

Quita el acceso y cierra sus sesiones, pero no borra el registro: su nombre sigue en las decisiones de revisión que firmó. Su correo se puede volver a invitar. No se puede dar de baja al último administrador (409 last-admin).

Parámetros

NombreDóndeTipoDescripción
user_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
204

Persona dada de baja.

409

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Webhooks

Avisos automáticos a la plataforma del cliente.

Direcciones que reciben avisos (solo administración)

GET /webhook-endpoints

Las del modo de la clave (ap_live_ o ap_test_): cada modo tiene sus propias direcciones y recibe solo sus eventos. Incluye la lista de tipos de evento que se pueden pedir.

Respuestas

CódigoDescripciónTipo
200

Direcciones.

object
403

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Añadir una dirección (devuelve el secreto de firma una sola vez)

POST /webhook-endpoints

Solo https:// y direcciones públicas: se rechazan localhost, nombres sin dominio, IP privadas, locales o de metadatos y URL con usuario o contraseña. Al enviar, la dirección se resuelve de nuevo y se bloquea si apunta a una red privada. Máximo 5 direcciones por modo.

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
url (obligatorio)string (uri)
descriptionstring
eventsarray<EventType>

Tipos de evento. Sin events (o con ["*"]), todos.

Respuestas

CódigoDescripciónTipo
201

Dirección creada.

WebhookEndpoint + object
409

Error (RFC 9457).

Problem
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Una dirección (sin el secreto)

GET /webhook-endpoints/{endpoint_id}

Parámetros

NombreDóndeTipoDescripción
endpoint_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Dirección.

WebhookEndpoint
404

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Cambiar la dirección, los eventos o la descripción; desactivar o reactivar

PATCH /webhook-endpoints/{endpoint_id}

enabled: false deja de enviar (lo pendiente queda como failed). enabled: true reactiva una dirección desactivada (también la que AccesPub desactivó por fallar durante días); empieza de cero.

Parámetros

NombreDóndeTipoDescripción
endpoint_id (obligatorio)pathstring

Cuerpo de la petición (obligatorio)

application/json · object

NombreTipoDescripción
urlstring (uri)
descriptionstring
eventsarray<EventType>
enabledboolean

Respuestas

CódigoDescripciónTipo
200

Dirección actualizada.

WebhookEndpoint
422

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Quitar una dirección (y su historial de envíos)

DELETE /webhook-endpoints/{endpoint_id}

Parámetros

NombreDóndeTipoDescripción
endpoint_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
204

Dirección eliminada.

404

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Secreto de firma nuevo (el anterior sigue firmando 24 horas)

POST /webhook-endpoints/{endpoint_id}/rotate-secret

Durante 24 horas cada aviso lleva dos firmas en webhook-signature (la del secreto nuevo y la del anterior), para cambiarlo sin cortes.

Parámetros

NombreDóndeTipoDescripción
endpoint_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Secreto nuevo (solo se muestra ahora).

WebhookEndpoint + object
default

Error (RFC 9457).

Problem

Enviar ahora un evento de prueba (webhook.test)

POST /webhook-endpoints/{endpoint_id}/test

Un solo intento, sin reintentos, también si la dirección está desactivada. La respuesta dice si ha llegado (delivered) y qué ha respondido vuestro sistema.

Parámetros

NombreDóndeTipoDescripción
endpoint_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Resultado del envío.

WebhookDelivery
default

Error (RFC 9457).

Problem

Últimos envíos a una dirección (30 días)

GET /webhook-endpoints/{endpoint_id}/deliveries

Parámetros

NombreDóndeTipoDescripción
endpoint_id (obligatorio)pathstring
statusquerystring (enum: pending, retrying, delivered, failed)
limitqueryinteger

Respuestas

CódigoDescripciónTipo
200

Envíos, del más reciente al más antiguo.

object
default

Error (RFC 9457).

Problem

Un envío, con el evento enviado

GET /webhook-endpoints/{endpoint_id}/deliveries/{delivery_id}

Parámetros

NombreDóndeTipoDescripción
endpoint_id (obligatorio)pathstring
delivery_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
200

Envío.

WebhookDelivery + object
404

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Volver a enviar un envío (entregado o no entregado)

POST /webhook-endpoints/{endpoint_id}/deliveries/{delivery_id}/retry

Se envía en unos segundos con el mismo webhook-id (el mismo evento).

Parámetros

NombreDóndeTipoDescripción
endpoint_id (obligatorio)pathstring
delivery_id (obligatorio)pathstring

Respuestas

CódigoDescripciónTipo
202

En cola.

WebhookDelivery
409

Error (RFC 9457).

Problem
default

Error (RFC 9457).

Problem

Eventos de webhook

job.needs_review

Un título tiene elementos pendientes de revisión humana

application/json · Event + object

job.ready

Un título ya no tiene nada pendiente: listo para finalizar

application/json · Event + object

job.completed

Un título se ha finalizado y sus salidas están listas

application/json · Event + object

job.failed

Un título no se ha podido analizar (status failed) o finalizar (vuelve a su estado, con error)

application/json · Event + object

job.ai_prefill_done

Han terminado las propuestas de la IA de un título (propuestas masivas)

application/json · Event + object

batch.completed

Todos los títulos del lote están finalizados o con error

application/json · Event + object

large_upload_request.resolved

ab serveis ha aprobado o rechazado una subida grande

application/json · Event + object

support_request.answered

ab serveis ha respondido una solicitud de ayuda

application/json · Event + object

credits.low

El saldo ha bajado del umbral de la organización o se ha agotado (solo live)

application/json · Event + object

webhook.test

Evento de prueba (POST /webhook-endpoints/{endpoint_id}/test)

application/json · Event + object

Esquemas

Market

Un mercado del ONIX comercial (un ProductSupply).

NombreTipoDescripción
territory (obligatorio)string

Países ISO 3166-1 separados por espacios (ES, FR BE CH, CA) o regiones ONIX (lista 49: WORLD, CA-QC…).

countries_excludedstring

Solo con una región (p. ej. WORLD menos CA US).

currencystring

ISO 4217 (lista 96).

price_amountstring

Importe; se acepta coma decimal. Sin precio → «precio por anunciar».

price_typestring

Lista 58. Por defecto 02 (PVP con impuestos); 01 sin impuestos; 04 precio fijo con impuestos.

tax_percentstring

IVA incluido en el precio, en %. Vacío si el precio no incluye impuestos.

availabilitystring

Lista 65. Por defecto 20 (disponible).

supplier_namestring

Proveedor de este mercado; por defecto, supplier_name del título/lote o la editorial.

supplier_rolestring

Lista 93. Por defecto 01.

sale_datestring

Fecha de venta en el mercado (AAAA-MM-DD).

market_statusstring

Lista 68. Por defecto 04 si hay fecha.

Commercial

Datos comerciales del ONIX 3.1 completo. Comunes (también en el lote): imprint, collection, pub_status, city, country, copyright_owner, audience, age_from, age_to, supplier_name, supplier_role, markets. Solo del título: subtitle, collection_number, publishing_date, copyright_year, contributors, print_format, cover_url.

NombreTipoDescripción
subtitlestring
collectionstring
collection_numberstring
imprintstring
pub_statusstring

Lista 64. Por defecto 04 (activo).

publishing_datestring

AAAA, AAAA-MM o AAAA-MM-DD. Manda sobre el dc:date del EPUB.

citystring
countrystring

ISO 3166-1 (lista 91).

copyright_yearstring
copyright_ownerstring
audiencestring

Lista 28.

age_fromstring
age_tostring
contributorsarray<object>

Sustituye a la autoría del EPUB.

print_formatstring (enum: Paperback, Hardcover)
cover_urlstring (uri)

URL pública y estable de la imagen de cubierta (JPEG o PNG; se recomienda al menos 1000 px en el lado corto). Viaja en el ONIX como SupportingResource (cubierta, lista 158 código 01): distribuidores y agregadores la descargan de ahí, así que no debe cambiar ni caducar.

supplier_namestring
supplier_rolestring
marketsarray<Market>

CommercialIssue

NombreTipoDescripción
codestring (enum: not_finalized, isbn_missing, publisher_missing, markets_missing, market_unpriced, date_missing, cover_missing, xsd_invalid)
levelstring (enum: error, warning)
fieldstring

CommercialBilling

NombreTipoDescripción
modestring (enum: off, included, paid)
credits_per_titleinteger

CommercialView

NombreTipoDescripción
titleCommercial
batchCommercial
effectiveCommercial
sourcesobject
isbnstring | null
publisherstring | null
issuesarray<CommercialIssue>
readyboolean
onix_fullobject | null
billingCommercialBilling + object

OnixFullResult

NombreTipoDescripción
generatedarray<object>
credits_chargedinteger

Problem

NombreTipoDescripción
type (obligatorio)string (uri)

https://api.accespub.app/problems/<código>. Códigos: invalid-request, unauthorized, forbidden, not-found, method-not-allowed, file-too-large, batch-limit-reached, storage-quota-exceeded, not-an-epub, fixed-layout-not-supported, unsafe-container, job-not-ready, job-not-finalized, nothing-to-finalize, pending-review, insufficient-credits, files-expired, invalid-decision, ai-unavailable, ai-blocked, ai-error, rate-limited, server-storage-full, idempotency-conflict, too-many-open-requests, server-error. En el campo error de un trabajo: processing-failed, finalize-failed e insufficient-credits (finalización automática sin créditos). Personas: email-in-use, invalid-token, user-deactivated, sign-in-links-disabled, last-admin, reviewer-not-registered.

title (obligatorio)string
status (obligatorio)integer
detailstring
instancestring
credits_requiredinteger

Solo en insufficient-credits.

credits_availableinteger

Solo en insufficient-credits.

errorsarray<object>

Detalle por campo, en errores de validación.

Page

NombreTipoDescripción
next_cursorstring | null

null en la última página.

Organization

NombreTipoDescripción
idstring
namestring
planstring
modestring (enum: live, test)
creditsobject
storageobject
limitsLimits

Limits

NombreTipoDescripción
max_epub_bytesinteger
max_large_epub_bytesinteger
max_jobs_per_batchinteger
max_batch_bytesinteger
ai_suggestions_per_minuteinteger

BatchStatus string (enum: open, processing, needs_review, ready, finalizing, completed, cancelled)

Estado agregado: needs_review si algún título tiene pendientes; ready si todos pueden finalizarse; completed si todos están finalizados o con error.

OnPending string (enum: wait, finalize)

Qué hacer si al terminar el análisis quedan decisiones pendientes: wait espera a la revisión (único camino a la conformidad); finalize entrega sin declarar conformidad.

AutoFinalize boolean

true: cada título se finaliza solo (y consume su crédito) cuando se toma su última decisión pendiente, o al terminar el análisis si no hay nada que revisar. false (por defecto): hay que pedirlo con finalize.

BatchCreate

NombreTipoDescripción
name (obligatorio)string
on_pendingOnPending
auto_finalizeAutoFinalize
defaultsobject
reviewer_user_idsarray<string>
external_idstring

BatchUpdate

NombreTipoDescripción
namestring
on_pendingOnPending
auto_finalizeAutoFinalize
reviewer_user_idsarray<string>

Batch

NombreTipoDescripción
idstring
namestring
statusBatchStatus
on_pendingOnPending
auto_finalizeAutoFinalize
ai_prefillboolean

El lote pide las propuestas de la IA al analizar (defaults.ai_prefill).

portal_urlstring (uri)

El lote en el portal de AccesPub (los de prueba, con ?mode=test).

external_idstring | null
created_atstring (date-time)
created_byActor
countsobject
reviewReviewProgress
size_bytesinteger
creditsobject

Créditos del lote (solo cuentan en modo live).

ReviewProgress

NombreTipoDescripción
totalinteger
decidedinteger
pendinginteger

JobStatus string (enum: queued, processing, needs_review, ready, finalizing, completed, failed, cancelled)

ready: sin pendientes, se puede finalizar. completed: finalizado, salidas disponibles. failed: ver error.

JobBilling

Créditos del título. Un crédito cubre hasta images_per_credit imágenes del libro (todas las que aparecen en el contenido); cada bloque adicional, o parte, consume uno más. Se fija al analizar y se cobra al finalizar por primera vez. En el portal, un título de más de un crédito pide confirmación antes de la revisión; con auto_finalize u on_pending=finalize esos títulos no se finalizan solos hasta que se confirme ese aviso o se pida /finalize.

NombreTipoDescripción
imagesinteger | null

Imágenes del libro (null hasta el análisis).

images_per_creditinteger
credits_requiredinteger
credits_chargedinteger

Cobrados en la finalización (0 si aún no).

extra_credits_acknowledged_atstring | null (date-time)

Job

NombreTipoDescripción
idstring
batch_idstring
statusJobStatus
filenamestring
size_bytesinteger
external_idstring | null
titlestring | null

dc:title del EPUB.

isbnstring | null
epub_versionstring | null
reviewReviewProgress
conformancestring | null (enum: wcag21aa, none, None)

Solo tras finalizar. wcag21aa si se declaró conformidad.

outputsobject

Estado de cada salida.

credit_consumedboolean
billingJobBilling
noticesarray<Notice>

Lo que conviene completar con PATCH /jobs/{job_id}/metadata (no bloquea).

review_flagsarray<string (enum: fast_decisions, all_ai_suggestions_accepted, bulk_unchanged)>

Señales de revisión anómala (no bloquean; quedan registradas y las ve ab serveis). fast_decisions: 10 decisiones o más a menos de 3 segundos por elemento desde el fin del análisis (sin contar la validación en tabla del portal). all_ai_suggestions_accepted: 5 propuestas de la IA usadas o más, todas sin cambiar una letra. bulk_unchanged: en la validación en tabla del portal, 20 propuestas o más confirmadas sin ningún cambio.

errorProblem | null
portal_urlstring (uri)

Ficha del título en el portal de AccesPub. Modelo mixto: vuestro sistema orquesta por la API y la revisión humana se hace en el portal; enlazad aquí desde vuestro frontal. Los títulos de prueba llevan ?mode=test.

review_urlstring (uri)

Pantalla de revisión del título en el portal (botón «Revisar en AccesPub»). Hace falta una persona de la organización con sesión en el portal; si no la tiene, inicia sesión y vuelve a esta pantalla.

created_atstring (date-time)
updated_atstring (date-time)

OutputState string (enum: pending, ready, ready_with_warnings, missing_data, invalid, not_applicable, expired)

ready_with_warnings: se entrega, pero falta algo (ver missing en el manifiesto: ISBN para el ONIX, errores de EPUBCheck…). expired: los ficheros caducaron (30 días tras finalizar).

JobFileKind string (enum: epub, report_html, onix_a11y, onix_full, original)

Report report.schema.json

ReviewKind string (enum: image, table, language)

ReviewItem

NombreTipoDescripción
id (obligatorio)string
kind (obligatorio)ReviewKind
status (obligatorio)string (enum: pending, decided)
documentstring

Fichero XHTML dentro del EPUB.

context_beforestring
context_afterstring
imageobject

Solo en image.

tableobject

Solo en table.

languageobject

Solo en language.

decisionDecision | null

Decisión vigente. En idiomas de documento puede llevar auto: true: asignado automáticamente con alta confianza, sin revisión humana.

decided_byReviewer | null

Revisor de la decisión vigente, si se tomó por la API.

decided_atstring | null (date-time)
suggestionobject | null

Última propuesta de la IA para esta imagen o tabla (pedida a mano o preparada por el texto alternativo masivo, source: prefill), o null. No se aplica sola.

hintobject | null

Solo imágenes. Orientación para validarlas (no es una decisión): suggest (informative, decorative o null) con sus motivos (caption: pie de figura; cover: portada; tiny, thin, flat, repeated; empty_alt: solo informa) y el grupo de imágenes casi iguales al que pertenece (group, group_size), para validarlas seguidas.

AiPrefill

Estado de las propuestas de la IA preparadas en lote para un título (imágenes y tablas).

NombreTipoDescripción
statusstring (enum: none, running, paused, done)

none: no se han pedido · running: en cola o generándose · paused: la cola está en pausa (ab serveis) · done: terminado (las que fallan se pueden volver a pedir).

totalinteger
queuedinteger
runninginteger
doneinteger
failedinteger

La IA no respondió tras varios intentos.

skippedinteger

Decidida antes de llegar su turno, o la IA no pudo proponer (filtros).

imagesinteger

De total, cuántas son imágenes (texto alternativo).

tablesinteger

De total, cuántas son tablas (título de la tabla).

pausedboolean
billingobject

Cómo se cobra en esta organización: included (incluido en el crédito del título; exige saldo para finalizarlo) o paid (créditos por bloque de imágenes, cobrados al pedirlas y devueltos si no se generan).

Suggestion

NombreTipoDescripción
item_idstring
kindstring (enum: image, table)
textstring
languagestring

Idioma del elemento (BCP 47), en el que está escrita la propuesta.

providerstring
created_atstring (date-time)

Reviewer

Persona que toma la decisión. Con sesión la pone la sesión. Con clave de API la indica el cliente y email tiene que ser el de una persona activa de la organización (el correo se guarda en minúsculas; el nombre registrado es el de su cuenta).

NombreTipoDescripción
name (obligatorio)string
email (obligatorio)string (email)
external_idstring | null

Identificador en la plataforma del cliente.

Actor

NombreTipoDescripción
typestring (enum: user, api_key)
idstring
namestring

ImageDecision

NombreTipoDescripción
kind (obligatorio)
decorative (obligatorio)boolean

true escribe alt="".

altstring

Obligatorio si decorative es false.

from_suggestionboolean

Si el texto parte de una propuesta de la IA (queda registrado).

TableDecision

NombreTipoDescripción
kind (obligatorio)
layout (obligatorio)boolean

true = tabla de maquetación (role="presentation").

captionstring

Título de la tabla de datos (<caption>). Se ignora si layout es true.

first_row_as_headersboolean

Convertir la primera fila en cabeceras (<th scope="col">).

from_suggestionboolean

LanguageDecision

NombreTipoDescripción
kind (obligatorio)
action (obligatorio)string (enum: keep, remove, replace)

Idioma en línea (scope: inline): keep (conservar xml:lang) o remove (quitarlo). Idioma de documento (scope: document): keep (conservar el actual) o replace (usar new_lang). Idioma del libro (scope: book): keep (dejar el OPF como está; no se admite si no hay un idioma válido) o replace (escribir languages en el OPF).

new_langstring | null

Solo idioma de documento: BCP 47 válido con replace (se normaliza, p. ej. EU → eu).

languagesarray<string> | null

Solo idioma del libro, con replace: lista ordenada de códigos BCP 47, el principal primero (como el editor de idiomas del dashboard). Un solo idioma deja un único dc:language y aplica ese idioma a los documentos sin idioma propio.

autoboolean

Solo en respuestas; ver ReviewItem.decision.

Decision ImageDecision | TableDecision | LanguageDecision

DecisionBatch

NombreTipoDescripción
reviewer (obligatorio)Reviewer
decisions (obligatorio)array<object>

Notice

NombreTipoDescripción
codestring (enum: date_ambiguous, page_source_missing, title_placeholder, epubcheck_errors)

epubcheck_errors: tras las correcciones automáticas, EPUBCheck sigue encontrando errores que AccesPub no puede corregir (los mismos que el aviso de incompatibilidad del dashboard); vienen en errors. El EPUB se entrega sin conformidad: corregid el original o pedid ayuda (POST /jobs/{job_id}/support-requests). date_ambiguous: la fecha dc:date del EPUB no se puede interpretar (p. ej. 05/06/2020). page_source_missing: el libro tiene lista de páginas y no declara la edición impresa de la que proceden. title_placeholder: el EPUB no tenía título y AccesPub puso «[Sin título]».

fieldstring | null
valuestring | null
detailstring
errorsarray<EpubcheckMessage>

Solo en epubcheck_errors (hasta 50).

EpubcheckMessage

NombreTipoDescripción
levelstring
codestring
messagestring
locationstring

SupportRequestCreate

NombreTipoDescripción
message (obligatorio)string
contact_email (obligatorio)string (email)
share_epubboolean

Autoriza a ab serveis a descargar el EPUB original para diagnosticarlo.

SupportRequest

NombreTipoDescripción
idstring
job_idstring
statusstring (enum: open, answered, closed)
messagestring
contact_emailstring (email)
share_epubboolean
resolutionstring | null (enum: fix_planned, publisher_fix, manual_fix_quote, fixed, closed, None)
responsestring | null

Respuesta de ab serveis.

email_sentboolean

Si el aviso a ab serveis salió por correo.

created_atstring (date-time)
resolved_atstring | null (date-time)

MetadataField

NombreTipoDescripción
valuestring | null
sourcestring (enum: epub, override)

Metadata

NombreTipoDescripción
dcobject
languagesobject

Solo lectura (se decide con el elemento de revisión book_language).

accessibility_summaryobject
page_source_isbnstring | null
subjectsobject

Materias (las del EPUB clasificadas, o las indicadas con PATCH).

noticesarray<Notice>
updated_atstring | null (date-time)

MetadataUpdate

NombreTipoDescripción
dcobject

Texto no vacío, o null para volver al valor del EPUB.

accessibility_summarystring | null
page_source_isbnstring | null
subjectsobject | null

Sustituye a todas las materias. null vuelve a las del EPUB.

MetadataSuggestion

NombreTipoDescripción
descriptionstring

Sinopsis propuesta (200–400 palabras).

themaarray<object>
bisac_hintstring

Categoría BISAC descrita en texto (no un código).

keywordsarray<string>
rejected_codesarray<string>

Códigos Thema propuestos que no existen (descartados).

languagestring
providerstring
sampleobject
created_atstring (date-time)

SkipResult

NombreTipoDescripción
skippedinteger

Elementos saltados sin confirmar.

confirmedinteger

Decisiones guardadas con confirmación.

savedinteger
reviewReviewProgress
job_statusJobStatus

DecisionRecord

NombreTipoDescripción
item_idstring

id del elemento cuando se decidió (puede cambiar al reprocesar).

kindstring (enum: image, table, language)
decisionDecision
reviewerReviewer
decided_atstring (date-time)

DecisionResult

NombreTipoDescripción
savedinteger
reviewReviewProgress
job_statusJobStatus

ready si ya no queda nada pendiente; finalizing si el lote tiene auto_finalize.

Manifest

NombreTipoDescripción
batch_idstring
generated_atstring (date-time)
jobsarray<object>

LargeUploadRequestCreate

NombreTipoDescripción
batch_id (obligatorio)string
filename (obligatorio)string
size_bytes (obligatorio)integer
reason (obligatorio)string

LargeUploadRequest LargeUploadRequestCreate + object

NombreTipoDescripción
idstring
statusstring (enum: pending, approved, rejected, expired)
requested_byActor
valid_untilstring | null (date-time)
created_atstring (date-time)

Role string (enum: admin, batch_manager, reviewer, external_reviewer)

User

NombreTipoDescripción
idstring
namestring | null
emailstring (email)
roleRole
statusstring (enum: invited, active, deactivated)
batch_idstring | null

Solo revisores externos.

created_atstring (date-time)
last_login_atstring | null (date-time)

Invitation User + object

NombreTipoDescripción
access_urlstring

Enlace personal (invitación, contraseña o lote). No se vuelve a mostrar.

email_sentboolean

Session

NombreTipoDescripción
userUser
organizationobject
csrf_tokenstring

Valor para la cabecera X-CSRF-Token.

expires_atstring (date-time)

Caducidad actual. La sesión se renueva con la actividad: caduca tras 12 horas sin usarse y, como máximo, 7 días después de iniciarse.

ApiKey

NombreTipoDescripción
idstring
labelstring
modestring (enum: live, test)
prefixstring
created_atstring (date-time)
last_used_atstring | null (date-time)

EventType string (enum: job.needs_review, job.ready, job.completed, job.failed, job.ai_prefill_done, batch.completed, large_upload_request.resolved, support_request.answered, credits.low)

WebhookEndpoint

NombreTipoDescripción
idstring
urlstring (uri)
descriptionstring
modestring (enum: live, test)
eventsarray<EventType>
enabledboolean
disabled_reasonstring | null (enum: manual, failing, None)

failing: AccesPub la ha desactivado tras 5 días fallando sin interrupción (y ha avisado por correo a la administración).

disabled_atstring | null (date-time)
failing_sincestring | null (date-time)

Desde cuándo falla sin interrupción.

created_atstring (date-time)
updated_atstring (date-time)
last_deliveryobject | null

WebhookDelivery

Un envío de un evento a una dirección (con sus intentos).

NombreTipoDescripción
idstring
event_idstring

Igual que la cabecera webhook-id.

event_typestring
statusstring (enum: pending, retrying, delivered, failed)

failed: agotados los reintentos (≈25 h), dirección desactivada o prueba sin éxito.

attemptsinteger
last_attempt_atstring | null (date-time)
response_statusinteger | null

Código HTTP que respondió vuestro sistema.

errorstring | null

Motivo del último fallo: http_<código>, timeout, connection_error, tls_error, dns_error, blocked_address, endpoint_disabled.

next_attempt_atstring | null (date-time)
delivered_atstring | null (date-time)
created_atstring (date-time)

CreditsLow

NombreTipoDescripción
organization_idstring
creditsobject
thresholdinteger

Umbral de la organización (10 por defecto; lo ajusta ab serveis).

exhaustedboolean

true cuando el saldo ha llegado a 0.

WebhookTest

NombreTipoDescripción
endpoint_idstring
messagestring

Event

NombreTipoDescripción
id (obligatorio)string

Igual que la cabecera webhook-id.

type (obligatorio)string

Uno de EventType, o webhook.test.

created_at (obligatorio)string (date-time)
mode (obligatorio)string (enum: live, test)
data (obligatorio)object

El objeto afectado tal como lo devolvería un GET en el momento del evento: Job (eventos job.*; en job.ai_prefill_done con ai_prefill), Batch, LargeUploadRequest, SupportRequest, CreditsLow o WebhookTest.

Volver arriba