ServiReports Connect API

Integra tus reportes de campo con tu ERP

Una API REST para que tu sistema consuma los reportes de tu organización: búscalos, descárgalos en PDF, etiquétalos con tu referencia y recibe avisos automáticos cuando se crean. Server-to-server, en cualquier lenguaje.

/api/v1
REST sobre HTTPS · JSON
Webhooks
report.created en tiempo real
Tu reporte
en tu sistema, ligado a tu orden
tu-servidor · terminal
# Trae el reporte de una orden y baja su PDF
curl -H "Authorization: Bearer $SR_API_KEY" \
  "https://api.servireports.com/api/v1/reports?query=OT-2026-00184"

# Respuesta
{ "reports": [{ "folio": "OYS2609-001",
            "referenceId": "OT-2026-00184" }],
  "count": 1 }
Webhooks en tiempo real5 lenguajes de ejemploTu reporte en tu sistema

Automatiza: el reporte foliado por tu técnico aparece solo en tu ERP.

Concilia sin doble captura: cada reporte ligado a tu orden por Referencia ID.

Menos llamadas, más automatización: webhooks + cache de tu lado.

Documentación para desarrolladores

Todo lo que necesitas para integrar, con ejemplos en 5 lenguajes.

Límites del servicio

Tomados de la configuración actual del servicio, no escritos a mano.

Descargas de PDF
cada 24 h

Por organización. Solo las descargas consumen cuota.

Consultas
Sin límite

Búsqueda, uso, Referencia ID e índice no consumen cuota.

01

Introducción

Conecta los reportes de campo de tu organización con tu ERP u otros sistemas.

ServiReports Connect es una API REST sobre HTTPS que responde en JSON. Con ella tu sistema puede buscar los reportes de tu organización, descargar su PDF, etiquetarlos con tu propio identificador y recibir avisos automáticos cuando ocurren eventos.

Al ser HTTP estándar, es compatible con cualquier lenguaje — JavaScript/Node, Python, PHP, Java, C#, Go, Ruby — o simplemente curl. No hay que instalar ningún SDK: usas el cliente HTTP que ya trae tu lenguaje.

Importante: la API es servidor-a-servidor (server-to-server)

Debes llamar la API desde el backend de tu sistema (tu servidor), NO desde el navegador ni desde el frontend de una página web. Dos razones:

  • Tu API_KEY es secreta. Si la pones en JavaScript de navegador, cualquiera que abra el inspector la puede robar.
  • Por seguridad, las llamadas desde un navegador de otro dominio son rechazadas (CORS / origen no permitido). Solo funcionan desde servidor, donde no hay navegador de por medio.

En corto: guarda la llave en una variable de entorno de tu servidor y haz las llamadas desde ahí. Todos los ejemplos de esta guía asumen eso.

Propósito. Automatizar tu operación: que un reporte foliado por tu técnico aparezca solo en tu ERP, ligado a tu orden de trabajo o factura, y obtener su PDF cuando lo necesites — sin que nadie entre al portal a copiar datos a mano.

Suscripción. El uso en producción requiere la suscripción de la API (una por organización). Puedes desarrollar y probar gratis en modo sandbox antes de activarla.

02

Anatomía de una llamada

De qué se compone cada petición — para que sepas exactamente qué mandar.

Toda llamada a la API se arma con cuatro piezas. Tomemos como ejemplo “buscar reportes”:

1. Método
GET

La acción HTTP: GET (leer), POST (crear), PATCH (actualizar), DELETE (borrar).

2. URL
https://api.servireports.com/api/v1/reports?query=bomba&limit=20

La URL base + la ruta del recurso + parámetros opcionales después del signo ?.

3. Encabezados
Authorization: Bearer TU_API_KEY

Tu llave. En POST/PATCH agrega también Content-Type: application/json.

4. Cuerpo (body)
{ "referenceId": "OT-2026-00184" }

Solo en POST/PATCH: los datos en JSON. GET y DELETE no llevan cuerpo.

Así se ve completa, con las cuatro piezas juntas (misma llamada en 5 lenguajes):

