{
  "info": {
    "name": "B5.ly Partner API (Headless)",
    "_postman_id": "c2d13b5c-49e8-4399-b07a-19acdc2a75bd",
    "description": "## Quickstart\n1. Set collection variables (`baseUrl`, `apiKey`, `providerId`).\n2. (Optional) Run folder **Assessment (v1) - Auto (Runner)** to generate a `resultId`.\n3. Send **Reports -> Create Report** to spend 1 credit and capture `reportId`.\n4. Send **Reports -> Get Report** to fetch the JSON metrics.\n\nNotes:\n- `v1` assessment endpoints only require `Authorization: Bearer <apiKey>`.\n- `b5plus/v2` endpoints require both `Authorization` and `X-Provider`.\n- Supported `lang`/`locale` values: `en`, `ar`, `es` (use the `{{lang}}` collection variable).\n- Debug endpoints under `/api/b5plus/v2/debug/*` require `adminKey` (`x-b5plus-key`) and are usually disabled in production.\n\nPartner guide: `/developer/b5plus-partner-headless-guide.md`",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "version": "2025-12"
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "pm.request.headers.remove('Authorization');",
          "pm.request.headers.remove('X-Provider');",
          "pm.request.headers.remove('x-b5plus-key');",
          "const segments = (pm.request.url && pm.request.url.path) ? pm.request.url.path : [];",
          "const pathName = '/' + segments.join('/');",
          "const isV2Debug = pathName.startsWith('/api/b5plus/v2/debug/');",
          "const adminKey = pm.collectionVariables.get('adminKey');",
          "if (adminKey && isV2Debug) {",
          "  pm.request.headers.add({ key: 'x-b5plus-key', value: adminKey });",
          "}",
          "const isEngine = pm.request.headers.has('X-Engine');",
          "const engineToken = pm.collectionVariables.get('engineToken');",
          "const resellerToken = pm.collectionVariables.get('apiKey') || pm.collectionVariables.get('token');",
          "if (isEngine) {",
            "  if (engineToken) {",
              "    pm.request.headers.add({ key: 'Authorization', value: 'Bearer ' + engineToken });",
            "  }",
          "} else {",
            "  if (resellerToken) {",
              "    pm.request.headers.add({ key: 'Authorization', value: 'Bearer ' + resellerToken });",
            "  }",
            "  const provider = pm.collectionVariables.get('providerId') || pm.collectionVariables.get('provider');",
            "  if (provider && pathName.startsWith('/api/b5plus/v2/')) {",
              "    pm.request.headers.add({ key: 'X-Provider', value: provider });",
            "  }",
          "}",
          "const autoIdempotent = ['/api/b5plus/v2/reports', '/api/b5plus/v2/ingest/result'];",
          "if (pm.request.method === 'POST' && autoIdempotent.includes(pathName) && !pm.request.headers.has('Idempotency-Key')) {",
            "  pm.request.headers.add({ key: 'Idempotency-Key', value: pm.variables.replaceIn('{{$guid}}') });",
          "}"
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "baseUrl",
      "value": "http://localhost:3000",
      "type": "string"
    },
    {
      "key": "apiKey",
      "value": "",
      "type": "string"
    },
    {
      "key": "adminKey",
      "value": "",
      "type": "string",
      "description": "Admin key for internal endpoints (maps to B5PLUS_V2_TEST_KEY)."
    },
    {
      "key": "providerId",
      "value": "",
      "type": "string"
    },
    {
      "key": "token",
      "value": "",
      "type": "string"
    },
    {
      "key": "provider",
      "value": "",
      "type": "string"
    },
    {
      "key": "lang",
      "value": "en",
      "type": "string",
      "description": "Language/locale code (en|ar|es). Used as v1 `lang` and v2 `locale`."
    },
    {
      "key": "customerRef",
      "value": "ACME-44721",
      "type": "string"
    },
    {
      "key": "testSessionId",
      "value": "",
      "type": "string"
    },
    {
      "key": "batchAnswersJson",
      "value": "[]",
      "type": "string"
    },
    {
      "key": "allAnswersJson",
      "value": "[]",
      "type": "string"
    },
    {
      "key": "resultId",
      "value": "",
      "type": "string"
    },
    {
      "key": "reportId",
      "value": "",
      "type": "string"
    },
    {
      "key": "viewRid",
      "value": "",
      "type": "string"
    },
    {
      "key": "viewExp",
      "value": "",
      "type": "string"
    },
    {
      "key": "viewSig",
      "value": "",
      "type": "string"
    },
    {
      "key": "engineToken",
      "value": "",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "Assessment (v1)",
      "item": [
        {
          "name": "Start Session",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"partnerUserRef\": \"demo_user_1\",\n  \"lang\": \"{{lang}}\",\n  \"meta\": {\n    \"age\": 30,\n    \"gender\": \"M\",\n    \"country\": \"US\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/tests/start",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "tests",
                "start"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Has testSessionId', function () { pm.expect(body.testSessionId).to.be.a('string'); });",
                  "if (body.testSessionId) { pm.collectionVariables.set('testSessionId', body.testSessionId); }",
                  "pm.collectionVariables.set('batchAnswersJson', '[]');",
                  "pm.collectionVariables.set('allAnswersJson', '[]');",
                  "pm.collectionVariables.set('resultId', '');"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Items (Batch)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/tests/items?testSessionId={{testSessionId}}&lang={{lang}}&batch=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "tests",
                "items"
              ],
              "query": [
                {
                  "key": "testSessionId",
                  "value": "{{testSessionId}}"
                },
                {
                  "key": "lang",
                  "value": "{{lang}}"
                },
                {
                  "key": "batch",
                  "value": "20"
                }
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Items returned', function () { pm.expect(body.items).to.be.an('array'); });",
                  "const items = Array.isArray(body.items) ? body.items : [];",
                  "const answers = items.map(it => ({ questionID: it.questionID, score: 3, domain: it.domain, facet: it.facet }));",
                  "pm.collectionVariables.set('batchAnswersJson', JSON.stringify(answers));"
                ]
              }
            }
          ]
        },
        {
          "name": "Submit Answers (Batch Only)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"testSessionId\": \"{{testSessionId}}\",\n  \"lang\": \"{{lang}}\",\n  \"finalize\": false,\n  \"answers\": {{batchAnswersJson}}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/tests/submit",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "tests",
                "submit"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200 or 202', function () { pm.expect([200, 202]).to.include(pm.response.code); });",
                  "const body = pm.response.json();",
                  "if (pm.response.code === 200 && body.resultId) { pm.collectionVariables.set('resultId', body.resultId); }"
                ]
              }
            }
          ]
        },
        {
          "name": "Save Demographics (Optional)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"testSessionId\": \"{{testSessionId}}\",\n  \"gender\": \"M\",\n  \"birthYear\": 1995,\n  \"countryCode\": \"US\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/tests/demographics",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "tests",
                "demographics"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('ok=true', function () { pm.expect(body.ok).to.eql(true); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Assessment (v1) - Auto (Runner)",
      "item": [
        {
          "name": "Start Session (Auto)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"partnerUserRef\": \"demo_user_auto\",\n  \"lang\": \"{{lang}}\",\n  \"meta\": {\n    \"age\": 30,\n    \"gender\": \"M\",\n    \"country\": \"US\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/tests/start",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "tests",
                "start"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "if (body.testSessionId) { pm.collectionVariables.set('testSessionId', body.testSessionId); }",
                  "pm.collectionVariables.set('batchAnswersJson', '[]');",
                  "pm.collectionVariables.set('allAnswersJson', '[]');",
                  "pm.collectionVariables.set('resultId', '');",
                  "postman.setNextRequest('Get Items (Auto)');"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Items (Auto)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/v1/tests/items?testSessionId={{testSessionId}}&lang={{lang}}&batch=20",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "tests",
                "items"
              ],
              "query": [
                {
                  "key": "testSessionId",
                  "value": "{{testSessionId}}"
                },
                {
                  "key": "lang",
                  "value": "{{lang}}"
                },
                {
                  "key": "batch",
                  "value": "20"
                }
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "const items = Array.isArray(body.items) ? body.items : [];",
                  "if (items.length === 0) {",
                  "  postman.setNextRequest('Finalize Submit (Auto)');",
                  "  return;",
                  "}",
                  "const batchAnswers = items.map(it => ({ questionID: it.questionID, score: (Math.floor(Math.random() * 5) + 1), domain: it.domain, facet: it.facet }));",
                  "pm.collectionVariables.set('batchAnswersJson', JSON.stringify(batchAnswers));",
                  "let all = [];",
                  "try { all = JSON.parse(pm.collectionVariables.get('allAnswersJson') || '[]'); } catch (e) { all = []; }",
                  "all = all.concat(batchAnswers);",
                  "pm.collectionVariables.set('allAnswersJson', JSON.stringify(all));",
                  "postman.setNextRequest('Submit Batch (Auto)');"
                ]
              }
            }
          ]
        },
        {
          "name": "Submit Batch (Auto)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"testSessionId\": \"{{testSessionId}}\",\n  \"lang\": \"{{lang}}\",\n  \"finalize\": false,\n  \"answers\": {{batchAnswersJson}}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/tests/submit",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "tests",
                "submit"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 202', function () { pm.response.to.have.status(202); });",
                  "postman.setNextRequest('Get Items (Auto)');"
                ]
              }
            }
          ]
        },
        {
          "name": "Finalize Submit (Auto)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"testSessionId\": \"{{testSessionId}}\",\n  \"lang\": \"{{lang}}\",\n  \"finalize\": true,\n  \"answers\": {{allAnswersJson}}\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/v1/tests/submit",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "v1",
                "tests",
                "submit"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Has resultId', function () { pm.expect(body.resultId).to.be.a('string'); });",
                  "if (body.resultId) { pm.collectionVariables.set('resultId', body.resultId); }",
                  "postman.setNextRequest(null);"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Admin",
      "item": [
        {
          "name": "Get Status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "status"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Response has ok flag', function () { pm.expect(body.ok).to.be.true; });"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Metrics",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/metrics",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "metrics"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                  "exec": [
                    "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                    "const body = pm.response.json();",
                    "pm.test('ok=true', function () { pm.expect(body.ok).to.eql(true); });"
                  ]
                }
              }
          ]
        }
      ]
    },
    {
      "name": "Catalog",
      "item": [
        {
          "name": "List Catalog Metrics",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/catalog/metrics",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "catalog",
                "metrics"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Includes metrics array', function () { pm.expect(body.metrics).to.be.an('array'); });"
                ]
              }
            }
          ]
        },
        {
          "name": "List Catalog Bundles",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/catalog/bundles",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "catalog",
                "bundles"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Includes bundles array', function () { pm.expect(body.bundles).to.be.an('array'); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Credits & Usage",
      "item": [
        {
          "name": "Get Credits",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/credits",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "credits"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Has credits_remaining', function () { pm.expect(body).to.have.property('credits_remaining'); });"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Usage Window",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/usage",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "usage"
              ],
              "query": [
                {
                  "key": "from",
                  "value": "2025-10-12T00:00:00Z"
                },
                {
                  "key": "to",
                  "value": "2025-10-19T00:00:00Z"
                }
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Includes credits_summary', function () { pm.expect(body).to.have.property('credits_summary'); });",
                  "pm.test('Includes usage array', function () { pm.expect(body.usage).to.be.an('array'); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Reports",
      "item": [
        {
          "name": "Create Report",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"resultId\": \"{{resultId}}\",\n  \"locale\": \"{{lang}}\",\n  \"customer_ref\": \"{{customerRef}}\",\n  \"bundles\": [\"elite\"]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
	                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
	                  "const body = pm.response.json();",
	                  "pm.test('ok=true', function () { pm.expect(body.ok).to.eql(true); });",
	                  "pm.test('Has report_id', function () { pm.expect(body.report_id).to.be.a('string'); });",
	                  "if (body.report_id) { pm.collectionVariables.set('reportId', body.report_id); }"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Report Status",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports/{{reportId}}/status",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports",
                "{{reportId}}",
                "status"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Report status present', function () { pm.expect(body).to.have.property('status'); });"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Report (Full)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports/{{reportId}}?format=full",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports",
                "{{reportId}}"
              ],
              "query": [
                {
                  "key": "format",
                  "value": "full"
                }
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Includes report payload', function () { pm.expect(body.report).to.be.an('object'); });"
                ]
              }
            }
          ]
        },
        {
          "name": "Get Report (33 Metrics)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports/{{reportId}}?format=metrics",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports",
                "{{reportId}}"
              ],
              "query": [
                {
                  "key": "format",
                  "value": "metrics"
                }
              ]
            }
          }
        },
        {
          "name": "Get Report (Organized)",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports/{{reportId}}?format=organized",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports",
                "{{reportId}}"
              ],
              "query": [
                {
                  "key": "format",
                  "value": "organized"
                }
              ]
            }
          }
        },
        {
          "name": "Get Report Filtered Metrics",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports/{{reportId}}?format=metrics&metric_keys=bounceBack,commStyle",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports",
                "{{reportId}}"
              ],
              "query": [
                {
                  "key": "format",
                  "value": "metrics"
                },
                {
                  "key": "metric_keys",
                  "value": "bounceBack,commStyle"
                }
              ]
            }
          }
        }
      ]
    },
    {
      "name": "Entitlements",
      "item": [
        {
          "name": "Unlock Report",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"bundle_ids\": [\n    \"elite\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports/{{reportId}}/unlock",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports",
                "{{reportId}}",
                "unlock"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Has bundles array', function () { pm.expect(body.bundles).to.be.an('array'); });"
                ]
              }
            }
          ]
        },
        {
          "name": "Create View Link",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"ttl_sec\": 3600\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports/{{reportId}}/view-links",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports",
                "{{reportId}}",
                "view-links"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Link returned', function () { pm.expect(body.link).to.be.a('string'); });",
                  "if (body.link) {",
                  "  const u = new URL(body.link);",
                  "  pm.collectionVariables.set('viewRid', u.searchParams.get('rid') || '');",
                  "  pm.collectionVariables.set('viewExp', u.searchParams.get('exp') || '');",
                  "  pm.collectionVariables.set('viewSig', u.searchParams.get('sig') || '');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Signed View",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/reports/view?rid={{viewRid}}&exp={{viewExp}}&sig={{viewSig}}",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "reports",
                "view"
              ],
              "query": [
                {
                  "key": "rid",
                  "value": "{{viewRid}}"
                },
                {
                  "key": "exp",
                  "value": "{{viewExp}}"
                },
                {
                  "key": "sig",
                  "value": "{{viewSig}}"
                }
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Report returned via signed link', function () { pm.expect(body.report).to.be.an('object'); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Customers",
      "item": [
        {
          "name": "Update Customer Grants",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"add\": [\n    \"elite\"\n  ],\n  \"remove\": [\n    \"basic\"\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/customers/{{customerRef}}/grants",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "customers",
                "{{customerRef}}",
                "grants"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Grants returned', function () { pm.expect(body.grants).to.be.an('array'); });"
                ]
              }
            }
          ]
        },
        {
          "name": "List Customer Reports",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/customers/{{customerRef}}/reports",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "customers",
                "{{customerRef}}",
                "reports"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Reports array returned', function () { pm.expect(body.reports).to.be.an('array'); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Engine Ingest (Dev)",
      "item": [
        {
          "name": "Ingest Result (partial)",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "X-Engine",
                "value": "b5"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"report_id\": \"{{reportId}}\",\n  \"metrics\": [\n    {\n      \"key\": \"insight_depth\",\n      \"profile\": \"numeric_index\",\n      \"score\": 3.6,\n      \"percentile\": 64,\n      \"confidence\": 0.72\n    },\n    {\n      \"key\": \"collaboration_flow\",\n      \"profile\": \"categorical_style\",\n      \"label\": \"async_anchor\",\n      \"percentile\": 58\n    },\n    {\n      \"key\": \"energy_stability\",\n      \"profile\": \"composite\",\n      \"facets\": [\n        {\n          \"facet_key\": \"weekly_consistency\",\n          \"score\": 4.0,\n          \"percentile\": 77\n        },\n        {\n          \"facet_key\": \"sprint_resilience\",\n          \"score\": 3.5\n        },\n        {\n          \"facet_key\": \"recovery_lag\",\n          \"score\": 3.0\n        }\n      ],\n      \"aggregate\": {\n        \"score\": 3.5,\n        \"trend\": \"steady\"\n      }\n    }\n  ]\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            },
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/ingest/result",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "ingest",
                "result"
              ]
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Ingest acknowledged', function () { pm.expect(body.ok).to.be.true; });",
                  "pm.test('Metrics ingested', function () { pm.expect(body.ingested_count).to.be.above(0); });",
                  "if (body.report_id) { pm.collectionVariables.set('reportId', body.report_id); }"
                ]
              }
            }
          ]
        },
        {
          "name": "Seed Values (debug)",
          "request": {
            "method": "POST",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/debug/seed-values",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "debug",
                "seed-values"
              ]
            },
            "body": {
              "mode": "raw",
              "raw": "{\"report_id\":\"{{reportId}}\"}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Status 200', function () { pm.response.to.have.status(200); });",
                  "const body = pm.response.json();",
                  "pm.test('Seeds applied', function () { pm.expect(body.metrics_count).to.equal(33); });"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "Debug",
      "item": [
        {
          "name": "Debug Ping",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/debug/ping",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "debug",
                "ping"
              ]
            }
          }
        },
        {
          "name": "Debug Smoke",
          "request": {
            "method": "GET",
            "header": [],
            "url": {
              "raw": "{{baseUrl}}/api/b5plus/v2/debug/smoke",
              "host": [
                "{{baseUrl}}"
              ],
              "path": [
                "api",
                "b5plus",
                "v2",
                "debug",
                "smoke"
              ]
            }
          }
        }
      ]
    }
  ]
}
