Download OpenAPI specification:
API pública del módulo de tickets.
Un ticket representa una solicitud de servicio/asistencia. Los campos
adicionales que lleva (form_data) los define un formulario, que se
resuelve a partir del alcance (tenant, insurer, assistance_type).
Los nombres de los campos están en inglés; los textos, en español.
Dos llamadas bastan para crear un ticket.
1. Verifica la credencial y descubre tu alcance. GET /api/v1/me
devuelve, además de tu identidad, el árbol completo de tenants,
aseguradoras y tipos de servicio a los que puedes acceder:
curl https://alfa.sistemagrmx.com/api/v1/me \
-H "Authorization: Bearer $GR_API_KEY"
{
"id": "018f1a2b-3c4d-7e5f-8a9b-0c1d2e3f4a5b",
"name": "integracion-demo",
"permissions": ["tickets.add_ticket", "tickets.view_ticket"],
"tenants": [
{ "code": "grupo-gr", "title": "Grupo GR",
"insurers": [
{ "code": "seguros-atlas", "title": "Seguros Atlas",
"assistance_types": [
{ "code": "vial", "title": "Asistencia vial", "schema_version": 3 }
] } ] } ]
}
2. Crea el ticket. Usa cualquier combinación del árbol anterior:
curl -X POST https://alfa.sistemagrmx.com/api/v1/tickets \
-H "Authorization: Bearer $GR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-4471" \
-d '{
"scope": { "tenant": "grupo-gr", "insurer": "seguros-atlas",
"assistance_type": "vial" },
"location": { "state": "cdmx", "municipality": "Cuauhtémoc" },
"request": { "channel": "phone" },
"contact": { "caller_name": "Juan Pérez",
"contact_phone": "5512345678" },
"form_data": { "policy_number": "POL-998877", "incident_date": "2026-07-26",
"vehicle_make": "Volkswagen", "has_injuries": "No",
"atlas_claim_number": "ATL-100245",
"vin": "3VWFE21C04M000001" }
}'
La respuesta trae el folio: "ticket_number": "GR-2026-000137".
3. Encuéntralo después por folio, teléfono o VIN:
curl "https://alfa.sistemagrmx.com/api/v1/tickets?q=5512345678" \
-H "Authorization: Bearer $GR_API_KEY"
Para construir un formulario de cara al usuario necesitarás además
GET /api/v1/forms/resolve, que devuelve el esquema de form_data.
Esta es una API versionada para integraciones externas: una vez
publicada, ningún campo cambia de nombre, tipo ni significado. Las
incorporaciones son siempre aditivas (campos opcionales nuevos); un
cambio incompatible sale como /v2.
Ninguna ruta ni cuerpo usa UUID: los UUID cambian entre entornos. Toda
referencia a un catálogo tiene la misma forma { code, title }.
| Entidad | Forma del code |
Ejemplo |
|---|---|---|
tenant, insurer, assistance_type |
legible | grupo-gr |
| Resto de catálogos | legible | cdmx, phone |
| Ticket | folio | GR-2026-000137 |
Todos los code son cadenas legibles y estables. Léelos siempre del
catálogo correspondiente en lugar de suponer un formato: no son
numéricos y pueden cambiar entre despliegues. La única excepción es
gender, cuyo code es una sola letra (M, F, O).
insurer es un tenant con rol de aseguradora, así que su code sale
del mismo espacio de nombres que tenant.
El cuerpo del ticket está agrupado por tema, de modo que se lea solo:
| Grupo | Contenido |
|---|---|
scope |
tenant, aseguradora y tipo de servicio (obligatorio) |
location |
estado y municipio (obligatorio) |
request |
cómo entró la solicitud; channel es obligatorio |
contact |
quién llama y cómo localizarle |
policy |
póliza, razón social y datos del cliente |
handling |
estatus de asignación y descripción de la asistencia |
form_data |
respuestas del formulario del tipo de servicio |
handling es lo que se actualiza con más frecuencia:
PATCH {"handling": {"assignment_status": "assigned"}}.
Un tenant no puede asegurar su propia solicitud: scope.tenant y
scope.insurer tienen que ser distintos. Enviarlos iguales devuelve
422 invalid_scope.
form_data se valida contra un formulario que los administradores
pueden editar. El formulario no pertenece al tipo de servicio: pertenece
al alcance completo (tenant, insurer, assistance_type) — dos
aseguradoras pueden tener formularios distintos para el mismo tipo de
servicio.
Por defecto no hay que hacer nada: la API valida contra el formulario vigente. Si te importa detectar que el formulario cambió bajo tus pies, envía la versión que conoces como precondición:
If-Schema-Version: 3
Si esa versión ya no es la vigente, la respuesta es 409
schema_version_rejected con la versión actual en error.details:
vuelve a resolver el formulario, reconstruye form_data y reintenta.
Toda respuesta de ticket incluye el schema_version con el que se
validó.
El VIN (número de serie del vehículo) no es un campo de primer nivel:
viaja en form_data bajo la clave vin, que es la que consulta la
búsqueda.
Los formularios se arman con definiciones de campo reutilizables
(key, label, data_type) repartidas en capas: una global, y otras
por tipo de servicio, tenant y aseguradora.
GET /api/v1/forms/resolve es el único endpoint de formularios: pliega
las capas que impliquen los parámetros que mandes y devuelve items
(etiquetas y orden) junto con schema (JSON Schema draft-07, la
validación). Sin parámetros obtienes la capa global; con
?assistance_type=vial, global + esa capa; añadiendo tenant y/o
insurer se pliegan también las suyas.
Así puedes pintar y validar un formulario antes de conocer el alcance
completo. La contrapartida es el versionado: schema_version sólo
viene cuando envías los tres ejes, porque sólo entonces el formulario
corresponde a un alcance con el que se puede crear un ticket. Cachea
contra If-Schema-Version únicamente esas respuestas.
GET /api/v1/tickets filtra y busca. Los filtros explícitos
(ticket_number, vin, phone, assistance_type, …) se combinan con
Y lógico. q es el atajo para una caja de búsqueda única: su formato
determina automáticamente contra qué se busca.
| Se detecta como | Cuando q… |
Campos consultados |
|---|---|---|
vin |
son 17 caracteres [A-HJ-NPR-Z0-9] (sin I, O, Q) |
clave vin de form_data |
phone |
deja exactamente 10 dígitos al quitar separadores | contact_phone, driver_phone |
ticket_number |
tiene la forma GR-AAAA-NNNNNN |
ticket_number |
Cuando se usa q, la respuesta incluye matched_by. Versiones futuras
pueden reconocer formatos adicionales: si eso te afecta, usa los
filtros explícitos, que son el camino estable.
Para sincronización incremental usa updated_since: devuelve sólo
los tickets modificados después de esa marca de tiempo, en vez de
recorrer todo el historial.
Una consulta sin coincidencias no es un error: devuelve 200 con
items: [] y total: 0.
Todos los endpoints requieren una API key en el encabezado
Authorization, con el esquema Bearer:
Authorization: Bearer grk_xxxxxxxxxxxxxxxxxxxx
Una API key ausente o inválida devuelve 401 unauthorized; una válida
sin permisos suficientes devuelve 403 forbidden.
Todas las respuestas de error comparten el mismo envoltorio Error,
con un code estable para decidir por programa, un message legible y
el request_id de la petición (cítalo al reportar incidencias).
code |
HTTP |
|---|---|
bad_request |
400 |
unauthorized |
401 |
forbidden |
403 |
not_found |
404 |
combination_unavailable |
409 |
schema_version_rejected |
409 |
unsupported_media_type |
415 |
invalid_scope |
422 |
validation_failed |
422 |
form_validation_failed |
422 |
search_term_unrecognized |
422 |
rate_limited |
429 |
Cuando el fallo es campo por campo, error.details[] lo desglosa con su
propio code estable: required, max_length, min_length,
pattern, invalid_option, unknown_field, outdated.
Las peticiones se limitan por integración, no por dirección IP: todas
las API keys de una misma integración comparten el mismo límite, de modo
que emitir claves nuevas no amplía la cuota. Cada respuesta incluye
X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset; al
superar el límite se devuelve 429 rate_limited con Retry-After, los
segundos que hay que esperar antes de reintentar.
POST /api/v1/tickets acepta el encabezado opcional Idempotency-Key
(cualquier cadena tuya: número de pedido, UUID, lo que uses). Repetir la
petición con la misma clave dentro de 24 h devuelve la respuesta
original en lugar de crear un ticket duplicado. Sin ese encabezado, un
reintento tras un timeout puede duplicar el ticket.
Devuelve la identidad de la API key, sus permisos efectivos y el árbol completo de alcance: los tenants a los que puede acceder, sus aseguradoras y los tipos de servicio de cada par, con la versión vigente del formulario de cada uno.
Es la única llamada necesaria antes de crear un ticket: de aquí
salen los tres code que van en scope. Cachea el resultado y
vuelve a pedirlo cuando un schema_version te resulte obsoleto.
Si una API key llega a tener un alcance muy grande, usa en su lugar
los endpoints individuales de /api/v1/catalogs.
curl https://alfa.sistemagrmx.com/api/v1/me \ -H "Authorization: Bearer $GR_API_KEY"
{- "id": "018f1a2b-3c4d-7e5f-8a9b-0c1d2e3f4a5b",
- "name": "integracion-demo",
- "permissions": [
- "tickets.add_ticket",
- "tickets.view_ticket"
], - "tenants": [
- {
- "code": "grupo-gr",
- "title": "Grupo GR",
- "insurers": [
- {
- "code": "seguros-atlas",
- "title": "Seguros Atlas",
- "assistance_types": [
- {
- "code": "vial",
- "title": "Asistencia vial",
- "schema_version": 3
}, - {
- "code": "medica",
- "title": "Asistencia en el hogar",
- "schema_version": 2
}
]
}
]
}
]
}Lista paginada de tickets, más reciente primero. Todos los filtros son opcionales y se combinan con Y lógico.
q es el atajo para una caja de búsqueda única: detecta el formato
del término y busca contra el identificador correspondiente.
| Se detecta como | Cuando q… |
Campos consultados | Coincidencia |
|---|---|---|---|
vin |
son 17 caracteres ^[A-HJ-NPR-Z0-9]{17}$ (sin I, O, Q) |
clave vin de form_data |
exacta, sin distinguir mayúsculas |
phone |
deja exactamente 10 dígitos tras quitar espacios, +, -, ( y ) |
contact_phone, driver_phone |
exacta sobre los 10 dígitos normalizados |
ticket_number |
coincide con ^GR-\d{4}-\d{6}$, sin distinguir mayúsculas |
ticket_number |
exacta |
Cuando se usa q, la respuesta incluye matched_by. Si el formato
no corresponde a ninguno, la respuesta es
422 search_term_unrecognized: usa entonces el filtro explícito.
Versiones futuras pueden reconocer formatos adicionales, así que
vin, phone y ticket_number son el camino estable.
updated_since devuelve sólo lo modificado después de esa marca de
tiempo. Es la forma correcta de mantener una copia al día sin
recorrer todo el historial en cada pasada.
No es un error: 200 con items: [] y total: 0.
| q | string [ 3 .. 64 ] characters Examples:
Término único de búsqueda: folio, teléfono o VIN. Su formato determina el campo consultado. |
| ticket_number | string^GR-\d{4}-\d{6}$ Example: ticket_number=GR-2026-000137 Filtro exacto por folio. |
| vin | string^[A-HJ-NPR-Z0-9]{17}$ Example: vin=3VWFE21C04M000001 Filtro exacto por la clave |
| phone | string Example: phone=5512345678 Filtro por teléfono, contra |
| tenant | string Example: tenant=grupo-gr
|
| insurer | string Example: insurer=seguros-atlas
|
| assistance_type | string Example: assistance_type=vial
|
| assignment_status | string Example: assignment_status=assigned
|
| created_from | string <date-time> Example: created_from=2026-07-01T00:00:00Z Sólo tickets creados en o después de esta fecha/hora. |
| created_to | string <date-time> Example: created_to=2026-07-31T23:59:59Z Sólo tickets creados en o antes de esta fecha/hora. |
| updated_since | string <date-time> Example: updated_since=2026-07-25T00:00:00Z Sólo tickets modificados después de esta fecha/hora. Úsalo para sincronización incremental. |
| limit | integer [ 1 .. 100 ] Default: 20 Cantidad máxima de registros por página. Un valor mayor que 100 se recorta a 100; no es un error. |
| offset | integer >= 0 Default: 0 Cantidad de registros a saltar antes de empezar la página. |
# Caja de búsqueda única curl "https://alfa.sistemagrmx.com/api/v1/tickets?q=5512345678" \ -H "Authorization: Bearer $GR_API_KEY" # Sincronización incremental curl "https://alfa.sistemagrmx.com/api/v1/tickets?updated_since=2026-07-25T00:00:00Z&limit=100" \ -H "Authorization: Bearer $GR_API_KEY"
{- "matched_by": "phone",
- "items": [
- {
- "ticket_number": "GR-2026-000137",
- "schema_version": 3,
- "scope": {
- "tenant": {
- "code": "grupo-gr",
- "title": "Grupo GR"
}, - "insurer": {
- "code": "seguros-atlas",
- "title": "Seguros Atlas"
}, - "assistance_type": {
- "code": "vial",
- "title": "Asistencia vial"
}
}, - "location": {
- "state": {
- "code": "cdmx",
- "title": "Ciudad de México"
}, - "municipality": "Cuauhtémoc"
}, - "request": {
- "channel": {
- "code": "phone",
- "title": "Teléfono"
}
}, - "contact": {
- "caller_name": "Juan Pérez",
- "contact_phone": "5512345678"
}, - "handling": {
- "assignment_status": {
- "code": "assigned",
- "title": "Asignado"
}
}, - "form_data": {
- "vehicle_make": "Volkswagen",
- "vin": "3VWFE21C04M000001"
}, - "created_at": "2026-07-25T14:32:10Z",
- "updated_at": "2026-07-25T15:04:51Z"
}
], - "limit": 20,
- "offset": 0,
- "total": 1
}Crea un ticket de servicio. Los tres code de scope salen de
GET /api/v1/me.
form_data lleva las respuestas del formulario del alcance. Por
defecto se valida contra el formulario vigente; no hace falta
declarar ninguna versión. Si quieres detectar que el formulario
cambió, envía If-Schema-Version con la versión que conoces y
recibirás 409 schema_version_rejected en lugar de una validación
contra un formulario que no esperabas.
Un fallo de form_data devuelve 422 form_validation_failed con el
detalle campo por campo en error.details.
Envía Idempotency-Key para que un reintento no duplique el ticket.
| Idempotency-Key | string <= 255 characters Example: pedido-4471 Clave de idempotencia: cualquier cadena tuya (número de pedido, UUID, etc.). Repetir la petición con la misma clave dentro de 24 h devuelve la respuesta original en lugar de crear un ticket duplicado. |
| If-Schema-Version | integer >= 1 Example: 3 Precondición opcional: la versión del formulario contra la que se
construyó Omitirlo valida contra el formulario vigente, que es el comportamiento por defecto. |
required | object (TicketScopeInput) Alcance del ticket, por |
required | object (TicketLocationInput) Ubicación administrativa del servicio. |
required | object (TicketRequestInput) Cómo entró la solicitud y quién la registró. |
object (TicketContactInput) Quién solicita el servicio y cómo localizarle. | |
object (TicketPolicy) Datos de póliza y del cliente. | |
object (TicketHandlingInput) Estado de atención del ticket. Es el grupo que más se actualiza. | |
object or null Respuestas del formulario del alcance. Las claves son las del
esquema que devuelve |
{- "scope": {
- "tenant": "grupo-gr",
- "insurer": "seguros-atlas",
- "assistance_type": "vial"
}, - "location": {
- "state": "cdmx",
- "municipality": "Cuauhtémoc"
}, - "request": {
- "channel": "phone"
}, - "form_data": {
- "vehicle_make": "Volkswagen",
- "incident_date": "2026-07-26"
}
}{- "ticket_number": "GR-2026-000137",
- "schema_version": 3,
- "scope": {
- "tenant": {
- "code": "grupo-gr",
- "title": "Grupo GR"
}, - "insurer": {
- "code": "seguros-atlas",
- "title": "Seguros Atlas"
}, - "assistance_type": {
- "code": "vial",
- "title": "Asistencia vial"
}
}, - "location": {
- "state": {
- "code": "cdmx",
- "title": "Ciudad de México"
}, - "municipality": "Cuauhtémoc"
}, - "request": {
- "channel": {
- "code": "phone",
- "title": "Teléfono"
}
}, - "contact": {
- "caller_name": "Juan Pérez",
- "contact_phone": "5512345678"
}, - "policy": {
- "card_number": "POL-998877"
}, - "form_data": {
- "vehicle_make": "Volkswagen",
- "vin": "3VWFE21C04M000001",
- "incident_date": "2026-07-26"
}, - "created_at": "2026-07-25T14:32:10Z",
- "updated_at": "2026-07-25T14:32:10Z"
}Devuelve un ticket por su folio. Un ticket_number inexistente
devuelve 404 not_found.
| ticket_number required | string^GR-\d{4}-\d{6}$ Example: GR-2026-000137 Folio del ticket, p. ej. |
curl https://alfa.sistemagrmx.com/api/v1/tickets/GR-2026-000137 \ -H "Authorization: Bearer $GR_API_KEY"
{- "ticket_number": "GR-2026-000137",
- "schema_version": 3,
- "scope": {
- "tenant": {
- "code": "grupo-gr",
- "title": "Grupo GR"
}, - "insurer": {
- "code": "seguros-atlas",
- "title": "Seguros Atlas"
}, - "assistance_type": {
- "code": "vial",
- "title": "Asistencia vial"
}
}, - "location": {
- "state": {
- "code": "cdmx",
- "title": "Ciudad de México"
}, - "municipality": "Cuauhtémoc"
}, - "request": {
- "channel": {
- "code": "phone",
- "title": "Teléfono"
}, - "agent_name": "María López"
}, - "contact": {
- "caller_name": "Juan Pérez",
- "contact_phone": "5512345678",
- "driver_name": "Juan Pérez"
}, - "policy": {
- "card_number": "POL-998877"
}, - "handling": {
- "assignment_status": {
- "code": "assigned",
- "title": "Asignado"
}, - "assistance": "Grúa en camino, ETA 25 min"
}, - "form_data": {
- "vehicle_make": "Volkswagen",
- "vin": "3VWFE21C04M000001",
- "atlas_claim_number": "Nissan Versa 2020",
- "incident_date": "2026-07-26"
}, - "created_at": "2026-07-25T14:32:10Z",
- "updated_at": "2026-07-25T15:04:51Z"
}Actualización parcial. Lo habitual es mover el estatus:
{ "handling": { "assignment_status": "assigned",
"assistance": "Grúa en camino, ETA 25 min" } }
Semántica: un grupo ausente deja intactos todos sus campos; una
clave ausente dentro de un grupo presente también; una clave con
valor null borra el campo (sólo en campos opcionales). Enviar
{} no cambia nada.
form_data se reemplaza completo, no se fusiona clave por clave.
Igual que al crear, puedes enviar If-Schema-Version para que la
petición falle si el formulario cambió.
| ticket_number required | string^GR-\d{4}-\d{6}$ Example: GR-2026-000137 Folio del ticket, p. ej. |
| If-Schema-Version | integer >= 1 Example: 3 Precondición opcional: la versión del formulario contra la que se
construyó Omitirlo valida contra el formulario vigente, que es el comportamiento por defecto. |
object or null Alcance del ticket, por | |
object or null Ubicación administrativa del servicio. | |
object or null Cómo entró la solicitud y quién la registró. | |
object (TicketContactInput) Quién solicita el servicio y cómo localizarle. | |
object (TicketPolicy) Datos de póliza y del cliente. | |
object (TicketHandlingInput) Estado de atención del ticket. Es el grupo que más se actualiza. | |
object or null Reemplaza el objeto completo; no se fusiona clave por clave. |
{- "handling": {
- "assignment_status": "assigned",
- "assistance": "Grúa en camino, ETA 25 min"
}
}{- "ticket_number": "GR-2026-000137",
- "schema_version": 3,
- "scope": {
- "tenant": {
- "code": "grupo-gr",
- "title": "Grupo GR"
}, - "insurer": {
- "code": "seguros-atlas",
- "title": "Seguros Atlas"
}, - "assistance_type": {
- "code": "vial",
- "title": "Asistencia vial"
}
}, - "location": {
- "state": {
- "code": "cdmx",
- "title": "Ciudad de México"
}, - "municipality": "Cuauhtémoc"
}, - "request": {
- "channel": {
- "code": "phone",
- "title": "Teléfono"
}
}, - "contact": {
- "caller_name": "Juan Pérez",
- "contact_phone": "5598765432"
}, - "handling": {
- "assignment_status": {
- "code": "assigned",
- "title": "Asignado"
}, - "assistance": "Grúa en camino, ETA 25 min"
}, - "form_data": {
- "vehicle_make": "Volkswagen",
- "vin": "3VWFE21C04M000001",
- "incident_date": "Av. Insurgentes Sur 500"
}, - "created_at": "2026-07-25T14:32:10Z",
- "updated_at": "2026-07-25T15:12:03Z"
}Entidades del alcance (tenants, aseguradoras, tipos de servicio) y catálogos simples de valores.
Índice de catálogos. Cada entrada indica qué parámetros de alcance hay que enviar para consultarlo, de modo que una sola llamada baste para saber cómo recorrer el resto.
Para el flujo normal de integración no hace falta: GET /api/v1/me ya
devuelve el alcance completo.
curl https://alfa.sistemagrmx.com/api/v1/catalogs \ -H "Authorization: Bearer $GR_API_KEY"
{- "items": [
- {
- "name": "tenants",
- "title": "Tenants",
- "scope": [ ]
}, - {
- "name": "insurers",
- "title": "Aseguradoras",
- "scope": [
- "tenant"
]
}, - {
- "name": "assistance-types",
- "title": "Tipos de servicio",
- "scope": [
- "tenant",
- "insurer"
]
}, - {
- "name": "state",
- "title": "Estados",
- "scope": [ ]
}, - {
- "name": "request_channel",
- "title": "Medios de solicitud",
- "scope": [ ]
}, - {
- "name": "request_type",
- "title": "Tipos de solicitud",
- "scope": [ ]
}, - {
- "name": "gender",
- "title": "Sexo",
- "scope": [ ]
}, - {
- "name": "assignment_status",
- "title": "Estatus de asignación",
- "scope": [ ]
}, - {
- "name": "request_mode",
- "title": "Modos de solicitud",
- "scope": [ ]
}
], - "total": 9
}Tenants sobre los que puede actuar la API key.
GET /api/v1/me ya los devuelve junto con sus aseguradoras y tipos de
servicio; este endpoint existe para keys con un alcance demasiado
grande para traerlo entero.
curl https://alfa.sistemagrmx.com/api/v1/catalogs/tenants \ -H "Authorization: Bearer $GR_API_KEY"
{- "items": [
- {
- "code": "grupo-gr",
- "title": "Grupo GR"
}, - {
- "code": "asistencias-mx",
- "title": "Asistencias MX"
}
], - "total": 2
}Aseguradoras relacionadas con el tenant indicado. Un tenant al que
la API key no tiene acceso devuelve 403 forbidden.
| tenant required | string Example: tenant=grupo-gr
|
curl "https://alfa.sistemagrmx.com/api/v1/catalogs/insurers?tenant=grupo-gr" \ -H "Authorization: Bearer $GR_API_KEY"
{- "items": [
- {
- "code": "seguros-atlas",
- "title": "Seguros Atlas"
}, - {
- "code": "patrimonial",
- "title": "Aseguradora Patrimonial"
}
], - "total": 2
}Tipos de servicio disponibles para el par (tenant, insurer),
cada uno con la versión vigente de su formulario.
Comparar ese schema_version con el que tienes en caché te dice si
necesitas volver a llamar a GET /api/v1/forms/resolve.
| tenant required | string Example: tenant=grupo-gr
|
| insurer required | string Example: insurer=seguros-atlas
|
curl "https://alfa.sistemagrmx.com/api/v1/catalogs/assistance-types?tenant=grupo-gr&insurer=seguros-atlas" \ -H "Authorization: Bearer $GR_API_KEY"
{- "items": [
- {
- "code": "vial",
- "title": "Asistencia vial",
- "schema_version": 3
}, - {
- "code": "medica",
- "title": "Asistencia en el hogar",
- "schema_version": 2
}
], - "total": 2
}Opciones de un catálogo simple, cada una con la forma
{ code, title }. El code es el valor que va en el campo
correspondiente del ticket (p. ej. el code de state se envía en
location.state).
Los catálogos con alcance (tenants, insurers,
assistance-types) tienen sus propias rutas. Los campos genéricos no
son un catálogo: viven en GET /api/v1/forms/resolve.
| catalog required | string Enum: "state" "request_channel" "request_type" "gender" "assignment_status" "request_mode" Example: state Nombre del catálogo simple a consultar. |
curl https://alfa.sistemagrmx.com/api/v1/catalogs/state \ -H "Authorization: Bearer $GR_API_KEY"
{- "items": [
- {
- "code": "cdmx",
- "title": "Ciudad de México"
}, - {
- "code": "15",
- "title": "Estado de México"
}
], - "total": 32
}Campos y esquema de form_data para un alcance, completo o parcial.
La versión (schema_version) sólo acompaña al alcance completo.
Devuelve el formulario de form_data vigente para los ejes de
alcance que envíes: etiquetas y orden en items, validación en
schema (JSON Schema draft-07).
El alcance se pliega por capas, y la global entra siempre:
| Parámetros | Capas plegadas |
|---|---|
| ninguno | global |
?assistance_type=vial |
global + vial |
?tenant=grupo-gr&assistance_type=vial |
global + vial + grupo-gr + grupo-gr·vial |
| los tres | todas, y la respuesta lleva schema_version |
Así puedes pintar y validar un formulario antes de conocer el
alcance completo: «¿qué campos lleva un servicio vial?» se responde
con ?assistance_type=vial, sin tenant ni aseguradora.
items y las propiedades de schema describen siempre el mismo
conjunto de campos. items va en orden de presentación; los
campos excluidos en el alcance no aparecen en ninguno de los dos.schema_version sólo aparece con los tres ejes. Su presencia
significa que ese formulario corresponde a un alcance con el que
se puede crear un ticket, y sólo esa respuesta sirve para
If-Schema-Version. Un alcance parcial no lleva versión porque
puede no corresponder a ningún formulario concreto.409 combination_unavailable sólo puede ocurrir
cuando envías los tres: es la comprobación de que la combinación
tenant/aseguradora/servicio existe.Para crear un ticket no hace falta llamar aquí: basta con
GET /api/v1/me.
| tenant | string Example: tenant=grupo-gr
|
| insurer | string Example: insurer=seguros-atlas
|
| assistance_type | string Example: assistance_type=vial
|
# Formulario de un tipo de servicio, sin tenant ni aseguradora curl "https://alfa.sistemagrmx.com/api/v1/forms/resolve?assistance_type=vial" \ -H "Authorization: Bearer $GR_API_KEY"
Sólo assistance_type: se pliegan la capa global y la de
vial. Sirve para pintar y validar, pero no lleva
schema_version, porque no corresponde a ningún alcance
con el que se pueda crear un ticket.
En schema se muestran las restricciones esenciales de
cada campo; la respuesta real añade además envoltorios que
aceptan o rechazan el valor vacío según required.
{- "scope": {
- "tenant": null,
- "insurer": null,
- "assistance_type": "vial"
}, - "items": [
- {
- "key": "policy_number",
- "label": "Número de póliza",
- "data_type": "text",
- "required": true,
- "position": 1
}, - {
- "key": "contact_email",
- "label": "Correo de contacto",
- "data_type": "email",
- "required": false,
- "position": 2
}, - {
- "key": "incident_date",
- "label": "Fecha del incidente",
- "data_type": "date",
- "required": true,
- "position": 10
}, - {
- "key": "vehicle_make",
- "label": "Marca del vehículo",
- "data_type": "text",
- "required": true,
- "position": 11
}, - {
- "key": "vehicle_year",
- "label": "Año del vehículo",
- "data_type": "number",
- "required": false,
- "position": 12
}, - {
- "key": "has_injuries",
- "label": "¿Hay lesionados?",
- "data_type": "radio",
- "required": true,
- "position": 13
}, - {
- "key": "vin",
- "label": "Número de serie (VIN)",
- "data_type": "text",
- "required": false,
- "position": 14
}
], - "schema": {
- "type": "object",
- "additionalProperties": false,
- "properties": {
- "policy_number": {
- "type": "string",
- "minLength": 4,
- "maxLength": 40
}, - "contact_email": {
- "type": "string",
- "pattern": "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
}, - "incident_date": {
- "type": "string",
- "format": "date",
- "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
}, - "vehicle_make": {
- "type": "string",
- "maxLength": 60
}, - "vehicle_year": {
- "type": "number",
- "minimum": 1980,
- "maximum": 2030
}, - "has_injuries": {
- "type": "string",
- "enum": [
- "Sí",
- "No"
]
}, - "vin": {
- "type": "string",
- "minLength": 17,
- "maxLength": 17,
- "pattern": "^[A-HJ-NPR-Z0-9]{17}$"
}
}, - "required": [
- "policy_number",
- "incident_date",
- "vehicle_make",
- "has_injuries"
]
}
}