API v1 https://scholaris-v2.jlsf2005.workers.dev/api/v1
Subes cualquier cosa, buscas, preguntas y citas.
Una cabecera, nueve verbos y JSON de ida y vuelta (o Markdown, que los agentes leen mejor). Cada pasaje llega con su página impresa o su segundo exactos y un enlace al lector, y ninguna cita sale de un modelo: todas salen del ancla guardada.
Los ejemplos se pueden copiar y pegar tal cual: solo hace falta la variable SCHOLARIS con tu clave.
Los nueve verbos
Todo cuelga de una misma dirección base. Los nombres de los campos están en castellano y en minúsculas.
https://scholaris-v2.jlsf2005.workers.dev/api/v1
POST/api/v1/documentos
Sube cualquier cosa: el fichero como cuerpo (PDF, EPUB, DOCX, presentaciones, hojas, audio, vídeo, imágenes), un formulario multipart con el campo archivo o un JSON con url (una web, un PDF, YouTube, Vimeo, un pódcast). Si el fichero ya estaba (misma huella SHA-256), devuelve el que hay con duplicado.
# Un fichero, como cuerpo (con su tipo y su nombre)
curl -s "https://scholaris-v2.jlsf2005.workers.dev/api/v1/documentos?nombre=libro.epub" -H "Authorization: Bearer $SCHOLARIS" \
-H "Content-Type: application/epub+zip" --data-binary @libro.epub
# Una URL (web, PDF, YouTube, Vimeo, pódcast), sin esperar
curl -s "https://scholaris-v2.jlsf2005.workers.dev/api/v1/documentos?esperar=0" -H "Authorization: Bearer $SCHOLARIS" \
-H "Content-Type: application/json" -d '{"url": "https://www.youtube.com/watch?v=fNk_zzaMoSs"}'
# Un formulario, con la ficha
curl -s https://scholaris-v2.jlsf2005.workers.dev/api/v1/documentos -H "Authorization: Bearer $SCHOLARIS" \
-F archivo=@entrevista.mp3 -F titulo="A fondo" -F autores="Cortázar, Julio" -F anio=1977
GET/api/v1/documentos
Lista la biblioteca. Filtra con q (título o autor) y estado; pagina con cursor.
Lee el texto por páginas o por un tramo de tiempo. desde y hasta admiten el folio impreso (23, xiv), la posición física entre corchetes ([12]) y, en audio y vídeo, tiempos (1:06:56).
# Las páginas 23 a 25 tal como están impresas
curl -sG https://scholaris-v2.jlsf2005.workers.dev/api/v1/documentos/ID/texto -H "Authorization: Bearer $SCHOLARIS" -d desde=23 -d hasta=25 -d formato=markdown
# Un tramo de una entrevista
curl -sG https://scholaris-v2.jlsf2005.workers.dev/api/v1/documentos/ID/texto -H "Authorization: Bearer $SCHOLARIS" -d desde=1:06:00 -d hasta=1:08:00
GET/api/v1/buscar
Busca pasajes (búsqueda híbrida y reordenada). Entre comillas, una frase literal. Cada pasaje trae cita, localizador, ancla, enlace y el texto literal.
curl -sG https://scholaris-v2.jlsf2005.workers.dev/api/v1/buscar -H "Authorization: Bearer $SCHOLARIS" \
--data-urlencode "q=la música me metía en el tiempo" -d k=5
POST/api/v1/preguntar
Responde en Markdown con notas al pie [^n]. El redactor solo puede citar los pasajes que se le dan, y cada nota se comprueba. Con stream llega por eventos.
curl -s https://scholaris-v2.jlsf2005.workers.dev/api/v1/preguntar -H "Authorization: Bearer $SCHOLARIS" -H "Content-Type: application/json" \
-d '{"pregunta": "¿Qué le pasa a Johnny con el tiempo cuando toca?"}'
POST/api/v1/citar
Devuelve tu texto con las citas insertadas (página exacta y cualquier estilo CSL) y la bibliografía. También acepta un .docx y lo devuelve citado, con su formato.
curl -s https://scholaris-v2.jlsf2005.workers.dev/api/v1/citar -H "Authorization: Bearer $SCHOLARIS" -H "Content-Type: application/json" \
-d '{"texto": "La música no saca a Johnny del tiempo: lo mete en otro.", "estilo": "chicago-author-date"}'
# Un .docx, devuelto citado
curl -s "https://scholaris-v2.jlsf2005.workers.dev/api/v1/citar?estilo=apa" -H "Authorization: Bearer $SCHOLARIS" \
-H "Content-Type: application/vnd.openxmlformats-officedocument.wordprocessingml.document" \
-H "Accept: application/vnd.openxmlformats-officedocument.wordprocessingml.document" \
--data-binary @trabajo.docx -o trabajo-citado.docx
POST/api/v1/verificar
Dice si tu biblioteca respalda una afirmación: respaldada, parcial, sin_respaldo o contradicha, con la probabilidad y los pasajes.
curl -s https://scholaris-v2.jlsf2005.workers.dev/api/v1/verificar -H "Authorization: Bearer $SCHOLARIS" -H "Content-Type: application/json" \
-d '{"afirmacion": "Johnny Carter dice que la música lo mete en el tiempo."}'
Cualquier lectura admite formato=markdown (o la cabecera Accept: text/markdown).
Lo que tarda (subir y citar) espera por defecto y responde con el resultado. Para no esperar, esperar=0 o la cabecera Prefer: respond-async: la respuesta es un 202 con progreso_url.
Una sesión de verdad
Cinco órdenes grabadas tal cual contra la versión local, con los ficheros del banco de pruebas: un cuento de Cortázar en PDF y una clase en audio ya subida. Las respuestas largas están recortadas donde dice […].
{
"id": "dmuwzohwaoqul34wy",
"titulo": "El perseguidor",
"autores": [
"Cortázar, Julio"
],
"estado": "listo",
"unidades": 37,
"referencia": "Cortázar, J. (1996). El perseguidor."
}
Buscar, en Markdown
curl -sG "$B/buscar" \
-H "Authorization: Bearer $SCHOLARIS" \
--data-urlencode "q=la música me metía en el tiempo" -d k=2 -d formato=markdown
# la música me metía en el tiempo
## 1. (Cortázar, 1996, p. 5)
*El perseguidor* · p. 5 · [abrir](http://localhost:8795/lector/dmuwzohwaoqul34wy?u=5&f=dmuwzohwaoqul34wy%3At0.8) · `dmuwzohwaoqul34wy:t0.8`
> Vaya si lo he oído; vaya si he tratado de escribirlo bien y verídicamente en mi biografía de Johnny.
>
> —Por eso en casa el tiempo no acababa nunca, sabes. De pelea en pelea, casi sin comer. Y para colmo la religión, ah, eso no te lo puedes imaginar. Cuando el maestro me consiguió un saxo que te hubieras muerto de risa si lo ves, entonces creo que me di cuenta en seguida. La música me sacaba del tiempo, aunque no es más que una manera de decirlo. Si quieres saber lo que realmente siento, yo creo que la música me metía en el tiempo. Pero entonces hay que creer que este tiempo no tiene nada que ver con... bueno, con nosotros, por decirlo así.
>
[…]
curl -s "$B/preguntar?formato=markdown" \
-H "Authorization: Bearer $SCHOLARIS" \
-H "Content-Type: application/json" \
-d '{"pregunta":"¿Qué le pasa a Johnny con el tiempo cuando toca?"}'
Cuando Johnny toca, experimenta que el tiempo cambia[^1][^2]. Aunque en un principio expresa que «la música me sacaba del tiempo», matiza que en realidad siente que lo «metía en el tiempo», entendiendo que se trata de un tiempo distinto que no tiene que ver con el orden cotidiano[^3]. Niega que se trate de una abstracción; más bien describe que simplemente cambia de lugar, comparando la experiencia con entrar en «un ascensor de tiempo» donde transcurren decenas de pisos en lo que dura una sola frase, mientras asuntos como las hipotecas o la religión dejan de existir para él[^4]. Asimismo, percibe la elasticidad del tiempo mediante la metáfora de una valija en la que, al tocar, es capaz de meter «cientos y cientos de trajes» o «una tienda entera»[^5].
Durante esos momentos musicales, Johnny siente que se abre una puerta y que vuela hacia un estado de seguridad donde queda «sobre todo sin tiempo, sin que después... sin que hubiera después... Por un rato no hubo más que siempre...»[^6]. Sin embargo, esa vivencia dura solo mientras se encuentra sumergido en la música; al dejar de tocar, cae de nuevo «de cabeza» en sí mismo[^6]. Bruno observa que en su ejecución Johnny «siempre está tocando mañana», adelantándose sin esfuerzo al hoy[^3], y viviendo intensamente lo que describe como su «cuarto de hora de minuto y medio», una alteración temporal frente al límite impuesto por los relojes[^1][^7].
[^1]: Cortázar, *El perseguidor* (1996), p. 9.
[^2]: Cortázar, *El perseguidor* (1996), p. 5.
[^3]: Cortázar, *El perseguidor* (1996), p. 5.
[^4]: Cortázar, *El perseguidor* (1996), pp. 5-6.
[^5]: Cortázar, *El perseguidor* (1996), p. 6.
[^6]: Cortázar, *El perseguidor* (1996), p. 34.
[^7]: Cortázar, *El perseguidor* (1996), pp. 16-17.
---
Fuentes (confianza alta):
[…]
Citar un texto propio
curl -s "$B/citar?formato=markdown" \
-H "Authorization: Bearer $SCHOLARIS" \
-H "Content-Type: application/json" \
-d '{"texto":"Johnny Carter siente que la música no lo saca del tiempo, sino que lo mete en otro. Ese tiempo no se parece al de los relojes.","estilo":"apa"}'
Johnny Carter siente que la música no lo saca del tiempo, sino que lo mete en otro (Cortázar, 1996, p. 5). Ese tiempo no se parece al de los relojes (Cortázar, 1996, pp. 8-9).
## Referencias
- Cortázar, J. (1996). El perseguidor.
Desde JavaScript
Con fetch y nada más (Node 20 o el navegador). Diez líneas: subir, buscar y preguntar.
import { readFile } from 'node:fs/promises';
const B = 'https://scholaris-v2.jlsf2005.workers.dev/api/v1';
const h = { Authorization: `Bearer ${process.env.SCHOLARIS}` };
const pedir = async (ruta, o = {}) => (await fetch(B + ruta, { ...o, headers: { ...h, ...o.headers } })).json();
const doc = await pedir('/documentos?nombre=articulo.pdf', { method: 'POST', headers: { 'Content-Type': 'application/pdf' }, body: await readFile('articulo.pdf') });
const { pasajes } = await pedir(`/buscar?k=3&q=${encodeURIComponent('atención escalada')}`);
for (const p of pasajes) console.log(p.cita, p.texto.slice(0, 80), p.enlace);
const r = await pedir('/preguntar', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pregunta: '¿Qué es la atención multicabeza?' }) });
console.log(r.respuesta);
Desde Python
El SDK trae una fachada de cinco verbos sobre esta misma API. Instálalo con pip (solo necesita requests):
pip install scholaris-sdk
from scholaris.api import Scholaris
s = Scholaris("sch_…") # o la variable SCHOLARIS_CLAVE
doc = s.subir("articulo.pdf") # también una URL
for p in s.buscar("atención escalada", k=3):
print(p["cita"], p["texto"][:80], p["enlace"])
print(s.preguntar("¿Qué es la atención multicabeza?")["respuesta"])
print(s.citar("La atención sustituye a la recurrencia.")["texto"])
print(s.verificar("El Transformer prescinde de la recurrencia.")["veredicto"])
Para agentes
Hay dos caminos: el servidor MCP, para los agentes que hablan MCP, y esta API, que cualquier agente con una herramienta HTTP sabe usar.
En Claude Code, con una clave que tenga el alcance «mcp»:
En Claude (web o escritorio): Ajustes → Conectores → Añadir conector personalizado, con esta dirección. Inicias sesión en Scholaris y concedes acceso; no hace falta clave.
Cita solo lo que devuelve la API, y copia cita y localizador tal cual.
Si citas literalmente, copia el texto literal; si parafraseas, pon igualmente la cita.
Da el enlace: es la manera de comprobar la página o el segundo.
Si la búsqueda no encuentra nada, dilo; no rellenes el hueco de memoria.
Cuando algo falla
Los errores dicen qué ha pasado en castellano («mensaje») y en inglés («message»), con un código estable para el programa y el enlace a esta guía:
{
"error": {
"codigo": "prohibido",
"mensaje": "Esta clave de API es de solo lectura.",
"message": "This key is not allowed to do that (check its scopes: lectura, escritura, mcp).",
"estado": 403,
"documentacion": "https://scholaris-v2.jlsf2005.workers.dev/api#errores"
}
}
Código
HTTP
Qué significa
no_autenticado
401
Falta la clave, no vale o se ha revocado.
prohibido
403
La clave no tiene el alcance necesario (escribir necesita escritura).
peticion_invalida
400
Falta un campo o no es válido: el mensaje dice cuál.
no_encontrado
404
No existe o no es tuyo.
conflicto
409
Choca con el estado actual; por ejemplo, el documento aún no tiene texto.
demasiado_grande
413
Por aquí caben ficheros de hasta 95 MB; para más, el SDK sube por partes.
cuota_superada · requiere_pro
402
Se ha agotado una cuota del plan.
limite_de_ritmo
429
Demasiadas peticiones seguidas: espera los segundos de Retry-After.
proveedor_fallo
502
Ha fallado un proveedor de IA: vuelve a intentarlo.
Los límites de ritmo y las cuotas son los de tu plan, los mismos que en la aplicación.
Para reintentar sin duplicar, manda una cabecera Idempotency-Key en «subir» y «citar»: con la misma clave, durante 24 horas, se devuelve el mismo recurso.
De dónde sale cada cita
Al leer un documento, Scholaris guarda de cada pasaje un ancla: la página física y el folio impreso que se ve en el papel, el segundo de un audio o de un vídeo, la diapositiva, la sección y el párrafo de una web. Es lo que devuelve el campo ancla.
La cita y el localizador se escriben desde esa ancla, nunca desde lo que diga un modelo; el enlace abre el lector en esa misma página o en ese mismo segundo. Si un pasaje no está en tu biblioteca, la API no lo cita.