Saltar al contenido principal

Visión General de la API

URL Base y Versionado

La API de Ozzie está versionada a través de la ruta de URL. La versión estable actual es v1.

https://api.ozzieapp.com/v1

Política de versionado:

  • El prefijo de versión (/v1, /v2, etc.) se incrementa solo para cambios incompatibles.
  • Los cambios aditivos (nuevos campos opcionales, nuevos endpoints) se hacen sin incrementar la versión.
  • Las versiones depreciadas se anuncian con al menos 90 días de antelación y devolverán un header de respuesta Deprecation durante el período de descontinuación.
  • Siempre fija una versión explícita en tu URL base. Nunca uses /latest.
Header de versión

Cuando una versión entra en su período de depreciación, todas las respuestas incluirán:

Deprecation: true
Sunset: Sat, 01 Nov 2025 00:00:00 GMT

Todos los Endpoints Disponibles

MétodoRutaDescripción
POST/v1/usersCrear un nuevo usuario
GET/v1/users/{user_id}Recuperar un usuario por ID de Ozzie o external_user_id
PATCH/v1/users/{user_id}Actualizar campos del usuario (name, email, phone, language)
POST/v1/users/{user_id}/financial-intakeEnviar un snapshot financiero mensual
GET/v1/users/{user_id}/financial-intakeObtener el intake financiero más reciente
GET/v1/users/{user_id}/financial-intake/historyObtener todos los snapshots históricos de intake
POST/v1/users/{user_id}/plan/generateGenerar un plan financiero personalizado
GET/v1/users/{user_id}/planObtener el plan activo actual
POST/v1/users/{user_id}/goalsCrear una meta financiera
GET/v1/users/{user_id}/goalsListar todas las metas
GET/v1/users/{user_id}/goals/{goal_id}Obtener una meta específica
PATCH/v1/users/{user_id}/goals/{goal_id}Actualizar una meta
DELETE/v1/users/{user_id}/goals/{goal_id}Eliminar una meta
POST/v1/users/{user_id}/transactionsEnviar transacciones (texto, imagen, PDF, hoja de cálculo)
GET/v1/users/{user_id}/transactionsListar transacciones con filtros
GET/v1/users/{user_id}/transactions/{transaction_id}Obtener una transacción específica
DELETE/v1/users/{user_id}/transactions/{transaction_id}Eliminar una transacción
GET/v1/users/{user_id}/money-movesObtener recomendaciones de gasto personalizadas
POST/v1/users/{user_id}/chatEnviar mensaje al asistente financiero de Ozzie
GET/v1/users/{user_id}/chat/historyObtener historial de mensajes del chat

Autenticación

Todas las solicitudes a la API deben incluir un header Authorization usando autenticación HTTP Bearer. El token es la codificación Base64 de tu client_id y client_secret unidos por dos puntos.

Formato del token:

base64(client_id + ":" + client_secret)

Formato del header:

Authorization: Bearer <base64_encoded_credentials>

Generando el token:

const token = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
// Usar como: `Bearer ${token}`
Mantén las credenciales en secreto

Nunca expongas tu client_secret en código del lado del cliente, aplicaciones móviles o repositorios públicos. Todas las llamadas a la API deben originarse desde tu servidor backend.


Convenciones de Solicitud y Respuesta

Headers de Solicitud

HeaderRequeridoValor
AuthorizationBearer <token>
Content-TypeSí (para POST/PATCH)application/json
AcceptNo (recomendado)application/json
Idempotency-KeyNoString UUID v4 para solicitudes POST idempotentes

Envelope de Respuesta

Todas las respuestas exitosas siguen esta estructura de envelope:

{
"object": "object_type_name",
"data": { ... }
}

Para endpoints de lista:

{
"object": "list",
"data": {
"items": [ ... ],
"has_more": true,
"next_cursor": "2025-04-30T12:00:00Z",
"total_count": 142
}
}

Códigos de Estado HTTP

EstadoSignificado
200 OKSolicitud exitosa
201 CreatedRecurso creado
204 No ContentRecurso eliminado
400 Bad RequestJSON malformado o error de validación
401 UnauthorizedCredenciales ausentes o inválidas
403 ForbiddenCredenciales válidas pero permisos insuficientes
404 Not FoundEl recurso no existe
409 ConflictEl recurso ya existe (ej.: usuario duplicado)
422 Unprocessable EntityError de lógica de negocio (ej.: intake ausente)
429 Too Many RequestsLímite de tasa excedido
500 Internal Server ErrorError en el servidor de Ozzie

Paginación

Los endpoints de lista usan paginación basada en cursor con cursores datetime ISO. Este enfoque es estable incluso cuando se insertan nuevos registros entre páginas.

Parámetros de Query

ParámetroTipoPredeterminadoDescripción
limitinteger50Número de registros por página (máx 200)
cursorstringString datetime ISO 8601 — devuelve registros más antiguos que este timestamp
fromstringFiltro: incluir registros a partir de esta fecha (YYYY-MM-DD)
tostringFiltro: incluir registros hasta esta fecha (YYYY-MM-DD)