curl -H "Authorization: Bearer TU_API_KEY" \
  "https://api.servireports.com/api/v1/reports?query=bomba&limit=20"

La API siempre responde con un código HTTP (200 = todo bien) y un cuerpo JSON. Mira la pestaña Respuesta arriba para ver exactamente qué te devuelve. En la sección Respuestas y diagnóstico explicamos cada código.

03

Modo Sandbox

Prueba la integración gratis, sin suscripción.

Las llaves que empiezan con dev_ son de sandbox. Funcionan gratis sobre los datos reales de tu organización, para que desarrolles y valides tu integración sin costo.

En sandbox, la descarga de PDF devuelve un PDF de prueba (con la leyenda “Prueba de descarga PDF”) y no consume cuota. Todo lo demás — búsqueda, referencia, registro de webhooks — se comporta igual que en producción, así tu código no cambia al pasar a vivo: solo cambias la llave.

04

Modo Producción

Tus reportes reales y sus PDF definitivos.

Las llaves que empiezan con sr_live_ son de producción: entregan tus reportes reales y el PDF definitivo de cada uno. Requieren la suscripción de la API activa.

Si llamas con una llave de producción sin suscripción activa, la API responde 403 API_SUBSCRIPTION_REQUIRED. Actívala o renuévala desde la gestión de la suscripción.

05

API Keys

Cómo generarlas, usarlas y revocarlas.

Generar. En la pestaña Claves generas una llave sandbox o de producción. La llave completa se muestra una sola vez al crearla — guárdala en un lugar seguro (variable de entorno o gestor de secretos). Solo guardamos una huella; no podemos volver a mostrártela.

Usar. Envíala en el encabezado Authorization: Bearer TU_API_KEY en cada solicitud. Tu organización se identifica a partir de la propia llave — nunca la envías tú.

curl -H "Authorization: Bearer TU_API_KEY" "https://api.servireports.com/api/v1/usage"

¿Puedo tener varias? Sí. Crea las que necesites (por sistema, por ambiente). Todas comparten la misma cuota diaria de descargas de tu organización.

Eliminar. Revoca una llave desde la pestaña Claves; deja de funcionar de inmediato. Si sospechas que se filtró, revócala y genera otra.

06

Uso justo (rate-limit)

Sin cobro por uso. Solo las descargas de PDF tienen cuota.

  • Las consultas son gratis y sin límite: buscar reportes, consultar uso, actualizar la referencia, gestionar webhooks.
  • Solo las descargas de PDF consumen una cuota diaria por organización, compartida entre todas tus llaves.
  • Al agotar la cuota del día, la descarga responde 429 API_RATE_LIMITED con el encabezado Retry-After (segundos hasta el reinicio). Respeta ese valor y reintenta.
  • Consulta cuánto te queda cuando quieras con GET /usage.
¿Se puede saltar el uso justo? No con múltiples llaves — la cuota es por organización. Si tu operación legítima necesita más, contacta a soporte para ajustar tu límite.
07

Respuestas y diagnóstico

Cómo saber si tu llamada salió bien — o qué pasó si no.

Cada respuesta trae un código HTTP. Con él diagnosticas todo: si empieza en 2xx salió bien; 4xx es un problema de tu petición; 5xx es un error temporal del servidor.

CódigoSignificaCuándo
200 OKTodo correcto.Búsqueda, PDF, referencia, usage, listar/eliminar webhooks.
201 CreatedRecurso creado.Al registrar un webhook (POST /webhooks).
4xxError de tu petición.Llave inválida, sin suscripción, cuota agotada, folio inexistente… (ver Códigos de error).
5xxError del servidor.Temporal. Reintenta con backoff; si persiste, contacta a soporte.
  • Los éxitos (2xx) devuelven el JSON del recurso (revisa la pestaña Respuesta en cada función).
  • Los errores devuelven { "code": "...", "error": "..." }. Programa contra code (estable), no contra el texto.
  • Toda respuesta trae el encabezado X-ServiReports-Mode: sandbox | production, para confirmar contra qué entorno hablas.
08

Actividad

Evalúa el uso y gestiona tus recursos.

