{
  "info": {
    "name": "HearthingX Partner API",
    "description": "Colección para integradores B2B (integración no biométrica). Configure variables base_url y api_key.\n\nOrden sugerido: 00 Health → 01 Sesión → 02 Ambiente → 03 Dispositivo → 04 Auditoría.\n\nAUTENTICACIÓN BIOMÉTRICA (enrolamiento y verificación de voz): se realiza EXCLUSIVAMENTE por WebSocket (voz viva, tramas PCM) con el cliente Node descargable desde la guía web (Ruta A). Postman cubre sesión, ambiente, dispositivo, confirmación de enrolamiento y auditoría; no realiza biometría.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    { "key": "base_url", "value": "http://localhost:8000" },
    { "key": "api_key", "value": "hx_sandbox_REEMPLACE" },
    { "key": "session_id", "value": "" },
    { "key": "device_signature", "value": "mic:test-device" },
    { "key": "challenge_id", "value": "" },
    { "key": "challenge_value", "value": "" },
    { "key": "challenge_t0_ms", "value": "" },
    { "key": "challenge_t1_ms", "value": "" }
  ],
  "auth": {
    "type": "bearer",
    "bearer": [{ "key": "token", "value": "{{api_key}}", "type": "string" }]
  },
  "item": [
    {
      "name": "00 Health",
      "item": [
        {
          "name": "GET /health (público)",
          "request": {
            "auth": { "type": "noauth" },
            "method": "GET",
            "url": "{{base_url}}/health"
          }
        },
        {
          "name": "GET /api/v1/health (API Key)",
          "request": {
            "method": "GET",
            "header": [{ "key": "X-API-Key", "value": "{{api_key}}" }],
            "url": "{{base_url}}/api/v1/health"
          }
        }
      ]
    },
    {
      "name": "01 Sesión",
      "item": [
        {
          "name": "POST /api/session/init (verify)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 200) {",
                  "  var j = pm.response.json();",
                  "  pm.collectionVariables.set('session_id', j.session_id);",
                  "  if (j.challenge) {",
                  "    pm.collectionVariables.set('challenge_id', j.challenge.challenge_id);",
                  "    pm.collectionVariables.set('challenge_value', j.challenge.value);",
                  "    var now = Date.now();",
                  "    pm.collectionVariables.set('challenge_t0_ms', String(now - 800));",
                  "    pm.collectionVariables.set('challenge_t1_ms', String(now));",
                  "  }",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"captcha_token\": \"mock-token\",\n  \"flow\": \"verify\",\n  \"device_info\": {\n    \"hw_id\": \"postman-demo-hw-001\",\n    \"model\": \"Postman\",\n    \"os\": \"integration-test\"\n  }\n}"
            },
            "url": "{{base_url}}/api/session/init"
          }
        },
        {
          "name": "POST /api/session/init (enrollment)",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 200) {",
                  "  var j = pm.response.json();",
                  "  pm.collectionVariables.set('session_id', j.session_id);",
                  "  if (j.challenge) {",
                  "    pm.collectionVariables.set('challenge_id', j.challenge.challenge_id);",
                  "    pm.collectionVariables.set('challenge_value', j.challenge.value);",
                  "    var now = Date.now();",
                  "    pm.collectionVariables.set('challenge_t0_ms', String(now - 800));",
                  "    pm.collectionVariables.set('challenge_t1_ms', String(now));",
                  "  }",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"captcha_token\": \"mock-token\",\n  \"flow\": \"enrollment\",\n  \"device_info\": {\n    \"hw_id\": \"postman-demo-hw-001\",\n    \"model\": \"Postman\",\n    \"os\": \"integration-test\"\n  }\n}"
            },
            "url": "{{base_url}}/api/session/init"
          }
        },
        {
          "name": "GET /api/challenge",
          "event": [
            {
              "listen": "test",
              "script": {
                "exec": [
                  "if (pm.response.code === 200) {",
                  "  var j = pm.response.json();",
                  "  pm.collectionVariables.set('challenge_id', j.challenge_id);",
                  "  pm.collectionVariables.set('challenge_value', j.value);",
                  "  var now = Date.now();",
                  "  pm.collectionVariables.set('challenge_t0_ms', String(now - 800));",
                  "  pm.collectionVariables.set('challenge_t1_ms', String(now));",
                  "}"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/challenge"
          }
        },
        {
          "name": "POST /api/session/logout",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{}"
            },
            "url": "{{base_url}}/api/session/logout"
          }
        },
        {
          "name": "POST /api/enroll/confirm",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"session_id\": \"{{session_id}}\"\n}"
            },
            "url": "{{base_url}}/api/enroll/confirm",
            "description": "Cierra/persiste el enrolamiento capturado en vivo por WebSocket (Ruta A). Pertenece al flujo de enrollment WS; no procesa audio por sí mismo."
          }
        }
      ]
    },
    {
      "name": "02 Ambiente",
      "item": [
        {
          "name": "POST /api/environment",
          "request": {
            "method": "POST",
            "body": {
              "mode": "formdata",
              "formdata": [
                {
                  "key": "archivo",
                  "type": "file",
                  "src": [],
                  "description": "WAV ~300-800ms ambiente SIN voz humana"
                }
              ]
            },
            "url": "{{base_url}}/api/environment?session_id={{session_id}}"
          }
        }
      ]
    },
    {
      "name": "03 Dispositivo",
      "item": [
        {
          "name": "POST /api/device/register",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"deviceId\": \"postman-mic-01\",\n  \"label\": \"Postman integration\"\n}"
            },
            "url": "{{base_url}}/api/device/register"
          }
        },
        {
          "name": "GET /api/v1/devices/{signature}/status",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/v1/devices/{{device_signature}}/status"
          }
        },
        {
          "name": "GET /api/devices/{signature}/status (legacy)",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/devices/{{device_signature}}/status"
          }
        }
      ]
    },
    {
      "name": "04 Auditoría (Partner v1)",
      "item": [
        {
          "name": "GET /api/v1/audit/auth-logs",
          "request": {
            "method": "GET",
            "url": {
              "raw": "{{base_url}}/api/v1/audit/auth-logs?limit=20&session_id={{session_id}}",
              "host": ["{{base_url}}"],
              "path": ["api", "v1", "audit", "auth-logs"],
              "query": [
                { "key": "limit", "value": "20" },
                { "key": "session_id", "value": "{{session_id}}" }
              ]
            }
          }
        },
        {
          "name": "GET /api/v1/audit/devices",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/v1/audit/devices?limit=20"
          }
        },
        {
          "name": "GET /api/v1/audit/subjects",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/v1/audit/subjects?limit=20"
          }
        },
        {
          "name": "GET /api/v1/audit/session-chain",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/v1/audit/session-chain?limit=20"
          }
        },
        {
          "name": "GET /api/v1/audit/identities",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/v1/audit/identities?limit=20"
          }
        },
        {
          "name": "GET /api/v1/audit/ga-logs",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/v1/audit/ga-logs?limit=10"
          }
        },
        {
          "name": "GET /api/audit/logs (legacy)",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/audit/logs?limit=10"
          }
        }
      ]
    },
    {
      "name": "05 Métricas",
      "item": [
        {
          "name": "GET /api/metrics/latency",
          "request": {
            "method": "GET",
            "url": "{{base_url}}/api/metrics/latency?endpoint=verify&limit=20"
          }
        },
        {
          "name": "GET /health/pad",
          "request": {
            "auth": { "type": "noauth" },
            "method": "GET",
            "url": "{{base_url}}/health/pad"
          }
        }
      ]
    },
    {
      "name": "07 Telemetría cliente",
      "item": [
        {
          "name": "POST /api/client-errors",
          "request": {
            "method": "POST",
            "header": [{ "key": "Content-Type", "value": "application/json" }],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"error_code\": \"WS_HANDSHAKE_FAILED\",\n  \"error_phase\": \"streaming\",\n  \"message\": \"Ejemplo integrador Postman\",\n  \"session_id\": \"{{session_id}}\",\n  \"hw_id\": \"postman-demo-hw-001\",\n  \"device_model\": \"Postman\",\n  \"os\": \"integration-test\",\n  \"app_version\": \"postman-1.0\"\n}"
            },
            "url": "{{base_url}}/api/client-errors"
          }
        }
      ]
    }
  ]
}
