Convenciones REST
Base URL y versionado
https://api.ministrium.com/v1/<resource>La versión va en la URL (/v1/). Cambios breaking suben a v2. Cambios aditivos (campos nuevos, endpoints nuevos) NO son breaking — clientes deben ignorar campos desconocidos.
Recursos y verbos
GET /v1/members Lista
POST /v1/members Crear
GET /v1/members/{id} Obtener
PATCH /v1/members/{id} Actualizar parcial
PUT /v1/members/{id} Reemplazar (raro, preferir PATCH)
DELETE /v1/members/{id} Eliminar (soft delete)Sub-recursos:
GET /v1/members/{id}/attendance
GET /v1/members/{id}/donations
GET /v1/groups/{id}/membersFormato
Todo es JSON UTF-8. Cabeceras estándar:
Content-Type: application/json; charset=utf-8
Accept: application/json
Accept-Language: es-MXAccept-Language afecta mensajes de error y campos como gender_label, status_label. Default: es.
IDs
Los IDs son prefixed UUIDs legibles:
mem_8c4b2e1a3d4f5b6c7d8e9f0a1b2c3d4e Miembro
don_4f5g6h7i8j9k0l1m2n3o4p5q6r7s8t9u Donación
evt_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6 Evento
grp_z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5 Grupo celularEl prefijo le dice el tipo sin necesidad de mirar el endpoint.
Paginación con cursor
Listas devuelven cursor:
{
"data": [{...}, {...}],
"next_cursor": "eyJvZmZzZXQiOjEwMH0=",
"total": 4327
}Para la siguiente página:
GET /v1/members?cursor=eyJvZmZzZXQiOjEwMH0=&limit=100limit máximo: 250. Default: 50.
Cuando `next_cursor` es `null`, llegó al final.Filtros
GET /v1/members?campus=centro&active=true&created_after=2026-01-01Operadores en query string para campos numéricos/fecha:
?age[gte]=18&age[lt]=35
?created_at[gte]=2026-01-01T00:00:00ZOrdenamiento
?sort=created_at Ascendente
?sort=-created_at Descendente
?sort=last_name,first_name MúltipleIdempotencia
Para POST que crean recursos, envíe Idempotency-Key (UUID v4):
curl -X POST /v1/donations \
-H "Idempotency-Key: 6ba7b810-9dad-11d1-80b4-00c04fd430c8" \
...Reintentar con la misma key dentro de 24 h devuelve la respuesta original sin re-ejecutar.
Fechas y horas
ISO 8601 con timezone. Todas las respuestas en UTC; envíe en UTC también:
2026-04-26T14:30:00Z
2026-04-26T08:30:00-06:00 ← también válido, se normaliza a UTC en respuestaSólo fecha: 2026-04-26.
Monedas
Montos como enteros en la unidad mínima (centavos):
{ "amount": 5000, "currency": "MXN" } // = $50.00 MXN
{ "amount": 12500, "currency": "USD" } // = $125.00 USDEsto evita errores de redondeo en floats.
CORS
Los dominios de la propia iglesia pueden hacer requests directos desde el browser si están en el allowlist (Configuración → API → CORS). Por defecto, la API no acepta requests browser de orígenes desconocidos.
ETag y cache
GET devuelven ETag. Use If-None-Match para evitar transferir datos sin cambios:
GET /v1/members/mem_123 -H "If-None-Match: \"abc123\""
→ 304 Not Modified