En la pestaña Actividad ves el uso por cada API key (última vez utilizada), para saber qué llaves están activas, detectar integraciones que dejaron de usarse y decidir cuáles conservar o revocar.

Para el estado de la cuota del día (límite, usado, restante) usa GET /usage desde tu integración — así tu propio sistema se monitorea y previene antes de una carga grande.

09

Reportes

Qué son y cómo se entregan.

Un reporte es el documento de campo que tu técnico generó y folió desde la app: datos generales, secciones de contenido, fotos y firmas. Una vez foliado es definitivo (no cambia). Cada reporte tiene un folio único (ej. OYS2609-001) — es su identificador.

  • Metadata (JSON) al buscarlo: folio, título, cliente, empresa, departamento, tipo de usuario, quién lo creó, fechas y tu referencia.
  • Documento en PDF cuando lo descargas: el reporte completo, listo para archivar o imprimir. Para verlo, cualquier visor de PDF estándar.

La API no entrega las fotos/firmas sueltas; entrega el PDF final, que ya las incluye.

10

Índice

El catálogo de reportes de tu organización.

El índice es la lista de todos los reportes foliados de tu organización con su metadata. Es lo que consultas con GET /reports, con filtros y paginación.

Se entrega como JSON paginado: cada respuesta trae un arreglo reports, un count y un nextCursor. La primera vez (para llenar tu ERP con el histórico) recorres todo el índice pidiendo páginas con ?cursor=<nextCursor> hasta que nextCursor venga vacío — o, más simple, pides ?limit=-1 y te devolvemos todo de una vez. Después ya no re-lees todo: te mantienes al día con el webhook report.created.

Volcado completo (backfill inicial), en 5 lenguajes:

Flujo de la paginación (bucle con cursor)
Tu servidor
GET /reports?limit=100
Respuesta
{ reports, nextCursor }
Guardas página
¿nextCursor?
sí → repite / no → fin
Tu servidor ServiReports
# El volcado completo se hace en bucle (pagina por pagina).
# Se implementa en tu lenguaje; el patron es: pedir 100, guardar,
# tomar nextCursor, repetir hasta que venga vacio. Ver otras pestanas.
11

Funciones

Cada operación de la API, con ejemplos en 5 lenguajes y su respuesta.

GET/catalog

Catálogo de departamentos, tipos de usuario y prefijos

Qué hace: devuelve el catálogo de departamentos, tipos de usuario y prefijos (el prefijo del folio, definido por cada plantilla) de tu organización. Cada elemento trae su ID, su nombre, a qué departamento pertenece cada tipo, y si está activo o fue eliminado.

¿Para qué lo necesitas? Los reportes traen deptId y userTypeId (IDs, no nombres) y su folio empieza con un prefijo. Con este catálogo tu ERP resuelve cada ID a su nombre, mapea el prefijo a su plantilla/tipo de reporte, y para filtrar en GET /reports por departamento o tipo usas el ID que sale de aquí.
  • Activos: los que existen hoy en tu organización (status: "active").
  • Eliminados: los que ya se borraron pero que aún aparecen en reportes viejos (status: "deleted") — así puedes seguir resolviendo esos IDs históricos.
  • Cada tipo de usuario trae su deptId + deptName (el departamento al que pertenece).
  • Cada prefijo trae folioPrefix, name (nombre de la plantilla), reportType y su templateId.
  • Agrega ?includeDeleted=false si solo quieres los activos (respuesta más rápida).
Flujo de la consulta
Tu servidor
GET /catalog
ServiReports
lee deptos + tipos
Respuesta
{ departments, userTypes }
Tu servidor
mapea IDs → nombres
Tu servidor ServiReports
curl -H "Authorization: Bearer TU_API_KEY" \
  "https://api.servireports.com/api/v1/catalog"

Uso eficiente: cachea el catálogo de tu lado y refréscalo de vez en cuando (cambia poco). Úsalo para poblar los filtros por departamento/tipo de tu ERP con los IDs correctos.

GET/reports/{folio}/pdf

Descargar PDF

Reemplaza {folio} por el folio del reporte (ej. /reports/OYS2609-001/pdf). No devuelve el archivo directo, sino un JSON con una URL de descarga temporal (válida 30 min); descargas el PDF desde ese downloadUrl.

