Reference · API de AccesPub 0.11.0
Generated from the OpenAPI contract 0.11.0. Descriptions are in Spanish; field names, codes and examples are language-neutral. Download 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
202y un trabajo en cola. El estado se consulta conGET /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-Keyen las operaciones que crean o cobran (borrador IETF).- Límite de peticiones con
429yRetry-After. - Fechas en ISO 8601 UTC. Tamaños en bytes. Paginación por cursor.
- Webhooks firmados según Standard Webhooks (HMAC-SHA256).
Server
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).
Authentication
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
Responses
| Code | Description | Type |
|---|---|---|
200 | Organización de la clave usada. | Organization |
default | Error (RFC 9457). | Problem |
Consumo de créditos por mes
GET /organization/usage
Parameters
| Name | In | Type | Description |
|---|---|---|---|
months | query | integer |
Responses
| Code | Description | Type |
|---|---|---|
200 | Consumo. | object |
default | Error (RFC 9457). | Problem |
Claves de la API (sin el secreto)
GET /api-keys
Responses
| Code | Description | Type |
|---|---|---|
200 | Claves. | object |
default | Error (RFC 9457). | Problem |
Crear una clave (solo administradores; se muestra entera una sola vez)
POST /api-keys
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
mode (required) | string (enum: live, test) | |
label (required) | string |
Responses
| Code | Description | Type |
|---|---|---|
201 | Clave creada. | ApiKey + object |
default | Error (RFC 9457). | Problem |
Revocar una clave
DELETE /api-keys/{key_id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
key_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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
Parameters
| Name | In | Type | Description |
|---|---|---|---|
cursor | query | string | Valor |
limit | query | integer | |
status | query | BatchStatus |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | 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. |
Request body (required)
application/json · BatchCreate
Responses
Estado de un lote
GET /batches/{batch_id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string |
Responses
Cambiar nombre, revisores o qué hacer con lo pendiente
PATCH /batches/{batch_id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string |
Request body (required)
application/json · BatchUpdate
Responses
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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 →
409nothing-to-finalize. - Un
job_idsque no es del lote →404; uno que no se puede finalizar (pendientes sinallow_pending, en proceso) →409.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string | |
Idempotency-Key | header | string | 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. |
Request body
application/json · object
| Name | Type | Description |
|---|---|---|
allow_pending | boolean | |
job_ids | array<string> | Solo estos títulos. Por defecto, todos los que cumplan la condición. |
Responses
Trabajos
Un trabajo es un EPUB dentro de un lote.
Trabajos (títulos) de un lote
GET /batches/{batch_id}/jobs
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string | |
cursor | query | string | Valor |
limit | query | integer | |
status | query | JobStatus |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string | |
Idempotency-Key | header | string | 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. |
Request body (required)
multipart/form-data · object
| Name | Type | Description |
|---|---|---|
file (required) | string (binary) | El EPUB. |
external_id | string | Identificador del título en la plataforma del cliente (se devuelve tal cual). |
isbn | string | ISBN-13 si el EPUB no lo declara (se ignoran guiones y espacios). Se usa en el ONIX. |
Responses
Estado de un trabajo
GET /jobs/{job_id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
Asignar revisores o corregir datos del título
PATCH /jobs/{job_id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
assignee_user_ids | array<string> | Revisores de este título (si no, los del lote). |
external_id | string | |
isbn | string |
Responses
Quitar un título del lote y borrar sus ficheros
DELETE /jobs/{job_id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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 →
409job-not-ready. - Ficheros caducados →
410files-expired.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string | |
Idempotency-Key | header | string | 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. |
Responses
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
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 avisadate_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 losdc:subjectdel 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.nullvuelve a las materias del EPUB. No se combina condc.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).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Request body (required)
application/json · MetadataUpdate
Responses
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→429conRetry-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 →
422ai-blocked. IA saturada o no configurada →503ai-unavailable.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
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_pendingesfalse→409pending-review. - Con
allow_pending: truese entrega sindcterms:conformsToy el informe lista lo pendiente. - Sin créditos →
402. - En cola, en proceso o ya finalizándose →
409job-not-ready. - Ficheros caducados →
410files-expired.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string | |
Idempotency-Key | header | string | 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. |
Request body
application/json · object
| Name | Type | Description |
|---|---|---|
allow_pending | boolean |
Responses
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string | |
cursor | query | string | Valor |
limit | query | integer | |
status | query | string (enum: pending, decided, all) | |
kind | query | ReviewKind |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string | |
item_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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_minutepor organización →429conRetry-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 →
422ai-blocked: hay que escribirlo a mano. - IA saturada o no disponible →
503ai-unavailableconRetry-After; error del proveedor →502ai-error.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string | |
item_id (required) | path | string |
Responses
Estado de las propuestas de la IA del título
GET /jobs/{job_id}/ai-prefill
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
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 (reviewerobligatorio), 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 conallow_pending.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string | |
Idempotency-Key | header | string | 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. |
Request body
application/json · object
| Name | Type | Description |
|---|---|---|
confirm_decorative | boolean | |
reviewer | Reviewer |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string | |
Idempotency-Key | header | string | 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. |
Request body (required)
application/json · DecisionBatch
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string | |
kind (required) | path | JobFileKind | |
lang | query | string (enum: es, en, ca, fr) | Idioma del informe HTML. |
naming | query | string (enum: filename, isbn) | Nombre de los ficheros descargados. |
Responses
Manifiesto del lote (estado de cada título y cada salida)
GET /batches/{batch_id}/manifest
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string | |
format | query | string (enum: json, csv) | json o csv. Si se omite, CSV cuando la cabecera Accept pide text/csv. |
Responses
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string | |
kind (required) | path | string (enum: epubs, reports, onix_a11y, onix_full) | |
job_ids | query | string | Solo estos títulos (separados por comas). Por defecto, todos los finalizados. |
lang | query | string (enum: es, en, ca, fr) | Idioma del informe HTML. |
naming | query | string (enum: filename, isbn) | Nombre de los ficheros descargados. |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Request body (required)
application/json · Commercial + object
| Name | Type | Description |
|---|---|---|
apply_to_batch | array<string> |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string |
Request body (required)
application/json · Commercial
Responses
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
batch_id (required) | path | string |
Request body
application/json · object
| Name | Type | Description |
|---|---|---|
job_ids | array<string> |
Responses
Subidas grandes
Permiso temporal para EPUB de más de 50 MB.
Solicitudes de subida grande de la organización
GET /large-upload-requests
Responses
| Code | Description | Type |
|---|---|---|
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.
Request body (required)
application/json · LargeUploadRequestCreate
Responses
| Code | Description | Type |
|---|---|---|
201 | Solicitud registrada (estado | 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
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
job_id (required) | path | string |
Request body (required)
application/json · SupportRequestCreate
Responses
| Code | Description | Type |
|---|---|---|
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
Parameters
| Name | In | Type | Description |
|---|---|---|---|
status | query | string (enum: open, answered, closed) |
Responses
| Code | Description | Type |
|---|---|---|
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
Responses
| Code | Description | Type |
|---|---|---|
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(conbatch_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).
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
email (required) | string (email) | |
role (required) | Role | |
name | string | Si no, la persona lo indica al aceptar. |
batch_id | string | Solo para |
send_email | boolean |
|
Responses
| Code | Description | Type |
|---|---|---|
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.
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
token (required) | string | |
password (required) | string | |
name | string |
Responses
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.
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
email (required) | string (email) | |
password (required) | string |
Responses
Entrar con el enlace de un lote (revisores externos)
POST /sessions/link
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
token (required) | string |
Responses
Cerrar la sesión
DELETE /sessions/current
Responses
| Code | Description | Type |
|---|---|---|
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
Responses
| Code | Description | Type |
|---|---|---|
200 | Identidad. | object |
default | Error (RFC 9457). | Problem |
Cambiar la propia contraseña (cierra las demás sesiones)
POST /me/password
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
current_password (required) | string | |
new_password (required) | string |
Responses
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).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
user_id (required) | path | string |
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
role (required) | string (enum: admin, batch_manager, reviewer) |
Responses
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).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
user_id (required) | path | string |
Responses
Enlace de acceso al portal para una persona (modelo mixto)
POST /users/{user_id}/sign-in-link
Para que quien revisa salte de vuestra aplicación al portal sin volver a iniciar
sesión. Vuestro servidor lo pide justo cuando la persona pulsa «Revisar en
AccesPub» y la redirige a url: el portal abre su sesión, en el modo de la clave
(real o prueba), y la lleva a next (por ejemplo, el review_url del título).
Sus decisiones quedan firmadas por ella.
- Solo con clave de API, desde vuestro servidor (nunca en el navegador ni en
una app). Con sesión de persona →
403. - Hay que pedir que se active para vuestra organización: AccesPub confía en
vuestro inicio de sesión para identificar a vuestra gente. Sin activar →
403sign-in-links-disabled. - Un solo uso y 5 minutos. Pedidlo en el momento del clic, no por adelantado.
- Sin escalar privilegios: una clave que no es de administración no puede
pedirlo para una persona administradora (
403). - La persona tiene que ser de vuestra organización (
404) y no estar dada de baja (409user-deactivated). Una persona invitada que aún no tiene contraseña queda activa al usarlo (versend_emailenPOST /invitations). next: una ruta del portal (/portal/…) o una dirección completa del portal, comoreview_urloportal_url. Otra cosa →422. Sinnext, la lista de lotes.- Cada enlace queda registrado (persona, clave, fecha y destino).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
user_id (required) | path | string |
Request body
application/json · object
| Name | Type | Description |
|---|---|---|
next | string |
Responses
Enlace nuevo (reenviar invitación, restablecer contraseña o enlace de lote)
POST /users/{user_id}/access-link
Invalida el enlace anterior del mismo tipo. Para una persona activa con
contraseña, el enlace sirve para restablecerla (POST /invitations/accept).
Dada de baja → 409 user-deactivated.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
user_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
201 | Enlace creado. | Invitation |
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.
Responses
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.
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
url (required) | string (uri) | |
description | string | |
events | array<EventType> | Tipos de evento. Sin |
Responses
Una dirección (sin el secreto)
GET /webhook-endpoints/{endpoint_id}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
endpoint_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
endpoint_id (required) | path | string |
Request body (required)
application/json · object
| Name | Type | Description |
|---|---|---|
url | string (uri) | |
description | string | |
events | array<EventType> | |
enabled | boolean |
Responses
| Code | Description | Type |
|---|---|---|
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}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
endpoint_id (required) | path | string |
Responses
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
endpoint_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
endpoint_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
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
Parameters
| Name | In | Type | Description |
|---|---|---|---|
endpoint_id (required) | path | string | |
status | query | string (enum: pending, retrying, delivered, failed) | |
limit | query | integer |
Responses
| Code | Description | Type |
|---|---|---|
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}
Parameters
| Name | In | Type | Description |
|---|---|---|---|
endpoint_id (required) | path | string | |
delivery_id (required) | path | string |
Responses
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).
Parameters
| Name | In | Type | Description |
|---|---|---|---|
endpoint_id (required) | path | string | |
delivery_id (required) | path | string |
Responses
| Code | Description | Type |
|---|---|---|
202 | En cola. | WebhookDelivery |
409 | Error (RFC 9457). | Problem |
default | Error (RFC 9457). | Problem |
Webhook events
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
Schemas
Market
Un mercado del ONIX comercial (un ProductSupply).
| Name | Type | Description |
|---|---|---|
territory (required) | string | Países ISO 3166-1 separados por espacios ( |
countries_excluded | string | Solo con una región (p. ej. |
currency | string | ISO 4217 (lista 96). |
price_amount | string | Importe; se acepta coma decimal. Sin precio → «precio por anunciar». |
price_type | string | Lista 58. Por defecto |
tax_percent | string | IVA incluido en el precio, en %. Vacío si el precio no incluye impuestos. |
availability | string | Lista 65. Por defecto |
supplier_name | string | Proveedor de este mercado; por defecto, |
supplier_role | string | Lista 93. Por defecto |
sale_date | string | Fecha de venta en el mercado (AAAA-MM-DD). |
market_status | string | Lista 68. Por defecto |
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.
| Name | Type | Description |
|---|---|---|
subtitle | string | |
collection | string | |
collection_number | string | |
imprint | string | |
pub_status | string | Lista 64. Por defecto |
publishing_date | string | AAAA, AAAA-MM o AAAA-MM-DD. Manda sobre el |
city | string | |
country | string | ISO 3166-1 (lista 91). |
copyright_year | string | |
copyright_owner | string | |
audience | string | Lista 28. |
age_from | string | |
age_to | string | |
contributors | array<object> | Sustituye a la autoría del EPUB. |
print_format | string (enum: Paperback, Hardcover) | |
cover_url | string (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 |
supplier_name | string | |
supplier_role | string | |
markets | array<Market> |
CommercialIssue
| Name | Type | Description |
|---|---|---|
code | string (enum: not_finalized, isbn_missing, publisher_missing, markets_missing, market_unpriced, date_missing, cover_missing, xsd_invalid) | |
level | string (enum: error, warning) | |
field | string |
CommercialBilling
| Name | Type | Description |
|---|---|---|
mode | string (enum: off, included, paid) | |
credits_per_title | integer |
CommercialView
| Name | Type | Description |
|---|---|---|
title | Commercial | |
batch | Commercial | |
effective | Commercial | |
sources | object | |
isbn | string | null | |
publisher | string | null | |
issues | array<CommercialIssue> | |
ready | boolean | |
onix_full | object | null | |
billing | CommercialBilling + object |
OnixFullResult
| Name | Type | Description |
|---|---|---|
generated | array<object> | |
credits_charged | integer |
Problem
| Name | Type | Description |
|---|---|---|
type (required) | string (uri) |
|
title (required) | string | |
status (required) | integer | |
detail | string | |
instance | string | |
credits_required | integer | Solo en |
credits_available | integer | Solo en |
errors | array<object> | Detalle por campo, en errores de validación. |
Page
| Name | Type | Description |
|---|---|---|
next_cursor | string | null |
|
Organization
| Name | Type | Description |
|---|---|---|
id | string | |
name | string | |
plan | string | |
mode | string (enum: live, test) | |
credits | object | |
storage | object | |
limits | Limits |
Limits
| Name | Type | Description |
|---|---|---|
max_epub_bytes | integer | |
max_large_epub_bytes | integer | |
max_jobs_per_batch | integer | |
max_batch_bytes | integer | |
ai_suggestions_per_minute | integer |
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
| Name | Type | Description |
|---|---|---|
name (required) | string | |
on_pending | OnPending | |
auto_finalize | AutoFinalize | |
defaults | object | |
reviewer_user_ids | array<string> | |
external_id | string |
BatchUpdate
| Name | Type | Description |
|---|---|---|
name | string | |
on_pending | OnPending | |
auto_finalize | AutoFinalize | |
reviewer_user_ids | array<string> |
Batch
| Name | Type | Description |
|---|---|---|
id | string | |
name | string | |
status | BatchStatus | |
on_pending | OnPending | |
auto_finalize | AutoFinalize | |
ai_prefill | boolean | El lote pide las propuestas de la IA al analizar (defaults.ai_prefill). |
portal_url | string (uri) | El lote en el portal de AccesPub (los de prueba, con |
external_id | string | null | |
created_at | string (date-time) | |
created_by | Actor | |
counts | object | |
review | ReviewProgress | |
size_bytes | integer | |
credits | object | Créditos del lote (solo cuentan en modo live). |
ReviewProgress
| Name | Type | Description |
|---|---|---|
total | integer | |
decided | integer | |
pending | integer |
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.
| Name | Type | Description |
|---|---|---|
images | integer | null | Imágenes del libro (null hasta el análisis). |
images_per_credit | integer | |
credits_required | integer | |
credits_charged | integer | Cobrados en la finalización (0 si aún no). |
extra_credits_acknowledged_at | string | null (date-time) |
Job
| Name | Type | Description |
|---|---|---|
id | string | |
batch_id | string | |
status | JobStatus | |
filename | string | |
size_bytes | integer | |
external_id | string | null | |
title | string | null | dc:title del EPUB. |
isbn | string | null | |
epub_version | string | null | |
review | ReviewProgress | |
conformance | string | null (enum: wcag21aa, none, None) | Solo tras finalizar. |
outputs | object | Estado de cada salida. |
credit_consumed | boolean | |
billing | JobBilling | |
notices | array<Notice> | Lo que conviene completar con |
review_flags | array<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). |
error | Problem | null | |
portal_url | string (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 |
review_url | string (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_at | string (date-time) | |
updated_at | string (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
| Name | Type | Description |
|---|---|---|
id (required) | string | |
kind (required) | ReviewKind | |
status (required) | string (enum: pending, decided) | |
document | string | Fichero XHTML dentro del EPUB. |
context_before | string | |
context_after | string | |
image | object | Solo en |
table | object | Solo en |
language | object | Solo en |
decision | Decision | null | Decisión vigente. En idiomas de documento puede llevar |
decided_by | Reviewer | null | Revisor de la decisión vigente, si se tomó por la API. |
decided_at | string | null (date-time) | |
suggestion | object | null | Última propuesta de la IA para esta imagen o tabla (pedida a mano o preparada
por el texto alternativo masivo, |
hint | object | null | Solo imágenes. Orientación para validarlas (no es una decisión): |
AiPrefill
Estado de las propuestas de la IA preparadas en lote para un título (imágenes y tablas).
| Name | Type | Description |
|---|---|---|
status | string (enum: none, running, paused, done) |
|
total | integer | |
queued | integer | |
running | integer | |
done | integer | |
failed | integer | La IA no respondió tras varios intentos. |
skipped | integer | Decidida antes de llegar su turno, o la IA no pudo proponer (filtros). |
images | integer | De |
tables | integer | De |
paused | boolean | |
billing | object | Cómo se cobra en esta organización: |
Suggestion
| Name | Type | Description |
|---|---|---|
item_id | string | |
kind | string (enum: image, table) | |
text | string | |
language | string | Idioma del elemento (BCP 47), en el que está escrita la propuesta. |
provider | string | |
created_at | string (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).
| Name | Type | Description |
|---|---|---|
name (required) | string | |
email (required) | string (email) | |
external_id | string | null | Identificador en la plataforma del cliente. |
Actor
| Name | Type | Description |
|---|---|---|
type | string (enum: user, api_key) | |
id | string | |
name | string |
ImageDecision
| Name | Type | Description |
|---|---|---|
kind (required) | ||
decorative (required) | boolean |
|
alt | string | Obligatorio si |
from_suggestion | boolean | Si el texto parte de una propuesta de la IA (queda registrado). |
TableDecision
| Name | Type | Description |
|---|---|---|
kind (required) | ||
layout (required) | boolean |
|
caption | string | Título de la tabla de datos ( |
first_row_as_headers | boolean | Convertir la primera fila en cabeceras ( |
from_suggestion | boolean |
LanguageDecision
| Name | Type | Description |
|---|---|---|
kind (required) | ||
action (required) | string (enum: keep, remove, replace) | Idioma en línea ( |
new_lang | string | null | Solo idioma de documento: BCP 47 válido con |
languages | array<string> | null | Solo idioma del libro, con |
auto | boolean | Solo en respuestas; ver |
Decision ImageDecision | TableDecision | LanguageDecision
DecisionBatch
| Name | Type | Description |
|---|---|---|
reviewer (required) | Reviewer | |
decisions (required) | array<object> |
Notice
| Name | Type | Description |
|---|---|---|
code | string (enum: date_ambiguous, page_source_missing, title_placeholder, epubcheck_errors) |
|
field | string | null | |
value | string | null | |
detail | string | |
errors | array<EpubcheckMessage> | Solo en |
EpubcheckMessage
| Name | Type | Description |
|---|---|---|
level | string | |
code | string | |
message | string | |
location | string |
SupportRequestCreate
| Name | Type | Description |
|---|---|---|
message (required) | string | |
contact_email (required) | string (email) | |
share_epub | boolean | Autoriza a ab serveis a descargar el EPUB original para diagnosticarlo. |
SupportRequest
| Name | Type | Description |
|---|---|---|
id | string | |
job_id | string | |
status | string (enum: open, answered, closed) | |
message | string | |
contact_email | string (email) | |
share_epub | boolean | |
resolution | string | null (enum: fix_planned, publisher_fix, manual_fix_quote, fixed, closed, None) | |
response | string | null | Respuesta de ab serveis. |
email_sent | boolean | Si el aviso a ab serveis salió por correo. |
created_at | string (date-time) | |
resolved_at | string | null (date-time) |
MetadataField
| Name | Type | Description |
|---|---|---|
value | string | null | |
source | string (enum: epub, override) |
Metadata
| Name | Type | Description |
|---|---|---|
dc | object | |
languages | object | Solo lectura (se decide con el elemento de revisión |
accessibility_summary | object | |
page_source_isbn | string | null | |
subjects | object | Materias (las del EPUB clasificadas, o las indicadas con PATCH). |
notices | array<Notice> | |
updated_at | string | null (date-time) |
MetadataUpdate
| Name | Type | Description |
|---|---|---|
dc | object | Texto no vacío, o |
accessibility_summary | string | null | |
page_source_isbn | string | null | |
subjects | object | null | Sustituye a todas las materias. |
MetadataSuggestion
| Name | Type | Description |
|---|---|---|
description | string | Sinopsis propuesta (200–400 palabras). |
thema | array<object> | |
bisac_hint | string | Categoría BISAC descrita en texto (no un código). |
keywords | array<string> | |
rejected_codes | array<string> | Códigos Thema propuestos que no existen (descartados). |
language | string | |
provider | string | |
sample | object | |
created_at | string (date-time) |
SkipResult
| Name | Type | Description |
|---|---|---|
skipped | integer | Elementos saltados sin confirmar. |
confirmed | integer | Decisiones guardadas con confirmación. |
saved | integer | |
review | ReviewProgress | |
job_status | JobStatus |
DecisionRecord
DecisionResult
| Name | Type | Description |
|---|---|---|
saved | integer | |
review | ReviewProgress | |
job_status | JobStatus |
|
Manifest
| Name | Type | Description |
|---|---|---|
batch_id | string | |
generated_at | string (date-time) | |
jobs | array<object> |
LargeUploadRequestCreate
| Name | Type | Description |
|---|---|---|
batch_id (required) | string | |
filename (required) | string | |
size_bytes (required) | integer | |
reason (required) | string |
LargeUploadRequest LargeUploadRequestCreate + object
| Name | Type | Description |
|---|---|---|
id | string | |
status | string (enum: pending, approved, rejected, expired) | |
requested_by | Actor | |
valid_until | string | null (date-time) | |
created_at | string (date-time) |
Role string (enum: admin, batch_manager, reviewer, external_reviewer)
User
| Name | Type | Description |
|---|---|---|
id | string | |
name | string | null | |
email | string (email) | |
role | Role | |
status | string (enum: invited, active, deactivated) | |
batch_id | string | null | Solo revisores externos. |
created_at | string (date-time) | |
last_login_at | string | null (date-time) |
Invitation User + object
| Name | Type | Description |
|---|---|---|
access_url | string | Enlace personal (invitación, contraseña o lote). No se vuelve a mostrar. |
email_sent | boolean |
Session
| Name | Type | Description |
|---|---|---|
user | User | |
organization | object | |
csrf_token | string | Valor para la cabecera X-CSRF-Token. |
expires_at | string (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. |
SignInLink
| Name | Type | Description |
|---|---|---|
url | string (uri) | Enlace de un solo uso al portal ( |
expires_at | string (date-time) | 5 minutos después de pedirlo. |
user_id | string | |
next | string | Pantalla del portal a la que lleva (ruta). |
ApiKey
| Name | Type | Description |
|---|---|---|
id | string | |
label | string | |
mode | string (enum: live, test) | |
prefix | string | |
created_at | string (date-time) | |
last_used_at | string | 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
| Name | Type | Description |
|---|---|---|
id | string | |
url | string (uri) | |
description | string | |
mode | string (enum: live, test) | |
events | array<EventType> | |
enabled | boolean | |
disabled_reason | string | null (enum: manual, failing, None) |
|
disabled_at | string | null (date-time) | |
failing_since | string | null (date-time) | Desde cuándo falla sin interrupción. |
created_at | string (date-time) | |
updated_at | string (date-time) | |
last_delivery | object | null |
WebhookDelivery
Un envío de un evento a una dirección (con sus intentos).
| Name | Type | Description |
|---|---|---|
id | string | |
event_id | string | Igual que la cabecera |
event_type | string | |
status | string (enum: pending, retrying, delivered, failed) |
|
attempts | integer | |
last_attempt_at | string | null (date-time) | |
response_status | integer | null | Código HTTP que respondió vuestro sistema. |
error | string | null | Motivo del último fallo: |
next_attempt_at | string | null (date-time) | |
delivered_at | string | null (date-time) | |
created_at | string (date-time) |
CreditsLow
| Name | Type | Description |
|---|---|---|
organization_id | string | |
credits | object | |
threshold | integer | Umbral de la organización (10 por defecto; lo ajusta ab serveis). |
exhausted | boolean | true cuando el saldo ha llegado a 0. |
WebhookTest
| Name | Type | Description |
|---|---|---|
endpoint_id | string | |
message | string |
Event
| Name | Type | Description |
|---|---|---|
id (required) | string | Igual que la cabecera |
type (required) | string | Uno de EventType, o |
created_at (required) | string (date-time) | |
mode (required) | string (enum: live, test) | |
data (required) | object | El objeto afectado tal como lo devolvería un GET en el momento del evento:
|