Developers API
Rights Track Public API
API REST de solo lectura para integraciones externas. Cada endpoint es una solicitud GET — no existe forma de crear, actualizar o eliminar datos a través de esta API.
Generá tus llaves desde la app: Herramientas de desarrollador → API Keys (solo superadmin). El token completo se muestra una sola vez, justo después de crearla — copialo de inmediato, no puede recuperarse después (solo revocarse y reemplazarse por una nueva).
hubExplorá los endpoints
Cuatro recursos de solo lectura, cada uno acotado por rango de fechas o por un identificador específico.
rocket launchPrueba rápida (Postman / curl)
Pasos para hacer tu primera llamada autenticada, de cero a respuesta.
Andá a Herramientas de desarrollador → API Keys → Nueva API Key.
Marcá los endpoints a los que esta llave podrá acceder (Partners, Works, …) — una llave solo funciona para los endpoints marcados al crearla. Si dejás Works sin marcar, toda solicitud a /works con esa llave devuelve 403 endpoint_not_enabled, aunque la llave en sí sea válida.
Copiá el token completo desde la pantalla "API Key creada" (empieza con rt_live_) — es la única vez que se muestra.
En Postman: pestaña Authorization → tipo Bearer Token → pegá el token. Con curl, agregá el header directo: -H "Authorization: Bearer rt_live_...".
Hacé la llamada. Si obtenés 403, la llave que usás no tiene ese endpoint marcado — volvé al paso 2 y creá una nueva llave con ese endpoint habilitado (no se puede editar los endpoints de una llave existente, solo su estado activa/inactiva).
Referencia rápida de errores mientras probás
| Hiciste esto | Obtenés |
|---|---|
No enviaste header Authorization, o el token está revocado / inventado | 401 invalid_api_key |
| Token válido, pero ese endpoint no estaba marcado al crear la llave | 403 endpoint_not_enabled |
| Sin rango de fechas y sin filtro por registro específico (id/code/etc.) | 422 con un mensaje que indica cuál falta |
| Rango de fechas mayor a 1 año | 422 date range cannot exceed 1 year |
| Todo lo anterior está bien | 200 con data + meta |
lockAutenticación
Enviá la llave en el header Authorization en cada solicitud:
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/partners?created_from=2025-01-01&created_to=2025-12-31"
| Respuesta | Significado |
|---|---|
| 401 invalid_api_key | Llave ausente, incorrecta o revocada |
| 403 endpoint_not_enabled | La llave es válida pero no tiene acceso otorgado a este endpoint |
| 422 <message> | Los parámetros de la solicitud fallaron la validación (ver cada endpoint) |
Cada llave está acotada a endpoints específicos (elegidos al crearla — partners, works, works_files, distribution). Una llave válida sin acceso a partners otorgado recibe 403 en /partners, aunque la llave en sí funcione bien en otros endpoints.
speedRate limiting
Rack::Attack limita todo el namespace /api/v1/* a 60 solicitudes por minuto por API key (usa límite por IP como respaldo si la solicitud no trae llave o trae una inválida, así que forzar llaves por fuerza bruta también queda limitado). Superar el límite devuelve:
view_listPaginación
Todo endpoint de listado devuelve la misma envoltura:
{
"data": [ ... ],
"meta": {
"page": 1,
"per_page": 100,
"total_entries": 532,
"total_pages": 6,
"remaining_entries": 432
}
}
| Campo | Descripción |
|---|---|
page | Empieza en 1 |
per_page | Por defecto y con tope en el máximo de cada endpoint (ver más abajo) — pasar un valor mayor lo recorta en silencio al máximo, nunca da error |
total_pages | total_entries dividido por per_page, redondeado hacia arriba |
remaining_entries | Cuántos registros quedan después de la página actual (0 cuando estás en la última) — usá este o total_pages para saber cuándo dejar de paginar |
Lista partners (usuarios con user_type: partners — es decir, afiliados/socios). Nunca devuelve personal interno, aspirantes, ni ningún otro tipo de usuario, sin importar los filtros pasados.
Parámetros requeridos (condicionalmente)
No existe un modo "traeme todo", por diseño — toda solicitud debe estar acotada por un rango de fechas o por un filtro de partner específico:
- ¿Buscás un partner específico (
code,ipi_numbery/oipi_name)? El rango de fechas es opcional — el identificador ya acota la consulta. - ¿No filtrás por ninguno de esos?
created_from/created_topasan a ser obligatorios, así una solicitud nunca puede recorrer toda la base de partners.
| Parámetro | Formato | Notas |
|---|---|---|
created_from | YYYY-MM-DD | Inicio inclusivo del rango |
created_to | YYYY-MM-DD | Fin inclusivo del rango |
Si pasás un rango, no puede superar 1 año — esto aplica sea o no requerido para esa solicitud: {"error": "date range cannot exceed 1 year"}
Omitir ambas fechas sin filtro de identificador devuelve: {"error": "created_from and created_to are both required unless searching by code, ipi_number, or ipi_name"}
Pasar solo una de created_from / created_to siempre da error (created_from and created_to must be provided together), sin importar otros filtros.
Filtros opcionales
Cualquiera de estos, por sí solo, alcanza para saltarse el requisito de rango de fechas:
| Parámetro | Coincide | Ejemplo |
|---|---|---|
code | exacto | ?code=12004 |
ipi_number | exacto | ?ipi_number=I-004607478-4 |
ipi_name | parcial, sin distinguir mayúsculas | ?ipi_name=garcia |
page | — | ?page=2 |
per_page | máx. 100, por defecto 100 | ?per_page=25 |
Ejemplos de solicitud
Por rango de fechas (sin filtro de identificador → rango requerido):
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/partners?created_from=2025-01-01&created_to=2025-12-31&per_page=2"
Por IP Name, sin rango de fechas:
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/partners?ipi_name=355662053"
Por código exacto, sin rango de fechas:
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/partners?code=12004"
Ejemplo de respuesta — 200 OK
{
"data": [
{
"id": 11,
"code": 12004,
"status": "partner",
"created_at": "2025-11-14T20:47:17Z",
"affiliation_date": "2025-11-27",
"first_name": "Luciano",
"last_name": "Pizarro",
"ipi_name": "844877098",
"ipi_number": "I-004607478-4",
"category": "Socio Administrado Leyenda",
"organization_type": "natural_person",
"id_type": "Comercio",
"number_id": "24332845754",
"email": "user.test@example.com",
"phone_number": "+54734374342342",
"country": "Aruba",
"state": "Oranjestad West",
"city": "test",
"address": "test",
"social_networks": [{ "id": "176583069017800", "link": "ts", "red_social": "Mastodon" }],
"musical_profiles": [{ "id": "176583069017800", "link": "trs", "platform": "Kick" }]
}
],
"meta": { "page": 1, "per_page": 2, "total_entries": 7, "total_pages": 4, "remaining_entries": 5 }
}
Referencia de campos
| Campo | Origen | Notas |
|---|---|---|
id | — | ID interno en la base de datos |
code | partner code | Autonumerado, empieza en 12000 |
status | account status | partner, approved, suspended, deleted, etc. |
created_at | record creation | ISO 8601, UTC |
affiliation_date | resolution date | Fecha en que se resolvió/aprobó la afiliación |
first_name / last_name | — | — |
ipi_name / ipi_number | IPI registry | — |
category | quality catalog | ej. "Socio Administrado Leyenda" |
organization_type | — | natural_person / juridical_person |
id_type / master_id_type | catalog | ej. "Comercio" |
number_id | — | Número de identificación nacional / tributaria |
email / phone_number | — | — |
country / state / city / address | — | — |
social_networks / musical_profiles | — | Arrays jsonb con la forma ingresada por el partner, sin normalizar |
Lista obras documentadas de tipo local o external (el catálogo "Obras locales" — /local_documents en la app). Nunca devuelve obras de tipo file (crudas, enviadas por CWR) o avr, sin importar los filtros pasados.
Parámetros requeridos (condicionalmente)
Misma regla que /partners: acotado por rango de fechas o por un filtro de obra específico.
- ¿Buscás una obra específica (
id,iswcy/otitle)? El rango de fechas es opcional. - ¿No filtrás por ninguno de esos?
created_from/created_topasan a ser obligatorios.
Filtros opcionales
| Parámetro | Coincide | Ejemplo |
|---|---|---|
id | exacto | ?id=54175 |
iswc | exacto | ?iswc=T-123456789-0 |
title | parcial, sin distinguir mayúsculas | ?title=baile |
page | — | ?page=2 |
per_page | máx. 100, por defecto 100 | ?per_page=25 |
Ejemplos de solicitud
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/works?title=baile"
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/works?id=54175"
Ejemplo de respuesta — 200 OK
{
"data": [
{
"id": 54175,
"created_at": "2026-06-05T13:38:06Z",
"updated_at": "2026-06-05T13:54:11Z",
"title": "EL BAILE DEL BEEPER",
"iswc": "",
"isrc": null,
"alternative_titles": [],
"interpreters": [],
"rhythm": "",
"duration": null,
"language_code": "",
"category": "POP",
"code": "00000000078935",
"type_of_creation": "local",
"status": "signed",
"approval_status": "approved",
"total_writers": 1,
"total_publishers": 4,
"rights_split": [
{
"name": "PEDRO PEREZ",
"designation": "CA",
"ipi_name_number": "519611064",
"interested_party_num": "12009",
"publisher_sequence": "",
"ip_base_number": null,
"legal_entity_type": null,
"pr_society": "010",
"pr_ownership_share": 100.0,
"pr_collection_share": 100.0,
"mr_society": "084",
"mr_ownership_share": 100.0,
"mr_collection_share": 0.0,
"sr_society": "099",
"sr_ownership_share": 0.0,
"sr_collection_share": 0.0,
"territory_tis_code": "0170",
"territory_inclusion": "I",
"publishers": []
}
]
}
],
"meta": { "page": 1, "per_page": 100, "total_entries": 1, "total_pages": 1, "remaining_entries": 0 }
}
Referencia de campos
| Campo | Origen | Notas |
|---|---|---|
id | — | ID interno en la base de datos |
created_at / updated_at | — | ISO 8601, UTC |
title / iswc / isrc | — | — |
alternative_titles | alternative_names | Array jsonb |
interpreters | related interpreters | Usa el campo legado como respaldo · array de nombres a mostrar |
rhythm / duration / language_code | — | Duración formateada MM:SS |
category | distribution_category | — |
code | submitter_work_num | Usa id como respaldo si viene vacío |
type_of_creation | — | Siempre local o external en este endpoint |
status / approval_status | — | ej. signed/approved |
total_writers / total_publishers | — | — |
rights_split | cwr_line_work_details | Cada fila (autores y editores) — esta es la "clave de reparto" completa: cuotas de titularidad/recaudo por tipo de derecho (pr/mr/sr), códigos de sociedad, territorio |
Lista los ficheros AVR/CWR subidos (no las obras dentro de ellos) — una fila por carga, con sus contadores de procesamiento. Excluye ficheros internos de acuse ACK.
Parámetros requeridos (condicionalmente)
Misma regla que los demás endpoints: acotado por rango de fechas o por un filtro de fichero específico.
- ¿Buscás un fichero específico (
id)? El rango de fechas es opcional. - ¿No filtrás por
id?created_from/created_topasan a ser obligatorios.
Filtros opcionales
| Parámetro | Coincide | Ejemplo |
|---|---|---|
id | exacto | ?id=162 |
file_type | exacto, AVR o CWR | ?file_type=AVR |
page | — | ?page=2 |
per_page | máx. 100, por defecto 100 | ?per_page=25 |
Ejemplos de solicitud
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/works_files?created_from=2026-01-01&created_to=2026-06-30&file_type=CWR"
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/works_files?id=162"
Ejemplo de respuesta — 200 OK
{
"data": [
{
"id": 162,
"type": "CWR",
"uploaded_at": "2026-05-06T17:22:14Z",
"file_name": "CW2505OMS_084.V21",
"display_name": null,
"transmitter": "ORGANIZACION MUSICAL SUDAMERIC",
"total_works_ok": 812,
"total_works_np": 40,
"total_works_rj": 12,
"total_works": 944,
"status": "finalized"
}
],
"meta": { "page": 1, "per_page": 100, "total_entries": 1, "total_pages": 1, "remaining_entries": 0 }
}
Referencia de campos
| Campo | Origen | Notas |
|---|---|---|
id | file_editors.id | ID interno en la base de datos |
type | file_type | Siempre AVR o CWR en este endpoint |
uploaded_at | created_at | ISO 8601, UTC |
file_name | — | Nombre de archivo original tal como se subió |
display_name | — | Nombre mostrado en la plataforma si fue renombrado; null en caso contrario |
transmitter | — | Emisor/remitente del fichero ("emisor") |
total_works_ok | computado | Obras que hicieron match/validaron correctamente |
total_works_np | computado | Obras con territorio fuera de 0170/2136 (requieren revisión) |
total_works_rj | computado | Obras rechazadas (las cuotas no suman 100%, o el detalle AVR fue marcado inválido) |
total_works | total_files | Total de obras leídas del fichero; null hasta que termina el procesamiento |
status | — | to_approve, finalized, pending, rejected, processing, deleted |
total_works_ok / np / rj siempre se calculan en vivo a partir de las obras asociadas al fichero — los mismos números que se ven en la pantalla interna "Archivos", nunca un valor guardado desactualizado.
Lista distribuciones ("repartos"), cada una con sus segmentos y entradas de recaudo anidados dentro.
Parámetros requeridos (condicionalmente)
Misma regla que los demás endpoints: acotado por rango de fechas o por un filtro de distribución específico.
- ¿Buscás una distribución específica (
id)? El rango de fechas es opcional. - ¿No filtrás por
id?created_from/created_topasan a ser obligatorios.
Filtros opcionales
| Parámetro | Coincide | Ejemplo |
|---|---|---|
id | exacto | ?id=13 |
page | — | ?page=2 |
per_page | máx. 100, por defecto 100 | ?per_page=25 |
Ejemplos de solicitud
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/distribution?created_from=2026-01-01&created_to=2026-06-30"
curl -H "Authorization: Bearer rt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://<your-domain>/api/v1/distribution?id=13"
Ejemplo de respuesta — 200 OK
{
"data": [
{
"id": 13,
"created_at": "2026-01-15T14:02:11Z",
"updated_at": "2026-02-01T09:40:03Z",
"type": "musical",
"code": "REP-2026-013",
"payment_date": "2026-02-15",
"description": "Reparto 1er trimestre 2026",
"total_segments": 1,
"segments": [
{
"code_segment": "SEG-001",
"society": "SAPIC",
"description": "Radio nacional",
"type_period": "trimestral",
"number_period": "1",
"year": 2026,
"date_start": "2026-01-01",
"date_end": "2026-03-31",
"revenue_entries": [
{
"code_segment": "SEG-001",
"concept": "Radiodifusión",
"description": "Ingresos por radio comercial",
"distribution_type": "general",
"method": "weight_by_use",
"right_type": "pr",
"unconverted_money": "1000000",
"converted_money": "980000",
"total_amount": "980000",
"currency": "COP",
"status": "distributed"
}
]
}
]
}
],
"meta": { "page": 1, "per_page": 100, "total_entries": 1, "total_pages": 1, "remaining_entries": 0 }
}
Referencia de campos — Distribution
| Campo | Origen | Notas |
|---|---|---|
id | — | ID interno en la base de datos |
created_at / updated_at | — | ISO 8601, UTC |
type | type_file | avr → audiovisual, cwr → musical |
code | code_distribution | — |
payment_date | date_distribution | — |
description | — | — |
total_segments | — | Conteo de distribution_segments |
segments | — | Array, ver abajo |
Segmento — segments[]
| Campo | Origen | Notas |
|---|---|---|
code_segment | — | — |
society | — | Sociedad de origen ("sociedad de origen") |
description | — | — |
type_period / number_period / year | — | ej. trimestral / 1 / 2026 |
date_start / date_end | — | — |
revenue_entries | — | Array, ver abajo |
Entrada de recaudo — revenue_entries[]
| Campo | Origen | Notas |
|---|---|---|
code_segment | segmento padre | Repetido acá para conveniencia |
concept | — | — |
description | description_concept | — |
distribution_type | — | — |
method | — | ej. weight_by_use, weight_by_use_and_duration |
right_type | — | pr / mr / sr |
unconverted_money | — | Monto en la moneda original, antes de la conversión |
converted_money | — | Monto convertido a la moneda de la distribución |
total_amount | = converted_money | El modelo de "recaudo" no tiene columna de total separada — este es el total ya convertido |
currency | distribución padre | Las entradas de recaudo no llevan moneda propia |
status | distribución padre | draft/to_distribute/distributed — las entradas de recaudo no llevan estado propio |
vpn_keyGestión de llaves
Herramientas de desarrollador → API Keys — solo superadmin.
Desactivar una llave la bloquea de inmediato sin borrar su historial; eliminarla la remueve por completo (no se puede deshacer).
El listado muestra las solicitudes de los últimos 30 días por llave, para detectar integraciones sin uso o con uso excesivo de un vistazo.