Flujo de la descarga (2 pasos)
Tu servidor
GET /{folio}/pdf
ServiReports
genera el PDF
Respuesta
{ downloadUrl }
Tu servidor
baja el downloadUrl
reporte.pdf
lo guardas
Tu servidor ServiReports
# 1) pide la URL de descarga
curl -H "Authorization: Bearer TU_API_KEY" \
  "https://api.servireports.com/api/v1/reports/OYS2609-001/pdf"

# 2) descarga el PDF desde el downloadUrl que te devolvio
curl -o reporte.pdf "URL_DEVUELTA"

Uso eficiente: solo esto consume cuota. Si vas a mostrar el mismo reporte varias veces, guárdalo de tu lado y reutilízalo. El campo downloads.remaining de la respuesta te dice cuánta cuota te queda.

PATCH/reports/{folio}

Actualizar la Referencia ID

Qué hace: le escribe (o cambia) a un reporte tu Referencia ID — tu identificador externo. En la URL va el {folio} (qué reporte quieres actualizar) y en el cuerpo va el valor nuevo: { "referenceId": "OT-2026-00184" }. Es decir: “a este reporte, ponle esta referencia”.

¿Qué es la Referencia ID y por qué te conviene? (léelo, vale oro para tu ERP)

Cada reporte ya viene clasificado por departamento y tipo de usuario — eso te dice de dónde salió y quién lo hizo. La Referencia ID es un dato extra tuyo para clasificarlo aún mejor, ligándolo a algo de tu mundo: el número de tu orden de trabajo, el folio de tu ERP, un proyecto o una factura.

Con eso, un reporte de campo deja de ser un documento suelto y se convierte en parte de tu flujo: puedes decir “dame el reporte de la orden OT-2026-00184” y encontrarlo al instante (GET /reports?query=OT-2026-00184). Ese puente entre el reporte del técnico y tu proceso de negocio es exactamente lo que hace que Connect API valga la pena para un ERP: automatizas la clasificación y la conciliación sin que nadie copie folios a mano.

Es texto libre (hasta 120 caracteres). No cambia ni se imprime en el PDF; es solo para clasificar e integrar.

¿De dónde sale y cómo se actualiza?

  • Al crear el reporte: el técnico la captura en la app al foliar (si la plantilla la pide). Ese es el camino normal.
  • Desde el Portal ServiReports: un admin la puede editar en el detalle del reporte.
  • Por la API (esta función): tu ERP la escribe o corrige automáticamente — ideal si necesitas re-clasificar reportes en lote o asignar la referencia desde tu sistema sin intervención humana.
Flujo de la actualización
Tu servidor
PATCH /{folio}
body
{ referenceId }
ServiReports
escribe en el índice
Respuesta
{ ok, referenceId }
Tu servidor ServiReports
curl -X PATCH \
  -H "Authorization: Bearer TU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"referenceId":"OT-2026-00184"}' \
  "https://api.servireports.com/api/v1/reports/OYS2609-001"

Para quitar la referencia, envía { "referenceId": "" } o null.

GET/usage

Consultar uso

Te dice el modo (sandbox/producción), si tu suscripción está activa y cuánta cuota de descargas te queda hoy. Úsalo para prevenir antes de una carga grande y reaccionar a lowRemaining.

Flujo de la consulta
Tu servidor
GET /usage
ServiReports
lee tu cuota
Respuesta
{ downloads: {...} }
Tu servidor
¿sigo o espero?
Tu servidor ServiReports
curl -H "Authorization: Bearer TU_API_KEY" "https://api.servireports.com/api/v1/usage"
12

Webhooks

Recibe avisos automáticos en tu servidor, en vez de consultar en bucle.

Un webhook es al revés de una llamada normal: en vez de que tú preguntes, nosotros avisamos a tu servidor cuando pasa algo. Tú registras una URL https tuya y te mandamos un POST firmado cada vez que ocurre el evento.

Paso 1 — registrar tu URL y a qué eventos suscribirte:

