Saltar al contenido principal

Data Contracts API (ejemplos canónicos)

OpenAPI en openapi.yaml es la fuente de contrato. Este documento agrega ejemplos ejecutables para QA, FE y BE.

1. Formato canónico de error

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Datos de entrada invalidos",
"details": [
{
"field": "email",
"reason": "invalid_format"
}
],
"trace_id": "d4b6b2a0-ae09-4f12-8f33-13d5ef35f5dc",
"retryable": false
}
}

2. Endpoints críticos y ejemplos

2.1 POST /api/v1/auth/login

Request:

{
"email": "user@example.com",
"password": "Secret123!"
}

200 OK:

{
"user": {
"id": "a505f0ea-c5bf-4f6e-a5f4-277ecfa2a68d",
"email": "user@example.com",
"roles": ["PATIENT"],
"status": "ACTIVE"
}
}

401 UNAUTHORIZED (code=UNAUTHORIZED) y 429 RATE_LIMITED (code=RATE_LIMITED) deben existir siempre.

2.2 POST /api/v1/auth/register

Headers requeridos:

  • Idempotency-Key: <uuid>

Request:

{
"email": "new.user@example.com",
"password": "Secret123!",
"role": "PATIENT"
}

201 CREATED:

{
"status": "success",
"user_id": "6f5d1944-4329-4fe9-84c6-9421769e4d1f",
"account_status": "PENDING_VERIFICATION",
"verification_required": true
}

Errores mínimos: 409 CONFLICT, 422 VALIDATION_ERROR, 429 RATE_LIMITED.

200 OK en POST /api/v1/auth/token/verify debe devolver sesión inicial:

{
"status": "success",
"account_status": "ACTIVE",
"user": {
"id": "6f5d1944-4329-4fe9-84c6-9421769e4d1f",
"email": "new.user@example.com",
"roles": ["PATIENT"],
"status": "ACTIVE"
}
}

Ademas, la respuesta debe incluir cabecera Set-Cookie para cookies HttpOnly de sesion (accessToken, refreshToken); Secure y SameSite dependen del entorno.

2.3 GET /api/v1/search/doctors

Query ejemplo:

  • country_code=GT&specialty_id=cardiology&page=1&page_size=20

200 OK:

{
"data": {
"items": [
{
"public_id": "57009d6f-aa06-4e53-87f8-e99527b1e756",
"display_name": "Dr. Juan Perez",
"specialty": "Cardiologia",
"distance_km": 2.3
}
],
"pagination": {
"page": 1,
"page_size": 20,
"total": 1
}
},
"trace_id": "7b49f9f2-134b-43e0-bfc6-b9883c375545"
}

Errores mínimos: 400 BAD_REQUEST, 500 INTERNAL_ERROR.

2.4 POST /api/v1/appointments

Headers requeridos:

  • Authorization: Bearer <token>
  • Idempotency-Key: <uuid>

Request:

{
"doctor_id": "e338db03-f9f9-4498-8ac0-a89e188e2c2d",
"entity_id": "753ab431-b68a-4b83-9e72-507dc4a14d42",
"slot_start": "2026-02-15T14:00:00Z",
"reason": "Consulta general"
}

201 CREATED:

{
"data": {
"appointment_id": "bb741e35-8f5f-451a-a5f5-776f8d7f2d8d",
"status": "CONFIRMED"
},
"trace_id": "134cb4c1-dcf8-4802-90da-7ba9a06d64ee"
}

Errores mínimos: 401, 403, 409, 422, 500.

2.5 POST /api/v1/payments/webhook/recurrente

Request:

{
"transaction_id": "RC-12345",
"status": "APPROVED",
"amount": 150.0,
"currency": "GTQ",
"signature": "sha256-hmac"
}

200 OK:

{
"data": {
"processed": true
},
"trace_id": "22517522-b0ff-48c8-b109-a04be4b83c14"
}

Errores mínimos: 400 BAD_REQUEST, 401 UNAUTHORIZED_SIGNATURE, 409 CONFLICT (duplicado), 500 INTERNAL_ERROR.

3. Checklist de completitud por endpoint crítico

  • Request example válido.
  • Response 2xx example válido.
  • Responses de error mínimo (4xx y 5xx) con code canónico.
  • trace_id presente en todas las respuestas.
  • Reglas de idempotencia explícitas cuando aplique.