curl --request POST \
--url https://api.ugps.io/api/work/records/pdf \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"batchId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"items": [
{
"id": "<string>"
}
]
}
'import requests
url = "https://api.ugps.io/api/work/records/pdf"
payload = {
"batchId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"items": [{ "id": "<string>" }]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({batchId: '3c90c3cc-0d44-4b50-8888-8dd25736052a', items: [{id: '<string>'}]})
};
fetch('https://api.ugps.io/api/work/records/pdf', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ugps.io/api/work/records/pdf",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'batchId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'items' => [
[
'id' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.ugps.io/api/work/records/pdf"
payload := strings.NewReader("{\n \"batchId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"items\": [\n {\n \"id\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ugps.io/api/work/records/pdf")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"batchId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"items\": [\n {\n \"id\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ugps.io/api/work/records/pdf")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"batchId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"items\": [\n {\n \"id\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body"<string>"{
"error": "El email es requerido"
}{
"error": "Token inválido o expirado"
}{
"error": "No tiene permisos para realizar esta acción"
}Descargar los PDFs de varios registros en un ZIP
Genera el PDF del formulario de cada registro seleccionado y responde un ZIP que se
streamea a medida que los PDFs terminan (la conexión no queda inactiva). Cada entrada
usa el mismo nombre que la descarga individual; si dos entradas coinciden se agrega la
fuente. Los registros que fallan no frenan el lote: van a errores.txt, al final del
ZIP, con fuente, id y motivo (Sin permiso, Sin formulario, Tiempo agotado,
Error de Navixy, Registro no encontrado, Error al generar el PDF).
Un usuario solo puede tener una descarga masiva en curso (409). Con un solo registro
conviene usar el endpoint individual. Como el ZIP se streamea, el resultado se consulta
después en GET /api/work/records/pdf/{batchId}/summary.
Permiso requerido: access_checkins. Los formularios de tarea exigen además
access_tasks: sin él, el ítem se reporta como Sin permiso en vez de rechazar el lote.
curl --request POST \
--url https://api.ugps.io/api/work/records/pdf \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"batchId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"items": [
{
"id": "<string>"
}
]
}
'import requests
url = "https://api.ugps.io/api/work/records/pdf"
payload = {
"batchId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"items": [{ "id": "<string>" }]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({batchId: '3c90c3cc-0d44-4b50-8888-8dd25736052a', items: [{id: '<string>'}]})
};
fetch('https://api.ugps.io/api/work/records/pdf', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ugps.io/api/work/records/pdf",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'batchId' => '3c90c3cc-0d44-4b50-8888-8dd25736052a',
'items' => [
[
'id' => '<string>'
]
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.ugps.io/api/work/records/pdf"
payload := strings.NewReader("{\n \"batchId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"items\": [\n {\n \"id\": \"<string>\"\n }\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ugps.io/api/work/records/pdf")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"batchId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"items\": [\n {\n \"id\": \"<string>\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ugps.io/api/work/records/pdf")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"batchId\": \"3c90c3cc-0d44-4b50-8888-8dd25736052a\",\n \"items\": [\n {\n \"id\": \"<string>\"\n }\n ]\n}"
response = http.request(request)
puts response.read_body"<string>"{
"error": "El email es requerido"
}{
"error": "Token inválido o expirado"
}{
"error": "No tiene permisos para realizar esta acción"
}Authorizations
Token de sesión Better Auth o API token (atk_...) en el header Authorization: Bearer <token>. Los JWT legacy ya no son válidos.
Body
Response
ZIP registros_<YYYY-MM-DD>.zip con un PDF por registro y, si hubo fallos, errores.txt.
The response is of type file.