Flujo del registro (una sola vez)
Tu servidor
POST /webhooks
body
{ url, events }
ServiReports
registra + genera secret
Respuesta
{ webhookId, secret }
Tu servidor ServiReports
curl -X POST \
  -H "Authorization: Bearer TU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://tu-sistema.com/sr-hook","events":["report.created"]}' \
  "https://api.servireports.com/api/v1/webhooks"

Guarda el secret que te devuelve: lo necesitas para verificar que el aviso realmente vino de nosotros. Cada envío llega a tu URL con estos encabezados:

X-ServiReports-Event: report.created
X-ServiReports-Delivery: <uuid> (id único por envío)
X-ServiReports-Signature: sha256=<hmac>

Paso 2 — verifica la firma antes de confiar en el aviso. Calculas el HMAC-SHA256 del cuerpo crudo (sin parsear) con tu secret y lo comparas con X-ServiReports-Signature:

# La verificacion de firma se hace en TU servidor (no con curl).
# Formula: sha256=HMAC_SHA256(cuerpo_crudo, tu_secret)
# Compara ese valor con el header X-ServiReports-Signature.
# Ver ejemplos en Node / Python / PHP / Java en las otras pestanas.
POSTreport.created

Evento: report.created

Se dispara cuando un técnico folía (crea) un reporte. Es el evento estrella para automatizar: el reporte llega solo a tu sistema, con su referenceId incluido, listo para ligarlo a tu orden. Abajo, un receptor completo (verifica firma + procesa) en 5 lenguajes, y en la pestaña Respuesta exactamente lo que te enviamos:

Flujo del webhook (nosotros te avisamos a ti)
Técnico folía
en la app
ServiReports
POST firmado
Tu /sr-hook
verifica firma
Tu ERP
guarda por referenceId
Tu servidor ServiReports
# Un receptor de webhook es un endpoint HTTP en TU servidor.
# No se implementa con curl. Elige tu lenguaje en las otras pestanas:
# el patron es SIEMPRE: (1) leer cuerpo crudo, (2) verificar firma,
# (3) responder 2xx rapido, (4) procesar de forma idempotente.

Responde 2xx para confirmar. Si tu endpoint falla, reintentamos; tras varios fallos seguidos el webhook se pausa solo (lo reactivas volviéndolo a registrar). Usa X-ServiReports-Delivery para no procesar dos veces el mismo aviso (idempotencia).

POSTusage.threshold

Evento: usage.threshold

Se dispara cuando tu cuota diaria de descargas baja de 10%, para que tu sistema se prepare antes de quedarse sin descargas. El cuerpo trae { limit, used, remaining, window, resetsInSec }. Se verifica con la misma firma HMAC de arriba.

Flujo del aviso
Tus descargas
bajan de 10%
ServiReports
POST usage.threshold
Tu servidor
verifica firma
Te preparas
espacias descargas
Tu servidor ServiReports
13

Códigos de error

Todos los errores, qué significan y qué hacer.

Los errores llegan con el código HTTP + un cuerpo { code, error }. Programa tu integración contra code (estable), no contra el texto (que puede cambiar).

HTTPcodeQué significa / qué hacer
401API_KEY_INVALIDLa llave falta, está mal formada o fue revocada. Revisa el header Authorization: Bearer.
403API_SUBSCRIPTION_REQUIREDLlave de producción sin suscripción activa. Activa o renueva la suscripción.
429API_RATE_LIMITEDCuota diaria de descargas agotada. Espera el Retry-After (segundos) y reintenta.
404REPORT_NOT_FOUNDEl folio no existe en tu organización. Verifica el folio.
400VALIDATION_BAD_JSONEl cuerpo no es JSON válido (en PATCH o POST). Corrige el body.
400VALIDATION_INVALID_URLLa url del webhook no es https o excede el largo permitido.
400VALIDATION_INVALID_EVENTEvento de webhook no soportado. Usa report.created o usage.threshold.
409WEBHOOK_LIMIT_REACHEDAlcanzaste el máximo de webhooks por organización (10). Elimina alguno.
404WEBHOOK_NOT_FOUNDEl webhookId no existe o no es de tu organización.
500INTERNAL_ERRORError temporal del servidor. Reintenta con backoff; si persiste, contacta a soporte.
14

