trading-platform/docs/02-definicion-modulos/OQI-009-marketplace/especificaciones/ET-MKT-002-api.md
rckrdmrd a7cca885f0 feat: Major platform documentation and architecture updates
Changes include:
- Updated architecture documentation
- Enhanced module definitions (OQI-001 to OQI-008)
- ML integration documentation updates
- Trading strategies documentation
- Orchestration and inventory updates
- Docker configuration updates

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 05:33:35 -06:00

21 KiB

id title type status priority epic project version dates tags
ET-MKT-002 Especificacion de API - Marketplace technical-spec Draft High OQI-009 trading-platform 1.0.0
created updated
2026-01-04 2026-01-04
marketplace
api
rest
endpoints

ET-MKT-002: Especificacion de API

Resumen

Este documento define los endpoints REST API para el modulo de Marketplace (OQI-009). Incluye endpoints para productos, compras, suscripciones, asesoria y visualizacion premium.

Base URL

/api/v1/marketplace

Autenticacion

Todos los endpoints requieren autenticacion via JWT Bearer token, excepto los marcados como publicos.

Authorization: Bearer <jwt_token>

Endpoints de Productos

GET /products

Lista productos del marketplace.

Query Parameters:

Parametro Tipo Requerido Descripcion
category string No Filtrar por categoria (slug)
type string No Filtrar por tipo de producto
search string No Busqueda en nombre/descripcion
featured boolean No Solo productos destacados
sort string No Ordenamiento: price_asc, price_desc, rating, newest
page number No Pagina (default: 1)
limit number No Items por pagina (default: 12, max: 50)

Response 200:

{
  "data": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440001",
      "name": "Pro Signal Pack",
      "slug": "pro-signal-pack",
      "shortDescription": "200 senales ML de alta confianza",
      "type": "signal_pack",
      "price": 29.00,
      "currency": "USD",
      "billingType": "one_time",
      "category": {
        "id": "cat-001",
        "name": "Senales",
        "slug": "signals"
      },
      "isFeatured": true,
      "metadata": {
        "credits": 200,
        "validityDays": 60,
        "minConfidence": 80
      }
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 12,
    "total": 7,
    "totalPages": 1
  }
}

GET /products/:id

Obtiene detalle de un producto.

Response 200:

{
  "id": "550e8400-e29b-41d4-a716-446655440001",
  "name": "Pro Signal Pack",
  "slug": "pro-signal-pack",
  "description": "Paquete de 200 senales ML de alta confianza...",
  "shortDescription": "200 senales ML de alta confianza",
  "type": "signal_pack",
  "price": 29.00,
  "currency": "USD",
  "billingType": "one_time",
  "subscriptionInterval": null,
  "category": {
    "id": "cat-001",
    "name": "Senales",
    "slug": "signals"
  },
  "isFeatured": true,
  "isActive": true,
  "metadata": {
    "credits": 200,
    "validityDays": 60,
    "minConfidence": 80
  },
  "relatedProducts": [
    {
      "id": "550e8400-e29b-41d4-a716-446655440002",
      "name": "Basic Signal Pack",
      "price": 9.00
    }
  ],
  "createdAt": "2026-01-04T00:00:00Z"
}

GET /categories

Lista categorias de productos.

Response 200:

{
  "data": [
    {
      "id": "cat-001",
      "name": "Senales",
      "slug": "signals",
      "description": "Paquetes de senales ML premium",
      "icon": "signal",
      "productCount": 3
    }
  ]
}

Endpoints de Compras

POST /purchases

Crea una nueva compra.

Request Body:

{
  "productId": "550e8400-e29b-41d4-a716-446655440001",
  "paymentMethodId": "pm_1234567890",
  "quantity": 1,
  "acceptedTerms": true
}

Response 201:

