curl --request GET \
--url https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}', 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.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"item_type": "activity",
"date": "2023-11-07T05:31:56Z",
"client_id": {},
"activity_id": "<string>",
"contact_id": {},
"opportunity_id": {},
"occurred_at": {},
"website_form_submission_id": {},
"activity_type_id": 123,
"activity_type_name": "<string>",
"content": "<string>",
"files_count": 123,
"contact_name": {},
"participants": "<array>",
"created_by": {},
"created_by_name": {},
"edited_at": {},
"editable": true,
"external_source": {},
"external_id": {},
"websiteFormSubmission": {},
"emailMeta": {},
"whatsappMeta": {},
"visit_detail_id": "<string>",
"visit_date": {},
"description": {},
"visit_type_name": {},
"visit_status_name": {},
"technician_name": {},
"address": {},
"task_id": "<string>",
"task_status": "<string>",
"assigned_to_name": {},
"assigned_to_id": {},
"task_due_date": {},
"task_completed_at": {},
"task_priority": {},
"task_version": 123,
"ticket_comment_id": "<string>",
"comment_visibility": "internal",
"fiscal_event_id": "<string>",
"fiscal_event_type": "<string>",
"fiscal_acceptance_status": "TACIT",
"fiscal_recipient": {},
"origin": {
"kind": "ticket",
"id": "<string>",
"label": "<string>",
"channel": "email"
},
"isThread": false,
"threadCount": 123,
"threadMessages": "<array>",
"threadType": "email"
}
]Get unified activity timeline for an opportunity
Get business activities and quote activities associated to an opportunity
curl --request GET \
--url https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId} \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}', 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.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.raul.ugps.io/api/v1/activity/by-opportunity/{opportunityId}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body[
{
"item_type": "activity",
"date": "2023-11-07T05:31:56Z",
"client_id": {},
"activity_id": "<string>",
"contact_id": {},
"opportunity_id": {},
"occurred_at": {},
"website_form_submission_id": {},
"activity_type_id": 123,
"activity_type_name": "<string>",
"content": "<string>",
"files_count": 123,
"contact_name": {},
"participants": "<array>",
"created_by": {},
"created_by_name": {},
"edited_at": {},
"editable": true,
"external_source": {},
"external_id": {},
"websiteFormSubmission": {},
"emailMeta": {},
"whatsappMeta": {},
"visit_detail_id": "<string>",
"visit_date": {},
"description": {},
"visit_type_name": {},
"visit_status_name": {},
"technician_name": {},
"address": {},
"task_id": "<string>",
"task_status": "<string>",
"assigned_to_name": {},
"assigned_to_id": {},
"task_due_date": {},
"task_completed_at": {},
"task_priority": {},
"task_version": 123,
"ticket_comment_id": "<string>",
"comment_visibility": "internal",
"fiscal_event_id": "<string>",
"fiscal_event_type": "<string>",
"fiscal_acceptance_status": "TACIT",
"fiscal_recipient": {},
"origin": {
"kind": "ticket",
"id": "<string>",
"label": "<string>",
"channel": "email"
},
"isThread": false,
"threadCount": 123,
"threadMessages": "<array>",
"threadType": "email"
}
]Authorizations
Token de sesión Better Auth para rutas de backoffice; las rutas de portal usan su token propio.
Path Parameters
Opportunity UUID
Query Parameters
Filter by activity type
Filter by contact
Filter activities from this date
"2026-01-01"
Filter activities until this date
"2026-12-31"
Include emails in timeline (default: true)
Group communications by thread (default: true)
Split WhatsApp conversations into sessions when inactivity gap matches N hours
own (por defecto, compatible con clientes anteriores): sólo el negocio; linked: suma comentarios y actividad de sus tickets vinculados (exige el módulo tickets)
own, linked Response
Timeline items (activities only) sorted by date DESC
Tipo de item: activity, visit, task, ticket_comment (comentario de un ticket vinculado al negocio) o fiscal_event (evento fiscal de la factura)
activity, visit, task, ticket_comment, fiscal_event Fecha del evento (para ordenamiento)
ID del cliente
ID de la actividad (si item_type = activity)
ID del contacto asociado
ID de la oportunidad asociada
Fecha/hora efectiva de la actividad
ID del formulario web asociado
ID del tipo de actividad
Nombre del tipo de actividad
Contenido de la actividad o tarea
Cantidad de archivos adjuntos
Nombre del contacto
Contactos participantes de la actividad
ID del usuario autor de la actividad
Nombre del creador
Última edición del contenido por su autor
El usuario actual puede editar el contenido (autor de un registro manual)
Fuente externa (outlook, whatsapp, etc.)
ID externo en el sistema de origen
Datos estructurados del formulario web asociado
Metadatos de correo asociados a la actividad
Metadatos de WhatsApp asociados a la actividad
ID de la visita (si item_type = visit)
Fecha de la visita
Descripción de la visita
Tipo de visita
Estado de la visita
Nombre del técnico
Dirección de la visita
ID de la tarea
Estado de la tarea
Nombre del responsable asignado
ID del responsable asignado
Vencimiento de la tarea
Cuándo se completó la tarea
Prioridad de la tarea: low, medium o high
Versión de la tarea para editarla
ID del comentario (si item_type = ticket_comment)
Nota interna o respuesta al cliente del ticket vinculado
internal, external ID del evento de la factura, o <documento>:intercambio / <documento>:aceptacion si sale del documento tributario (si item_type = fiscal_event)
Tipo del evento de la factura (dte_emitted, sii_accepted, payment_received, email_sent…) o dte_intercambio_sent / dte_acceptance
Aceptación comercial del receptor en dte_acceptance
TACIT, EXPRESS, CLAIMED Casilla de intercambio en dte_intercambio_sent
Registro donde ocurrió (timeline del negocio): el negocio o un ticket vinculado
Show child attributes
Show child attributes
Indica si este item es un thread agrupado de emails
Cantidad de mensajes en el thread (cuando isThread = true)
Array de actividades que forman parte del thread (cuando isThread = true)
Tipo de hilo agrupado
email, whatsapp