Eficiencia de uso

Ideas para que aproveches la API al máximo en tu servidor — menos llamadas, menos cuota, más automatización.

Esta sección no son reglas, son ideas de implementación: cómo montar la API del lado de tu servidor para que rinda al máximo. Combínalas todas y tu integración prácticamente se auto-mantiene.

Idea 1 · Recibe con webhooks, no consultes en bucle

En vez de preguntar cada rato “¿hay reportes nuevos?”, deja que nosotros te avisemos. Registras el webhook report.created UNA vez y cada reporte nuevo llega solo a tu servidor. Cero polling, cero cuota (los webhooks no cuestan).

Técnico folía
ServiReports
POST report.created
Tu servidor
lo recibe al instante
Tu servidor ServiReports

Idea 2 · Mantén tu propio índice (espejo del nuestro)

Guarda en tu base de datos una copia de cada reporte que llega (por webhook) o del volcado inicial (con cursor). Así tienes tu propio índice, siempre actualizado, y no dependes de llamarnos para listar o filtrar.

Volcado inicial
GET /reports (cursor)
Tu índice local
lo llenas
webhooks
lo mantienen al día
Tu servidor ServiReports
# El volcado completo se hace en bucle (pagina por pagina).
# Se implementa en tu lenguaje; el patron es: pedir 100, guardar,
# tomar nextCursor, repetir hasta que venga vacio. Ver otras pestanas.

Idea 3 · Guarda los PDF en tu servidor (ahorra cuota)

La descarga de PDF es lo único que consume cuota. Cuando bajes un PDF, guárdalo en tu almacenamiento. Como un reporte foliado nunca cambia, ese PDF te sirve para siempre — no vuelvas a pedirlo.

¿Tengo el PDF?
reviso mi storage
lo devuelvo (0 cuota)
No
GET /{folio}/pdf
Lo guardo
y lo devuelvo
Tu servidor ServiReports

Idea 4 · Consulta primero tu servidor (local-first)

Si ya implementaste tu índice local (idea 2) y tu cache de PDF (idea 3), haz que tu app consulte primero tu servidor y solo caiga a la API cuando falte algo. Con el tiempo, casi todo lo resuelves sin llamarnos: máxima velocidad, mínima cuota.

Tu app pide algo
¿Está local?
Sí → responde
0 llamadas
No → API
y cachea
Tu servidor ServiReports
# Patron conceptual (se implementa en tu servidor, no con curl):
# 1. Busca el reporte en TU base local.
# 2. Si esta -> lo devuelves (0 llamadas, 0 cuota).
# 3. Si NO esta -> lo pides a la API, lo guardas en tu base, y lo devuelves.
# Con el tiempo casi todo lo resuelves localmente.

Idea 5 · El flujo completo (todo junto)

Uniendo las ideas anteriores: el webhook llena tu índice, ligas cada reporte por referenceId a tu orden, y el PDF se baja una sola vez bajo demanda y queda cacheado.

webhook
report.created
Guardas en ERP
por referenceId
Usuario abre orden
PDF (1 vez)
cacheado
Tu servidor ServiReports
# Flujo recomendado (pseudo-pasos, cada paso en tu lenguaje):
# 1. Registras UNA vez el webhook report.created.
# 2. Cada reporte nuevo llega solo a tu /sr-hook -> lo guardas en tu ERP.
# 3. Cuando un usuario abre la orden, bajas el PDF UNA vez y lo archivas.
# Asi no consultas en bucle y solo gastas cuota cuando de verdad ves el PDF.

Recordatorios rápidos:

  • Respeta Retry-After en un 429 (espera creciente / backoff exponencial).
  • Revisa /usage antes de una carga grande y actúa ante el webhook usage.threshold.
  • Verifica siempre la firma del webhook y procesa idempotente con X-ServiReports-Delivery.
Resultado: tu ERP se mantiene sincronizado en tiempo real, con la clasificación por referenceId lista, y solo gastas cuota cuando alguien realmente necesita ver un PDF que aún no tienes. Mínimas llamadas, máxima automatización.