Files
bifrost/tests/e2e/api/collections/bifrost-v1-inference-features.postman_collection.json
Beyhan Oğur 880f412e2c first commit
2026-04-26 21:52:23 +03:00

1913 lines
62 KiB
JSON

{
"info": {
"name": "Bifrost V1 - Inference with Bifrost Features",
"description": "Combined test suite: Async Inference, Fallbacks, Management E2E Flows, Rate Limit, Session Stickiness, and VK Governance Routing.",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
},
"variable": [
{
"key": "base_url",
"value": "http://localhost:8080",
"type": "string"
},
{
"key": "provider",
"value": "openai",
"type": "string"
},
{
"key": "chat_model",
"value": "gpt-4o",
"type": "string"
},
{
"key": "embedding_model",
"value": "text-embedding-3-small",
"type": "string"
},
{
"key": "job_id",
"value": "",
"type": "string"
},
{
"key": "embed_job_id",
"value": "",
"type": "string"
},
{
"key": "poll_retries",
"value": "0",
"type": "string"
},
{
"key": "embed_poll_retries",
"value": "0",
"type": "string"
},
{
"key": "fallback_provider",
"value": "anthropic",
"type": "string"
},
{
"key": "fallback_model",
"value": "claude-3-5-sonnet-20241022",
"type": "string"
},
{
"key": "customer_id",
"value": "",
"type": "string"
},
{
"key": "team_id",
"value": "",
"type": "string"
},
{
"key": "vk_id",
"value": "",
"type": "string"
},
{
"key": "vk_value",
"value": "",
"type": "string"
},
{
"key": "session_id",
"value": "",
"type": "string"
}
],
"item": [
{
"name": "Async Inference",
"item": [
{
"name": "Submit Chat Completion",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"pm.collectionVariables.set('poll_retries', '0');"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"if (code === 404) {",
" pm.test('Async not configured (404)', function() { pm.expect(true).to.be.true; });",
" if (typeof postman !== 'undefined' && postman.setNextRequest) {",
" postman.setNextRequest('Submit with stream (expect 400)');",
" }",
" return;",
"}",
"pm.test('Status 202', function() { pm.expect(code).to.equal(202); });",
"if (code === 202) {",
" var json = pm.response.json();",
" pm.test('Has job_id', function() { pm.expect(json.id).to.be.a('string'); });",
" pm.test('Status is pending', function() { pm.expect(json.status).to.equal('pending'); });",
" pm.collectionVariables.set('job_id', json.id);",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/async/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"async",
"chat",
"completions"
]
}
}
},
{
"name": "Poll Chat Completion",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"if (code === 404) { pm.test('Skip - async not configured', function() { pm.expect(true).to.be.true; }); return; }",
"var json = pm.response.json();",
"var status = json.status;",
"if (status === 'pending' || status === 'processing') {",
" pm.test('HTTP 202 while pending/processing', function() { pm.expect(code).to.equal(202); });",
" var retries = parseInt(pm.collectionVariables.get('poll_retries') || '0', 10);",
" if (retries < 10) {",
" pm.collectionVariables.set('poll_retries', String(retries + 1));",
" var end = Date.now() + 3000;",
" while (Date.now() < end) {}",
" if (typeof postman !== 'undefined' && postman.setNextRequest) {",
" postman.setNextRequest('Poll Chat Completion');",
" }",
" } else {",
" pm.test('Job completed or max retries', function() { pm.expect(status).to.be.oneOf(['completed', 'failed']); });",
" }",
"} else if (status === 'completed') {",
" pm.test('HTTP 200 when completed', function() { pm.expect(code).to.equal(200); });",
" pm.test('Job completed', function() { pm.expect(status).to.equal('completed'); });",
" pm.test('Has result', function() { pm.expect(json.result).to.not.be.undefined; });",
" pm.test('Result has choices with content', function() {",
" pm.expect(json.result).to.have.property('choices').that.is.an('array').and.has.length.above(0);",
" pm.expect(json.result.choices[0]).to.have.property('message');",
" pm.expect(json.result.choices[0].message).to.have.property('content').that.is.a('string');",
" });",
"} else if (status === 'failed') {",
" pm.test('HTTP 200 when failed', function() { pm.expect(code).to.equal(200); });",
" pm.test('Job failed (acceptable)', function() { pm.expect(status).to.equal('failed'); });",
"}"
]
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/v1/async/chat/completions/{{job_id}}",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"async",
"chat",
"completions",
"{{job_id}}"
]
}
}
},
{
"name": "Submit Embedding with TTL",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"pm.collectionVariables.set('embed_poll_retries', '0');"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"if (code === 404) { pm.test('Skip - async not configured', function() { pm.expect(true).to.be.true; }); return; }",
"pm.test('Status 202', function() { pm.expect(code).to.equal(202); });",
"if (code === 202) {",
" var json = pm.response.json();",
" pm.collectionVariables.set('embed_job_id', json.id);",
" pm.test('expires_at is set when TTL provided', function() { pm.expect(json.expires_at).to.not.be.undefined; });",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-async-job-result-ttl",
"value": "60"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{embedding_model}}\",\n \"input\": \"Hello world\",\n \"encoding_format\": \"float\"\n}"
},
"url": {
"raw": "{{base_url}}/v1/async/embeddings",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"async",
"embeddings"
]
}
}
},
{
"name": "Poll Embedding",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"if (code === 404) { pm.test('Skip - async not configured', function() { pm.expect(true).to.be.true; }); return; }",
"var json = pm.response.json();",
"var status = json.status;",
"if (status === 'pending' || status === 'processing') {",
" pm.test('HTTP 202 while pending/processing', function() { pm.expect(code).to.equal(202); });",
" var retries = parseInt(pm.collectionVariables.get('embed_poll_retries') || '0', 10);",
" if (retries < 10) {",
" pm.collectionVariables.set('embed_poll_retries', String(retries + 1));",
" var end = Date.now() + 3000;",
" while (Date.now() < end) {}",
" if (typeof postman !== 'undefined' && postman.setNextRequest) {",
" postman.setNextRequest('Poll Embedding');",
" }",
" }",
"} else if (status === 'completed') {",
" pm.test('HTTP 200 when completed', function() { pm.expect(code).to.equal(200); });",
" pm.test('Embedding job completed', function() { pm.expect(status).to.equal('completed'); });",
" pm.test('Result has embedding data', function() {",
" pm.expect(json.result).to.not.be.undefined;",
" pm.expect(json.result).to.have.property('data').that.is.an('array').and.has.length.above(0);",
" pm.expect(json.result.data[0]).to.have.property('embedding').that.is.an('array');",
" });",
"} else if (status === 'failed') {",
" pm.test('HTTP 200 when failed', function() { pm.expect(code).to.equal(200); });",
"}"
]
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/v1/async/embeddings/{{embed_job_id}}",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"async",
"embeddings",
"{{embed_job_id}}"
]
}
}
},
{
"name": "Submit with stream (expect 400)",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"if (code === 404) { pm.test('Skip - async not configured', function() { pm.expect(true).to.be.true; }); return; }",
"pm.test('Streaming not supported on async - expect 400', function() { pm.expect(code).to.equal(400); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"stream\": true\n}"
},
"url": {
"raw": "{{base_url}}/v1/async/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"async",
"chat",
"completions"
]
}
}
}
]
},
{
"name": "Fallbacks",
"item": [
{
"name": "Chat Completion with fallbacks",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Status is 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" var extra = json.extra_fields || {};",
" var providerUsed = extra.provider || json.provider;",
" var allowed = ['openai', 'anthropic'];",
" pm.test('Provider is openai or anthropic', function() {",
" pm.expect(providerUsed).to.be.oneOf(allowed);",
" });",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"openai/gpt-4o\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"fallbacks\": [\"anthropic/claude-3-5-sonnet-20241022\"],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Forced fallback (invalid primary)",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Status is 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" var extra = json.extra_fields || {};",
" var providerUsed = extra.provider || json.provider;",
" pm.test('Provider is openai (fallback)', function() {",
" pm.expect(String(providerUsed).toLowerCase()).to.equal('openai');",
" });",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"openai/nonexistent-model-xyz\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"fallbacks\": [\"openai/gpt-4o\"],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "All fallbacks fail",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Status is non-2xx', function() { pm.expect(code).to.not.be.within(200, 299); });",
"if (code >= 400) {",
" try {",
" var json = pm.response.json();",
" var msg = (json.error && json.error.message) ? json.error.message : (json.message || '');",
" pm.test('Error response has message', function() {",
" pm.expect(msg).to.be.a('string').and.not.be.empty;",
" });",
" } catch (e) {}",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"openai/nonexistent-1\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"fallbacks\": [\"openai/nonexistent-2\"],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
}
]
},
{
"name": "Management Flows",
"item": [
{
"name": "Flow A - List Providers",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('List Providers returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/providers",
"host": [
"{{base_url}}"
],
"path": [
"api",
"providers"
]
}
}
},
{
"name": "Flow A - List Keys",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('List Keys returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{base_url}}/api/keys",
"host": [
"{{base_url}}"
],
"path": [
"api",
"keys"
]
}
}
},
{
"name": "Flow A - Chat Completion",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Chat Completion returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi\"}],\n \"max_completion_tokens\": 5,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Flow B - Create Customer",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"var body = { name: 'Mgmt Flow Customer ' + Date.now(), email: 'mgmt@example.com' };",
"pm.request.body.raw = JSON.stringify(body);"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Create Customer returns 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" pm.test('Response contains customer object', function() { pm.expect(json.customer || json).to.be.an('object'); });",
" var c = json.customer || json;",
" pm.test('Customer has non-empty id', function() { pm.expect(c.id).to.be.a('string').and.not.be.empty; });",
" if (c.id) pm.collectionVariables.set('customer_id', c.id);",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "{{base_url}}/api/governance/customers",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"customers"
]
}
}
},
{
"name": "Flow B - Create Team",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"var cid = pm.collectionVariables.get('customer_id');",
"var body = { name: 'Mgmt Flow Team ' + Date.now() };",
"if (cid) body.customer_id = cid;",
"pm.request.body.raw = JSON.stringify(body);"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Create Team returns 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" pm.test('Response contains team object', function() { pm.expect(json.team || json).to.be.an('object'); });",
" var t = json.team || json;",
" pm.test('Team has non-empty id', function() { pm.expect(t.id).to.be.a('string').and.not.be.empty; });",
" if (t.id) pm.collectionVariables.set('team_id', t.id);",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "{{base_url}}/api/governance/teams",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"teams"
]
}
}
},
{
"name": "Flow B - Create VK",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"var tid = pm.collectionVariables.get('team_id');",
"var body = { name: 'Mgmt Flow VK ' + Date.now() };",
"if (tid) body.team_id = tid;",
"pm.request.body.raw = JSON.stringify(body);"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Create VK returns 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" var vk = json.virtual_key || json;",
" pm.test('Response contains VK object', function() { pm.expect(vk).to.be.an('object'); });",
" pm.test('VK has non-empty id', function() { pm.expect(vk.id).to.be.a('string').and.not.be.empty; });",
" pm.test('VK value has sk-bf- prefix', function() { pm.expect(vk.value).to.match(/^sk-bf-/); });",
" if (vk.id) pm.collectionVariables.set('vk_id', vk.id);",
" if (vk.value) pm.collectionVariables.set('vk_value', vk.value);",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys"
]
}
}
},
{
"name": "Flow B - Chat Completion with VK",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Chat with VK returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi\"}],\n \"max_completion_tokens\": 5,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Flow B - Delete VK",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Delete VK returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys/{{vk_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys",
"{{vk_id}}"
]
}
}
},
{
"name": "Flow B - Delete Team",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Delete Team returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "{{base_url}}/api/governance/teams/{{team_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"teams",
"{{team_id}}"
]
}
}
},
{
"name": "Flow B - Delete Customer",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Delete Customer returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "{{base_url}}/api/governance/customers/{{customer_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"customers",
"{{customer_id}}"
]
}
}
},
{
"name": "Flow C - Create VK",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"var body = { name: 'Lifecycle VK ' + Date.now() };",
"pm.request.body.raw = JSON.stringify(body);"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Create VK returns 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" var vk = json.virtual_key || json;",
" pm.test('Response contains VK object', function() { pm.expect(vk).to.be.an('object'); });",
" pm.test('VK has non-empty id', function() { pm.expect(vk.id).to.be.a('string').and.not.be.empty; });",
" pm.test('VK value has sk-bf- prefix', function() { pm.expect(vk.value).to.match(/^sk-bf-/); });",
" if (vk.id) pm.collectionVariables.set('vk_id', vk.id);",
" if (vk.value) pm.collectionVariables.set('vk_value', vk.value);",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys"
]
}
}
},
{
"name": "Flow C - Chat Completion with VK",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Chat with VK returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi\"}],\n \"max_completion_tokens\": 5,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Flow C - Update VK (rename)",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"pm.request.body.raw = JSON.stringify({ name: 'Lifecycle VK Renamed ' + Date.now() });"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Update VK returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys/{{vk_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys",
"{{vk_id}}"
]
}
}
},
{
"name": "Flow C - Chat Completion after rename",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Chat after rename returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi\"}],\n \"max_completion_tokens\": 5,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Flow C - Deactivate VK",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"pm.request.body.raw = JSON.stringify({ is_active: false });"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Deactivate VK returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "PUT",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys/{{vk_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys",
"{{vk_id}}"
]
}
}
},
{
"name": "Flow C - Chat with deactivated VK (expect 403)",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Deactivated VK returns 403', function() { pm.expect(code).to.equal(403); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi\"}],\n \"max_completion_tokens\": 5,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Flow C - Delete VK",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Delete VK returns 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys/{{vk_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys",
"{{vk_id}}"
]
}
}
}
]
},
{
"name": "Rate Limit",
"item": [
{
"name": "Setup - Create VK with rate limit",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"var ts = Date.now();",
"var body = {",
" name: 'Rate Limit Test VK ' + ts,",
" rate_limit: {",
" request_max_limit: 2,",
" request_reset_duration: '1m'",
" }",
"};",
"pm.request.body.raw = JSON.stringify(body);"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Create VK returns 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" var vk = json.virtual_key || json;",
" pm.test('Response contains VK object', function() { pm.expect(vk).to.be.an('object'); });",
" pm.test('VK has non-empty id', function() { pm.expect(vk.id).to.be.a('string').and.not.be.empty; });",
" pm.test('VK value has sk-bf- prefix', function() { pm.expect(vk.value).to.match(/^sk-bf-/); });",
" if (vk.id) pm.collectionVariables.set('vk_id', vk.id);",
" if (vk.value) pm.collectionVariables.set('vk_value', vk.value);",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys"
]
}
}
},
{
"name": "Chat Completion #1",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Request 1: 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi\"}],\n \"max_completion_tokens\": 5,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Chat Completion #2",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Request 2: 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi\"}],\n \"max_completion_tokens\": 5,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Chat Completion #3 (expect 429)",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Request 3: 429 rate limited', function() { pm.expect(code).to.equal(429); });",
"if (code === 429) {",
" var json = pm.response.json();",
" var errType = (json.type || (json.error && json.error.type) || '').toString();",
" if (errType) {",
" pm.test('Error type indicates rate limit', function() {",
" pm.expect(errType).to.match(/request_limited|rate_limited|token_limited/);",
" });",
" }",
" pm.test('Error has message', function() {",
" pm.expect(json.error).to.be.an('object');",
" pm.expect(json.error.message).to.be.a('string').and.not.be.empty;",
" });",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hi\"}],\n \"max_completion_tokens\": 5,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Teardown - Delete VK",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var vkId = pm.collectionVariables.get('vk_id');",
"if (!vkId) { pm.test('Teardown skipped - no VK to delete', function() { pm.expect(true).to.be.true; }); return; }",
"var code = pm.response.code;",
"pm.test('Delete VK returns 2xx', function() { pm.expect(code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys/{{vk_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys",
"{{vk_id}}"
]
}
}
}
]
},
{
"name": "Session Stickiness",
"item": [
{
"name": "Chat Completion with session ID",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"var sid = 'test-session-' + Date.now();",
"pm.collectionVariables.set('session_id', sid);"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Status is 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-session-id",
"value": "{{session_id}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Chat Completion with same session ID",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Status is 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-session-id",
"value": "{{session_id}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Chat Completion with different session ID",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Status is 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-session-id",
"value": "test-session-other-{{$timestamp}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Chat Completion with session TTL",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"pm.test('Status is 2xx', function() { pm.expect(pm.response.code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-session-id",
"value": "test-session-ttl"
},
{
"key": "x-bf-session-ttl",
"value": "60"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
}
]
},
{
"name": "VK Routing",
"item": [
{
"name": "Setup - Create VK with provider config",
"event": [
{
"listen": "prerequest",
"script": {
"type": "text/javascript",
"exec": [
"var ts = Date.now();",
"var body = {",
" name: 'Routing Test VK ' + ts,",
" provider_configs: [{",
" provider: pm.collectionVariables.get('provider') || 'openai',",
" weight: 1.0,",
" allowed_models: [pm.collectionVariables.get('chat_model') || 'gpt-4o']",
" }]",
"};",
"pm.request.body.raw = JSON.stringify(body);"
]
}
},
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Create VK returns 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" var vk = json.virtual_key || json;",
" pm.test('Response contains VK object', function() { pm.expect(vk).to.be.an('object'); });",
" pm.test('VK has non-empty id', function() { pm.expect(vk.id).to.be.a('string').and.not.be.empty; });",
" pm.test('VK value has sk-bf- prefix', function() { pm.expect(vk.value).to.match(/^sk-bf-/); });",
" if (vk.id) pm.collectionVariables.set('vk_id', vk.id);",
" if (vk.value) pm.collectionVariables.set('vk_value', vk.value);",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{}"
},
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys"
]
}
}
},
{
"name": "Chat Completion - model without provider prefix",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Status is 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" var extra = json.extra_fields || {};",
" var providerUsed = extra.provider;",
" var expected = (pm.collectionVariables.get('provider') || 'openai').toLowerCase();",
" pm.test('Provider matches VK config', function() {",
" pm.expect(String(providerUsed).toLowerCase()).to.equal(expected);",
" });",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Chat Completion - explicit provider prefix",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Status is 2xx', function() { pm.expect(code).to.be.within(200, 299); });",
"if (code >= 200 && code <= 299) {",
" var json = pm.response.json();",
" var extra = json.extra_fields || {};",
" var providerUsed = extra.provider;",
" var expected = (pm.collectionVariables.get('provider') || 'openai').toLowerCase();",
" pm.test('Provider matches VK config (explicit prefix)', function() {",
" pm.expect(String(providerUsed).toLowerCase()).to.equal(expected);",
" });",
"}"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"{{provider}}/{{chat_model}}\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Chat Completion - blocked model (expect 403)",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var code = pm.response.code;",
"pm.test('Model blocked - expect 4xx', function() { pm.expect(code).to.be.oneOf([400, 403]); });"
]
}
}
],
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "x-bf-vk",
"value": "{{vk_value}}"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"model\": \"nonexistent-model\",\n \"messages\": [{\"role\": \"user\", \"content\": \"Hello\"}],\n \"max_completion_tokens\": 10,\n \"stream\": false\n}"
},
"url": {
"raw": "{{base_url}}/v1/chat/completions",
"host": [
"{{base_url}}"
],
"path": [
"v1",
"chat",
"completions"
]
}
}
},
{
"name": "Teardown - Delete VK",
"event": [
{
"listen": "test",
"script": {
"type": "text/javascript",
"exec": [
"var vkId = pm.collectionVariables.get('vk_id');",
"if (!vkId) { pm.test('Teardown skipped - no VK to delete', function() { pm.expect(true).to.be.true; }); return; }",
"var code = pm.response.code;",
"pm.test('Delete VK returns 2xx', function() { pm.expect(code).to.be.within(200, 299); });"
]
}
}
],
"request": {
"method": "DELETE",
"header": [],
"url": {
"raw": "{{base_url}}/api/governance/virtual-keys/{{vk_id}}",
"host": [
"{{base_url}}"
],
"path": [
"api",
"governance",
"virtual-keys",
"{{vk_id}}"
]
}
}
}
]
}
]
}