Extracción de Datos
La extracción de datos desde Parsable se realiza mediante un proceso asíncrono que involucra 4 endpoints secuenciales. Este flujo permite programar la generación del reporte, monitorear su estado, obtener una URL de descarga segura y, finalmente, consumir el archivo CSV.
1. Glosario de Parámetros y Variables
Para facilitar la integración y comprensión del flujo de extracción de datos, a continuación se detallan los identificadores, variables de entorno y tokens utilizados en esta documentación:
| Variable / Parámetro | Tipo | Origen / Ámbito | Descripción |
|---|---|---|---|
url_base_api | Configuración | Entorno (.env) | URL raíz de los servicios web de Parsable (ej. https://api.parsable.net o la variante regional correspondiente). |
token_acceso | Credencial | Autenticación | Token de tipo Bearer JWT temporal obtenido tras autenticarse con las credenciales del sistema cliente. Es obligatorio para los endpoints de estado y firma. |
team_id | Identificador | Plataforma Parsable | Código único global que identifica a la organización o equipo de Alpura dentro del tenant de Parsable. |
report_id | Identificador | Dinámico (Paso 3.1) | ID único asignado a la tarea de compilación del reporte asíncrono. Se genera al solicitar la exportación de datos de los formularios. |
signedDownloadUrl | URL | Dinámico (Paso 3.3) | Enlace seguro y firmado criptográficamente que apunta directamente al almacenamiento en la nube (CloudFront/S3). Contiene tokens de expiración y firma mutua. |
Los valores de token_acceso y las firmas dinámicas dentro de signedDownloadUrl contienen credenciales de acceso a datos sensibles de producción (calidad, ranchos, asesores). Nunca deben quedar expuestos de forma fija en repositorios públicos de código.
2. Resumen del Flujo Asíncrono
El ciclo de vida para obtener el reporte de entradas de trabajo consta de los siguientes pasos:
| Paso | Método | Endpoint / URL | Descripción |
|---|---|---|---|
| 1 | POST | /v2/csv-reports/v1/reports/{team_id}/jobs-inputs | Solicita la generación del reporte. Retorna un report_id. |
| 2 | GET | /v2/csv-reports/v1/reports/{team_id}/jobs-inputs/{report_id} | Consulta el estado del procesamiento (Polling). |
| 3 | GET | /v2/csv-reports/v1/reports/{team_id}/jobs-inputs/{report_id}/file | Obtiene la URL firmada de descarga una vez esté READY. |
| 4 | GET | {signedDownloadUrl} | Descarga el archivo físico .csv desde el servidor de almacenamiento. |
3. Diagrama
4. Explicación del Flujo de Comunicación
El ciclo de vida para la extracción y consumo del reporte de entradas de trabajo (jobs-inputs) se compone de 4 pasos secuenciales detallados a continuación:
4.1. Paso 1 (Solicitud)
El sistema cliente inicializa el flujo enviando una petición HTTP POST con los criterios de filtrado específicos al endpoint del equipo. La API de Parsable no procesa ni genera el archivo de forma síncrona debido al volumen potencial de datos; en su lugar, registra la tarea en una cola de fondo y devuelve de inmediato un código 202 Accepted junto con un token único de seguimiento llamado report_id (ej. 6a3aaf3a0d7387409fa6bafa).
- jobTypes
- Fechas (created / updated)
- Optimización de Columnas
Tipo: Arreglo de cadenas.
Segmenta por la naturaleza del trabajo. Valores válidos: ["Normal", "On-Demand", "Recurring", "Issue"].
Recomendación: Filtrar "On-Demand" si solo se desean ver ejecuciones reales de asesores y no los jobs padre del sistema.
createdDate: Rango de tiempo basado en la creación del Job utilizando formato extendido ISO 8601 (fromyto). Ej:{"from": "2026-06-01T00:00:00.000Z"}.jobLastUpdatedDate: Rango basado en la última modificación de los datos. Parámetro crítico para implementar extracciones delta o cargas incrementales hacia el Data Lake.
columns: Arreglo explícito con los identificadores técnicos de las columnas requeridas (ej.["job_id", "job_status"]). Reduce drásticamente el peso del archivo resultante.excludeEmptyInputFields: Booleano. Entrue, limpia del reporte las filas de campos de entrada que no hayan recibido respuesta por parte del usuario.
4.2. Paso 2 (Polling)
Debido a que la generación de reportes masivos se procesa de forma asíncrona, el sistema cliente inicia un bucle de consulta periódica (Polling Loop) realizando peticiones HTTP GET cada 5 a 10 segundos utilizando el report_id obtenido. El sistema debe interpretar el estado devuelto conforme a la siguiente matriz de ciclo de vida:
- Estados de Transición (Continuar Polling):
INITIAL: La solicitud de reporte ha sido registrada exitosamente en la base de datos de Parsable.SCHEDULED: La tarea se encuentra en la cola de procesamiento, esperando asignación de recursos.IN_PROGRESS: El motor de reportes está extrayendo de forma activa los inputs de los jobs y estructurando el CSV.PUBLISHING: El archivo plano.csvya fue generado y se está transmitiendo hacia el storage cloud seguro.
- Estados Finales (Terminar Polling):
READY: El procesamiento ha culminado con éxito. El archivo está totalmente disponible para pasar al Paso 3.ERROR: Ocurrió un fallo crítico e inesperado. Se debe abortar el bucle, alertar al orquestador (ej. Airflow) y revisar los filtros del Paso 1.DUPLICATE: Se detectó una solicitud idéntica en proceso. Se sugiere reutilizar el flujo original.
4.3. Paso 3 (Firma/Autorización)
Una vez que el estado del reporte cambia de forma estricta a READY, el cliente realiza una petición HTTP GET al endpoint finalizador del reporte (/file). Parsable valida internamente que el archivo exista en su infraestructura y responde con un objeto JSON que contiene un enlace directo expuesto. Este enlace cuenta con parámetros de seguridad y firmas criptográficas de acceso que son tanto temporales como seguras.
4.4. Paso 4 (Descarga)
El sistema cliente realiza la última petición HTTP GET apuntando directamente a la infraestructura de almacenamiento seguro de Parsable (signedDownloadUrl).
En este punto, se deben omitir las cabeceras tradicionales de autenticación (como Authorization: Bearer <token>), dado que la autorización de lectura de AWS S3 / CloudFront, las llaves públicas de acceso y el tiempo límite de expiración vienen delegados e inyectados directamente dentro de los query parameters de la URL generada: signedDownloadUrl&urlExpirationDateUtc.
El servidor procesa la firma de la URL y responde con un Content-Type: text/csv, entregando el flujo de datos del archivo físico para su posterior ingesta y transformación en la base de datos destino.
5. Especificación Técnica de los Endpoints
5.1 Headers Globales
Para realizar las peticiones a la API base de Parsable, es obligatorio incluir las siguientes cabeceras:
Authorization: Bearer <token_acceso>
Content-Type: application/json
6. APIs
6.1. Solicitud
El sistema cliente inicializa el flujo enviando una petición HTTP POST con los criterios de filtrado específicos al endpoint del equipo. La API de Parsable no procesa ni genera el archivo de forma síncrona debido al volumen potencial de datos; en su lugar, registra la tarea en una cola de fondo y devuelve de inmediato un código 202 Accepted junto con la entidad del reporte en estado inicial.
- 📋 Criterios de Filtrado
- 💻 Ejemplo de cURL
jobTypes: Arreglo de cadenas para segmentar por la naturaleza del trabajo. Valores válidos:["Normal", "On-Demand", "Recurring", "Issue"].createdDate: Rango de tiempo basado en la creación del Job utilizando formato extendido ISO 8601 (fromyto). Ej:{"from": "2026-06-01T06:00:00.000Z"}.templates: Diccionario de UUIDs de plantillas para restringir la extracción a formularios específicos (ej. Calidad de Leche). Si se deja vacío, extrae todos de forma global.columns: Arreglo explícito con los identificadores técnicos de las columnas requeridas para optimizar el tamaño del archivo resultante.
curl --location '<url_base_api>/v2/csv-reports/v1/reports/<team_id>/jobs-inputs' \
--header 'Authorization: Bearer <token_acceso>' \
--header 'Content-Type: application/json' \
--data '{
"jobTypes": ["Normal"],
"createdDate": {
"from": "2026-06-01T06:00:00.000Z",
"to": "2026-06-22T05:59:59.999Z"
},
"templates": {
"711177e4-b93a-485d-a838-2c52d90423e5": [],
"bf7a6a62-c225-4311-8149-58b3aaffe5b7": []
},
"businessFunctions": [],
"businessUnits": [],
"locations": [],
"jobIds": [],
"excludeEmptyInputFields": false,
"columns": []
}'
{
"id": "6a3aefc580e6bc3bc369fe1a",
"state": "INITIAL",
"createdAt": "2026-06-23T20:42:45.451623725Z",
"createdBy": "6fbedaab-cb85-4455-870a-601a2011ae6e",
"params": {
"createdDate": {
"from": "2026-06-01T06:00:00Z",
"to": "2026-06-22T05:59:59.999Z"
},
"columns": [],
"templates": {
"711177e4-b93a-485d-a838-2c52d90423e5": [],
"bf7a6a62-c225-4311-8149-58b3aaffe5b7": []
},
"businessFunctions": [],
"businessUnits": [],
"locations": [],
"jobTypes": [
"Normal"
],
"jobIds": [],
"excludeEmptyInputFields": false
}
}
El valor de la propiedad id es el identificador del reporte que se utilizará en los siguientes pasos para el monitoreo (polling).
6.2. Polling
Debido a que la generación de reportes masivos se procesa de forma asíncrona, el sistema cliente inicia un bucle de consulta periódica (Polling Loop) realizando peticiones HTTP GET cada 5 a 10 segundos utilizando el id del reporte (ej. 6a3aefc580e6bc3bc369fe1a) obtenido en el paso anterior. El sistema debe interpretar el estado devuelto conforme a las siguientes especificaciones:
- 📋 Matriz de Estados
- 💻 Ejemplo de cURL
| Tipo de Estado | Estado | Descripción |
|---|---|---|
| Transición (Continuar Polling) | INITIAL | La solicitud de reporte ha sido registrada exitosamente en la base de datos de Parsable. |
SCHEDULED | La tarea se encuentra en la cola de procesamiento, esperando asignación de recursos. | |
IN_PROGRESS | El motor de reportes está extrayendo de forma activa los inputs de los jobs y estructurando el CSV. | |
PUBLISHING | El archivo plano .csv ya fue generado y se está transmitiendo hacia el storage cloud seguro. | |
| Final (Terminar Polling) | READY | El procesamiento ha culminado con éxito. El archivo está totalmente disponible para pasar al Paso 3. |
ERROR | Ocurrió un fallo crítico e inesperado. Se debe abortar el bucle, alertar al orquestador (ej. Airflow) y revisar los filtros del Paso 1. | |
DUPLICATE | Se detectó una solicitud idéntica en proceso. Se sugiere reutilizar el flujo original. |
curl --location '<url_base_api>/v2/csv-reports/v1/reports/<team_id>/jobs-inputs/<report_id>' \
--header 'Authorization: Bearer <token_acceso>'
{
"id": "6a3aefc580e6bc3bc369fe1a",
"state": "READY",
"createdAt": "2026-06-23T20:42:45.451Z",
"createdBy": "6fbedaab-cb85-4455-870a-601a2011ae6e",
"comment": "Processed by Lambda via SQS",
"params": {
"createdDate": {
"from": "2026-06-01T06:00:00Z",
"to": "2026-06-22T05:59:59.999Z"
},
"columns": [],
"templates": {
"711177e4-b93a-485d-a838-2c52d90423e5": [],
"bf7a6a62-c225-4311-8149-58b3aaffe5b7": []
},
"businessFunctions": [],
"businessUnits": [],
"locations": [],
"jobTypes": [
"Normal"
],
"jobIds": [],
"excludeEmptyInputFields": false
}
}
Una vez que la propiedad state devuelva estrictamente el valor READY, se puede terminar el ciclo de monitoreo de forma segura y avanzar hacia el Paso 3.
6.3. Firma/Autorización
Una vez que el estado del reporte cambia de forma estricta a READY, el sistema cliente solicita la generación del enlace seguro de descarga. La API de Parsable valida internamente la existencia del recurso y genera un acceso firmado criptográficamente de carácter temporal.
- 📋 Detalles del Endpoint
- 💻 Ejemplo de cURL
| Atributo | Detalle |
|---|---|
| Método HTTP | GET |
| Endpoint | <url_base_api>/v2/csv-reports/v1/reports/<team_id>/jobs-inputs/<report_id>/file |
| Propósito | Mutar el estado lógico a un recurso físico delegando la seguridad de la descarga a firmas de URL de almacenamiento seguro con tiempo de expiración definido. |
curl --location '<url_base_api>/v2/csv-reports/v1/reports/<team_id>/jobs-inputs/<report_id>/file' \
--header 'Authorization: Bearer <token_acceso>'
{
"type": "csv",
"sizeInBytes": 15823537,
"signedDownloadUrl": "[https://document-service-ro-us.parsable.net/27d1ad35-d38a-5bff-9ce1-35d145f6b611/7018fd79-e7e0-48e1-b0fa-fade46b0bb3c/jobs_inputs-report-8e84fd84-eb94-4838-bdf9-d246bfabbc81-2026-06-23_20-43-09-818-UTC.csv?versionId=z.IkDGUG8BjXtRgFZ6DR_ynk6jCbdrDU&Expires=1782249887&Signature=qJHiyeBc](https://document-service-ro-us.parsable.net/27d1ad35-d38a-5bff-9ce1-35d145f6b611/7018fd79-e7e0-48e1-b0fa-fade46b0bb3c/jobs_inputs-report-8e84fd84-eb94-4838-bdf9-d246bfabbc81-2026-06-23_20-43-09-818-UTC.csv?versionId=z.IkDGUG8BjXtRgFZ6DR_ynk6jCbdrDU&Expires=1782249887&Signature=qJHiyeBc)...",
"urlExpirationDateUtc": "2026-06-23T21:24:47.448105295"
}
La propiedad signedDownloadUrl contiene la ubicación exacta del archivo físico y expira de forma estricta en la marca de tiempo indicada por urlExpirationDateUtc.
6.4. Descarga
El paso final del flujo ejecuta el consumo físico del archivo plano .csv. La descarga se realiza directamente contra la infraestructura de almacenamiento distribuido seguro de Parsable.
- 📋 Mecanismo de Consumo
- 💻 Ejemplo de cURL
En este endpoint se deben omitir por completo los encabezados tradicionales de autenticación (como Authorization: Bearer). Intentar inyectar el token Bearer en el almacenamiento seguro resultará en un fallo técnico de firma mutua (HTTP 400 Bad Request o HTTP 403 Forbidden).
El servidor de storage lee los query parameters inyectados dentro de la propiedad signedDownloadUrl (Signature, Expires, versionId, Key-Pair-Id), valida la firma delegada y abre un canal de transmisión de datos directos (Stream) devolviendo un encabezado Content-Type: text/csv.
curl --location '[https://document-service-ro-us.parsable.net/27d1ad35-d38a-5bff-9ce1-35d145f6b611/7018fd79-e7e0-48e1-b0fa-fade46b0bb3c/jobs_inputs-report-8e84fd84-eb94-4838-bdf9-d246bfabbc81-2026-06-23_20-43-09-818-UTC.csv?versionId=z.IkDGUG8BjXtRgFZ6DR_ynk6jCbdrDU&Expires=1782249887&Signature=qJHiyeBcHHMIZc90RbRtU54jOhtN8qDrLfY0BNDjM0z4MESfKo0rGFvkr4pC7jjGA9-ByLWMOM93xhMQZdHBkd6vqZp9jGXqR0T4YXBS2t6Xi0-x4WvJEenDTu8e4P~eiPcT49W-TcYb8RaxjDYGwcT0Z9ygzNMpCSwgBiJejqVPbJfSqEzbQl~BzUQsGk8KRzLqRo~yyT~f0ItLGOHpCuqGkriVx4JPSqMMWYABMrkBAORPMdRFbxu7VFa3RtaALmiKCLI-UTAPwJTrn2GPF9HMF0vYCAatf7BzgMC4QmbftVM29q-ShE5oOvOi97Eug1I0une9SmxdnFsNoIIj4w__&Key-Pair-Id=K6IZ3YL4GCIIR](https://document-service-ro-us.parsable.net/27d1ad35-d38a-5bff-9ce1-35d145f6b611/7018fd79-e7e0-48e1-b0fa-fade46b0bb3c/jobs_inputs-report-8e84fd84-eb94-4838-bdf9-d246bfabbc81-2026-06-23_20-43-09-818-UTC.csv?versionId=z.IkDGUG8BjXtRgFZ6DR_ynk6jCbdrDU&Expires=1782249887&Signature=qJHiyeBcHHMIZc90RbRtU54jOhtN8qDrLfY0BNDjM0z4MESfKo0rGFvkr4pC7jjGA9-ByLWMOM93xhMQZdHBkd6vqZp9jGXqR0T4YXBS2t6Xi0-x4WvJEenDTu8e4P~eiPcT49W-TcYb8RaxjDYGwcT0Z9ygzNMpCSwgBiJejqVPbJfSqEzbQl~BzUQsGk8KRzLqRo~yyT~f0ItLGOHpCuqGkriVx4JPSqMMWYABMrkBAORPMdRFbxu7VFa3RtaALmiKCLI-UTAPwJTrn2GPF9HMF0vYCAatf7BzgMC4QmbftVM29q-ShE5oOvOi97Eug1I0une9SmxdnFsNoIIj4w__&Key-Pair-Id=K6IZ3YL4GCIIR)' \
--output 'alp_facturacion_plazos_credito.csv'
"job_id","job_guid","record_type","job_title","job_created_date_utc","job_status","job_template_title","step_title","field_label","field_type","field_value","attr_locations","attr_bus_func"
"Job-1009","c60f0c6a-9506-4729-8d45-6e279cc52914","Job","SA-01-01 Salud del hato...","2026-06-15 17:15:04","Completed","SA-02-01 SALUD DEL HATO","Datos generales","Nombre de Asesor Técnico","list","JORGE ALBERTO CALDERÓN SÁNCHEZ","Dirección de Calidad","Calidad Torreón"
"Job-1009","c60f0c6a-9506-4729-8d45-6e279cc52914","Job","SA-01-01 Salud del hato...","2026-06-15 17:15:04","Completed","SA-02-01 SALUD DEL HATO","Datos generales","REGION","list","TORREON","Dirección de Calidad","Calidad Torreón"
"Job-1009","c60f0c6a-9506-4729-8d45-6e279cc52914","Job","SA-01-01 Salud del hato...","2026-06-15 17:15:04","Completed","SA-02-01 SALUD DEL HATO","Campañas Zoosanitarias","¿Participa en campaña oficial de Brucelosis?","yesno","yes","Dirección de Calidad","Calidad Torreón"
Nota: Cada fila del CSV representa un campo evaluado (field_guid) individualmente dentro de los pasos del formulario técnico.