{
  "id": "purchase-001",
  "status": "completed",
  "product": {
    "id": "550e8400-e29b-41d4-a716-446655440001",
    "name": "Pro Signal Pack"
  },
  "quantity": 1,
  "unitPrice": 29.00,
  "totalPrice": 29.00,
  "currency": "USD",
  "paymentId": "pi_abc123",
  "completedAt": "2026-01-04T12:00:00Z",
  "receipt": {
    "url": "https://receipts.stripe.com/...",
    "emailSent": true
  },
  "activation": {
    "type": "signal_credits",
    "creditsAdded": 200,
    "newBalance": 215,
    "expiresAt": "2026-03-04T12:00:00Z"
  }
}

Response 402 (Pago Fallido):

{
  "error": {
    "code": "PAYMENT_FAILED",
    "message": "El pago no pudo ser procesado",
    "details": {
      "declineCode": "insufficient_funds"
    }
  }
}

GET /purchases

Lista compras del usuario autenticado.

Query Parameters:

Parametro Tipo Descripcion
status string Filtrar por estado
productType string Filtrar por tipo de producto
from date Fecha desde
to date Fecha hasta
page number Pagina
limit number Items por pagina

Response 200:

{
  "data": [
    {
      "id": "purchase-001",
      "product": {
        "id": "prod-001",
        "name": "Pro Signal Pack",
        "type": "signal_pack"
      },
      "totalPrice": 29.00,
      "currency": "USD",
      "status": "completed",
      "completedAt": "2026-01-04T12:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 5
  }
}

GET /purchases/:id

Obtiene detalle de una compra.

Response 200:

{
  "id": "purchase-001",
  "product": {
    "id": "prod-001",
    "name": "Pro Signal Pack",
    "type": "signal_pack",
    "price": 29.00
  },
  "quantity": 1,
  "unitPrice": 29.00,
  "totalPrice": 29.00,
  "currency": "USD",
  "status": "completed",
  "paymentMethod": "visa ****4242",
  "completedAt": "2026-01-04T12:00:00Z",
  "receipt": {
    "url": "https://receipts.stripe.com/..."
  }
}

Endpoints de Suscripciones

POST /subscriptions

Crea una nueva suscripcion.

Request Body:

{
  "productId": "550e8400-e29b-41d4-a716-446655440003",
  "paymentMethodId": "pm_1234567890",
  "acceptedTerms": true
}

Response 201:

{
  "id": "sub-001",
  "status": "active",
  "product": {
    "id": "prod-003",
    "name": "Unlimited Signals"
  },
  "price": 49.00,
  "currency": "USD",
  "interval": "monthly",
  "currentPeriodStart": "2026-01-04T00:00:00Z",
  "currentPeriodEnd": "2026-02-04T00:00:00Z",
  "cancelAtPeriodEnd": false
}

GET /subscriptions

Lista suscripciones del usuario.

Response 200:

{
  "data": [
    {
      "id": "sub-001",
      "product": {
        "id": "prod-003",
        "name": "Unlimited Signals",
        "type": "signal_pack"
      },
      "status": "active",
      "price": 49.00,
      "interval": "monthly",
      "currentPeriodEnd": "2026-02-04T00:00:00Z",
      "cancelAtPeriodEnd": false
    }
  ]
}

DELETE /subscriptions/:id

Cancela una suscripcion.

Request Body:

{
  "reason": "No longer needed",
  "cancelImmediately": false
}

Response 200:

{
  "id": "sub-001",
  "status": "active",
  "cancelAtPeriodEnd": true,
  "canceledAt": "2026-01-04T12:00:00Z",
  "accessEndsAt": "2026-02-04T00:00:00Z",
  "message": "Tu suscripcion se cancelara al final del periodo actual"
}

Endpoints de Creditos de Senales

GET /credits

Obtiene creditos de senales del usuario.

Response 200:

{
  "totalAvailable": 150,
  "hasUnlimited": false,
  "credits": [
    {
      "id": "credit-001",
      "productName": "Pro Signal Pack",
      "initialAmount": 200,
      "remainingAmount": 150,
      "expiresAt": "2026-03-04T12:00:00Z",
      "isUnlimited": false
    }
  ],
  "usage": {
    "today": 3,
    "thisWeek": 15,
    "thisMonth": 50
  }
}

GET /credits/history

Historial de uso de creditos.

Response 200:

{
  "data": [
    {
      "id": "delivery-001",
      "signal": {
        "id": "sig-001",
        "symbol": "BTC/USDT",
        "action": "BUY",
        "confidence": 87.5
      },
      "deliveredAt": "2026-01-04T14:30:00Z",
      "channel": "both"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 20,
    "total": 50
  }
}

Endpoints de Asesoria

GET /advisors

Lista asesores disponibles.

Query Parameters:

Parametro Tipo Descripcion
specialty string Filtrar por especialidad
language string Filtrar por idioma
minRating number Rating minimo
sort string rating, price, experience
page number Pagina
limit number Items por pagina

Response 200:

{
  "data": [
    {
      "id": "advisor-001",
      "displayName": "Maria Garcia, CFA",
      "title": "Crypto Trading Expert",
      "shortBio": "10 anos de experiencia en mercados crypto...",
      "specialties": ["crypto", "defi", "technical_analysis"],
      "experienceYears": 10,
      "languages": ["es", "en"],
      "rating": 4.9,
      "reviewCount": 85,
      "completedSessions": 120,
      "priceFrom": 49.00,
      "profileImageUrl": "https://...",
      "nextAvailable": "2026-01-05T09:00:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 10,
    "total": 5
  }
}

GET /advisors/:id

Obtiene perfil completo de un asesor.

Response 200:

{
  "id": "advisor-001",
  "displayName": "Maria Garcia, CFA",
  "title": "Crypto Trading Expert",
  "bio": "Analista certificada CFA con 10 anos de experiencia...",
  "shortBio": "10 anos de experiencia en mercados crypto...",
  "specialties": ["crypto", "defi", "technical_analysis"],
  "experienceYears": 10,
  "languages": ["es", "en"],
  "rating": 4.9,
  "reviewCount": 85,
  "completedSessions": 120,
  "profileImageUrl": "https://...",
  "isVerified": true,
  "sessionOptions": [
    {
      "duration": 30,
      "price": 49.00,
      "currency": "USD",
      "includes": ["video", "notes"]
    },
    {
      "duration": 60,
      "price": 89.00,
      "currency": "USD",
      "includes": ["video", "notes", "action_plan"]
    },
    {
      "duration": 90,
      "price": 119.00,
      "currency": "USD",
      "includes": ["video", "notes", "action_plan", "follow_up"]
    }
  ],
  "reviews": [
    {
      "id": "review-001",
      "rating": 5,
      "comment": "Excelente sesion, muy profesional",
      "userName": "Juan P.",
      "createdAt": "2026-01-03T00:00:00Z"
    }
  ]
}

GET /advisors/:id/availability

Obtiene disponibilidad de un asesor.

Query Parameters:

Parametro Tipo Descripcion
duration number Duracion de sesion en minutos
timezone string Zona horaria del usuario
from date Fecha desde
to date Fecha hasta

Response 200:

{
  "advisorId": "advisor-001",
  "duration": 60,
  "timezone": "America/Mexico_City",
  "slots": [
    {
      "date": "2026-01-06",
      "times": ["09:00", "10:00", "11:00", "14:00", "15:00"]
    },
    {
      "date": "2026-01-07",
      "times": ["09:00", "10:00", "14:00"]
    }
  ]
}

POST /advisory-sessions

Agenda una sesion de asesoria.

Request Body:

{
  "advisorId": "advisor-001",
  "productId": "prod-advisory-60",
  "scheduledAt": "2026-01-06T10:00:00-06:00",
  "timezone": "America/Mexico_City",
  "paymentMethodId": "pm_1234567890",
  "notes": "Quiero discutir mi estrategia de DeFi"
}

Response 201:

{
  "id": "session-001",
  "advisor": {
    "id": "advisor-001",
    "displayName": "Maria Garcia, CFA"
  },
  "duration": 60,
  "scheduledAt": "2026-01-06T16:00:00Z",
  "scheduledAtLocal": "2026-01-06T10:00:00-06:00",
  "timezone": "America/Mexico_City",
  "status": "scheduled",
  "price": 89.00,
  "currency": "USD",
  "calEventId": "cal-event-123",
  "joinUrl": null,
  "confirmationEmailSent": true
}

GET /advisory-sessions

Lista sesiones del usuario.

Query Parameters:

Parametro Tipo Descripcion
status string scheduled, completed, cancelled
from date Fecha desde
to date Fecha hasta

Response 200:

{
  "data": [
    {
      "id": "session-001",
      "advisor": {
        "id": "advisor-001",
        "displayName": "Maria Garcia, CFA",
        "profileImageUrl": "https://..."
      },
      "duration": 60,
      "scheduledAt": "2026-01-06T16:00:00Z",
      "status": "scheduled",
      "joinUrl": "https://daily.co/room-xyz",
      "canReschedule": true,
      "canCancel": true
    }
  ]
}

GET /advisory-sessions/:id

Obtiene detalle de una sesion.

Response 200:

{
  "id": "session-001",
  "advisor": {
    "id": "advisor-001",
    "displayName": "Maria Garcia, CFA",
    "profileImageUrl": "https://..."
  },
  "duration": 60,
  "scheduledAt": "2026-01-06T16:00:00Z",
  "endedAt": null,
  "status": "scheduled",
  "joinUrl": "https://daily.co/room-xyz",
  "recordingUrl": null,
  "notes": {
    "summary": null,
    "recommendations": [],
    "resources": [],
    "followUpActions": []
  },
  "review": null,
  "canReschedule": true,
  "canCancel": true,
  "cancellationPolicy": {
    "fullRefundBefore": "2026-01-05T16:00:00Z",
    "partialRefundBefore": "2026-01-06T04:00:00Z"
  }
}

PATCH /advisory-sessions/:id

Reagenda una sesion.

Request Body:

{
  "scheduledAt": "2026-01-07T14:00:00-06:00",
  "timezone": "America/Mexico_City"
}

Response 200:

{
  "id": "session-001",
  "scheduledAt": "2026-01-07T20:00:00Z",
  "status": "scheduled",
  "message": "Sesion reagendada exitosamente"
}

DELETE /advisory-sessions/:id

Cancela una sesion.

Request Body:

{
  "reason": "Schedule conflict"
}

Response 200:

{
  "id": "session-001",
  "status": "cancelled",
  "cancelledAt": "2026-01-04T12:00:00Z",
  "refund": {
    "amount": 89.00,
    "percentage": 100,
    "status": "processing"
  }
}

POST /advisory-sessions/:id/notes

Asesor agrega notas a la sesion.

Request Body:

{
  "summary": "Discutimos estrategias de DeFi y riesgos...",
  "recommendations": [
    "Diversificar en multiples protocolos",
    "Implementar stop-loss automaticos"
  ],
  "resources": [
    {
      "title": "Guia de DeFi Seguro",
      "url": "https://..."
    }
  ],
  "followUpActions": [
    "Revisar portfolio actual",
    "Configurar alertas de precio"
  ]
}

Response 201:

{
  "id": "notes-001",
  "sessionId": "session-001",
  "createdAt": "2026-01-06T18:00:00Z",
  "notificationSent": true
}

POST /advisory-sessions/:id/reviews

Usuario deja review de la sesion.

Request Body:

{
  "rating": 5,
  "comment": "Excelente sesion, Maria es muy profesional y conocedora",
  "isPublic": true
}

Response 201:

{
  "id": "review-001",
  "rating": 5,
  "comment": "Excelente sesion...",
  "isPublic": true,
  "createdAt": "2026-01-06T19:00:00Z"
}

Endpoints de Visualizacion Premium

GET /visualization/subscription

Obtiene estado de suscripcion de visualizacion.

Response 200:

{
  "isActive": true,
  "subscription": {
    "id": "vis-sub-001",
    "startedAt": "2026-01-01T00:00:00Z",
    "expiresAt": "2026-02-01T00:00:00Z",
    "cancelAtPeriodEnd": false
  },
  "features": [
    "ml_indicators",
    "unlimited_backtest",
    "unlimited_alerts",
    "multi_chart_4"
  ],
  "limits": {
    "alerts": -1,
    "layouts": -1,
    "backtestDays": -1,
    "charts": 4
  }
}

POST /visualization/subscribe

Crea suscripcion de visualizacion premium.

Request Body:

{
  "paymentMethodId": "pm_1234567890",
  "acceptedTerms": true
}

Response 201:

{
  "subscription": {
    "id": "vis-sub-001",
    "status": "active",
    "startedAt": "2026-01-04T00:00:00Z",
    "expiresAt": "2026-02-04T00:00:00Z"
  },
  "features": [
    "ml_indicators",
    "unlimited_backtest",
    "unlimited_alerts",
    "multi_chart_4"
  ],
  "message": "Visualizacion Premium activada"
}

GET /visualization/indicators

Lista indicadores disponibles.

Response 200:

{
  "basic": [
    {
      "id": "sma",
      "name": "Simple Moving Average",
      "type": "overlay",
      "available": true
    },
    {
      "id": "rsi",
      "name": "Relative Strength Index",
      "type": "panel",
      "available": true
    }
  ],
  "premium": [
    {
      "id": "ml_range_predictor",
      "name": "Range Predictor",
      "type": "overlay",
      "description": "Predice rangos de precio",
      "available": true,
      "requiresPremium": true
    },
    {
      "id": "ml_amd_detector",
      "name": "AMD Detector",
      "type": "overlay",
      "description": "Detecta patrones AMD",
      "available": true,
      "requiresPremium": true
    }
  ]
}

GET /visualization/layouts

Lista layouts guardados del usuario.

Response 200:

{
  "data": [
    {
      "id": "layout-001",
      "name": "Mi Layout Principal",
      "isDefault": true,
      "chartCount": 4,
      "createdAt": "2026-01-03T00:00:00Z"
    }
  ],
  "limits": {
    "max": -1,
    "used": 3
  }
}

POST /visualization/layouts

Guarda un nuevo layout.

Request Body:

{
  "name": "Crypto Watch",
  "layoutConfig": {
    "grid": "2x2",
    "charts": [
      {"position": 0, "symbol": "BTC/USDT", "timeframe": "4H"},
      {"position": 1, "symbol": "ETH/USDT", "timeframe": "4H"},
      {"position": 2, "symbol": "SOL/USDT", "timeframe": "4H"},
      {"position": 3, "symbol": "AVAX/USDT", "timeframe": "4H"}
    ]
  },
  "indicators": [
    {"chartIndex": 0, "indicators": ["ml_range_predictor", "sma"]},
    {"chartIndex": 1, "indicators": ["ml_amd_detector"]}
  ],
  "isDefault": false
}

Response 201:

{
  "id": "layout-002",
  "name": "Crypto Watch",
  "isDefault": false,
  "createdAt": "2026-01-04T12:00:00Z"
}

POST /visualization/alerts

Crea una alerta de indicador.

Request Body:

{
  "indicatorId": "ml_amd_detector",
  "symbol": "BTC/USDT",
  "conditions": [
    {
      "field": "phase",
      "operator": "equals",
      "value": "distribution"
    }
  ],
  "notificationChannels": ["push", "email"],
  "triggerOnce": false
}

Response 201:

{
  "id": "alert-001",
  "indicatorId": "ml_amd_detector",
  "symbol": "BTC/USDT",
  "isActive": true,
  "createdAt": "2026-01-04T12:00:00Z"
}

POST /visualization/backtest

Ejecuta un backtest.

Request Body:

{
  "symbol": "BTC/USDT",
  "strategyConfig": {
    "indicators": ["ml_amd_detector", "ml_signal_overlay"],
    "entryConditions": [...],
    "exitConditions": [...]
  },
  "periodStart": "2025-10-01",
  "periodEnd": "2026-01-01",
  "initialCapital": 10000
}

Response 200:

{
  "id": "backtest-001",
  "symbol": "BTC/USDT",
  "periodStart": "2025-10-01",
  "periodEnd": "2026-01-01",
  "initialCapital": 10000.00,
  "finalCapital": 12450.00,
  "totalReturn": 0.245,
  "totalTrades": 45,
  "winningTrades": 30,
  "losingTrades": 15,
  "winRate": 66.67,
  "profitFactor": 2.3,
  "maxDrawdown": -8.5,
  "sharpeRatio": 1.82,
  "trades": [
    {
      "entryDate": "2025-10-05T14:00:00Z",
      "exitDate": "2025-10-06T10:00:00Z",
      "entryPrice": 42150.00,
      "exitPrice": 43200.00,
      "side": "long",
      "pnl": 250.00,
      "pnlPercent": 2.49
    }
  ]
}

Webhooks

POST /webhooks/stripe

Procesa eventos de Stripe.

Headers:

Stripe-Signature: t=1234567890,v1=signature...

Eventos Soportados:

  • payment_intent.succeeded
  • payment_intent.payment_failed
  • customer.subscription.created
  • customer.subscription.updated
  • customer.subscription.deleted
  • invoice.paid
  • invoice.payment_failed

POST /webhooks/cal

Procesa eventos de Cal.com.

Eventos Soportados:

  • BOOKING_CREATED
  • BOOKING_CANCELLED
  • BOOKING_RESCHEDULED
  • MEETING_ENDED

Payload Ejemplo:

{
  "triggerEvent": "BOOKING_CREATED",
  "payload": {
    "bookingId": 12345,
    "uid": "booking-uid-123",
    "startTime": "2026-01-06T16:00:00Z",
    "endTime": "2026-01-06T17:00:00Z",
    "attendees": [
      {
        "email": "user@example.com",
        "name": "Juan Perez"
      }
    ],
    "metadata": {
      "sessionId": "session-001"
    }
  }
}

POST /webhooks/daily

Procesa eventos de Daily.co.

Eventos Soportados:

  • meeting.started
  • meeting.ended
  • recording.ready

Codigos de Error

Codigo HTTP Status Descripcion
PRODUCT_NOT_FOUND 404 Producto no encontrado
PRODUCT_UNAVAILABLE 400 Producto no disponible
INSUFFICIENT_CREDITS 400 Creditos insuficientes
PAYMENT_FAILED 402 Pago fallido
SUBSCRIPTION_EXISTS 409 Ya existe suscripcion activa
ADVISOR_NOT_AVAILABLE 400 Asesor no disponible
SLOT_NOT_AVAILABLE 409 Horario no disponible
SESSION_NOT_CANCELLABLE 400 Sesion no puede cancelarse
PREMIUM_REQUIRED 403 Requiere suscripcion premium
LIMIT_EXCEEDED 400 Limite excedido

Formato de Error:

{
  "error": {
    "code": "PAYMENT_FAILED",
    "message": "El pago no pudo ser procesado",
    "details": {
      "declineCode": "insufficient_funds"
    },
    "timestamp": "2026-01-04T12:00:00Z",
    "requestId": "req-abc123"
  }
}

Rate Limiting

Endpoint Limite Ventana
GET /products 100 1 minuto
POST /purchases 10 1 minuto
POST /subscriptions 5 1 minuto
POST /advisory-sessions 10 1 hora
POST /visualization/backtest 20 1 hora

Headers de Rate Limit:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1704369600

Referencias