Campos de Respuesta Paginada

CampoTipoDescripción
has_morebooleantrue si existen páginas adicionales
next_cursorstring | nullPasa esto como cursor en la próxima solicitud para obtener la siguiente página
total_countintegerNúmero total de registros coincidentes (no solo esta página)

Ejemplo de Paginación

async function fetchAllTransactions(userId) {
const allTransactions = [];
let cursor = null;

do {
const params = new URLSearchParams({ limit: '200' });
if (cursor) params.set('cursor', cursor);

const res = await fetch(
`https://api.ozzieapp.com/v1/users/${userId}/transactions?${params}`,
{ headers }
);
const json = await res.json();
allTransactions.push(...json.data.transactions);

cursor = json.data.has_more ? json.data.next_cursor : null;
} while (cursor);

return allTransactions;
}
Estabilidad del cursor

Los cursores se basan en timestamps created_at. Los registros creados después de iniciar la paginación no aparecerán en la secuencia de páginas actual — inicia una nueva solicitud para capturar nuevos registros.


Códigos de Error

Todos los errores siguen este formato:

{
"error": {
"code": "ERROR_CODE",
"message": "Explicación legible de qué salió mal."
}
}
CódigoEstado HTTPDescripción
INVALID_JSON400El cuerpo de la solicitud no es JSON válido. Verifica comas extra, comillas faltantes o problemas de codificación.
VALIDATION_ERROR400Uno o más campos fallaron en la validación. El message identificará el campo y la restricción específicos.
UNAUTHORIZED401El header Authorization está ausente, malformado o las credenciales son inválidas.
FORBIDDEN403Las credenciales son válidas pero no tienen permiso para acceder a este recurso (ej.: acceder al usuario de otro cliente).
NOT_FOUND404El recurso solicitado (usuario, transacción, meta, etc.) no existe.
CONFLICT409Ya existe un recurso con una clave única conflictiva (ej.: external_user_id ya en uso).
INTAKE_REQUIRED422Debe enviarse un snapshot de intake financiero antes de esta operación (ej.: generación de plan).
PLAN_REQUIRED422Debe generarse un plan financiero antes de esta operación (ej.: money moves).
PERSONALITY_REQUIRED422El perfil de personalidad de Ozzie para este usuario aún no ha sido inicializado. Se resuelve automáticamente después de la generación del plan.
RATE_LIMIT_EXCEEDED429Has excedido el límite de tasa de solicitudes. Consulta el header Retry-After para saber cuándo reintentar.
VERSION_MISMATCH400La versión de la API que estás usando ya no está soportada. Actualiza tu URL base a la versión actual.
INTERNAL_ERROR500Ocurrió un error inesperado en los servidores de Ozzie. Estos se registran e investigan automáticamente. Reintenta con backoff exponencial.

Límite de Tasa

Los límites de tasa se aplican por client_id. Límites actuales:

TierSolicitudes por minutoBurst
Standard12020
Growth600100
EnterprisePersonalizadoPersonalizado

Cuando se excede el límite, la API devuelve HTTP 429 con:

HTTP/1.1 429 Too Many Requests
Retry-After: 15
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1746460800
Header de RespuestaDescripción
Retry-AfterSegundos a esperar antes de reintentar
X-RateLimit-LimitTu cuota total de solicitudes por minuto
X-RateLimit-RemainingSolicitudes restantes en la ventana actual
X-RateLimit-ResetTimestamp Unix de cuando se reinicia la ventana
Implementa backoff

Siempre implementa backoff exponencial al manejar respuestas 429. Un bucle de reintento simple sin demora empeorará la presión sobre el límite de tasa. Comienza con un retraso de 1 segundo, duplicando hasta 32 segundos.


Idempotencia

Las solicitudes POST que crean recursos soportan idempotencia a través del header Idempotency-Key. Si proporcionas la misma clave en una solicitud repetida (ej.: después de un timeout de red), Ozzie devolverá la respuesta original en lugar de crear un duplicado.

POST https://api.ozzieapp.com/v1/users
Authorization: Bearer czJjbGllbnQ6czJzZWNyZXQ=
Content-Type: application/json
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000

{
"external_user_id": "usr_8821",
"name": "Maria Santos"
}

Reglas:

  • La clave debe ser un UUID v4.
  • Las claves están limitadas a tu client_id y expiran después de 24 horas.
  • Si la solicitud original todavía está en curso, el reintento recibirá HTTP 409 con código CONFLICT hasta que el original se complete.
  • Soportado en: POST /v1/users, POST /v1/users/{user_id}/financial-intake, POST /v1/users/{user_id}/transactions.
No todos los POSTs son idempotentes

POST /v1/users/{user_id}/plan/generate y POST /v1/users/{user_id}/chat no son idempotentes por diseño — cada llamada intencionalmente genera un nuevo recurso.