{
  "info": {
    "name": "Colter — purchase, delivery and customer review",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "Approved-account pilot. Import and send individual requests. Configure token and reviewer_token as private environment secrets; they are intentionally absent here. Request 3 gives a quote without execution, then inspect it before request 5. Alternatively use bounded purchase. Do not switch quote and purchase paths with one key: retain the exact payload for retries. operation_mode defaults to inspect; each write requires deliberate selection. Review is a separate customer action that may finalize a charge. Synthetic question and references must be replaced with authorized pilot inputs. A charge is not proof of collection."
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{token}}",
        "type": "string"
      }
    ]
  },
  "variable": [
    {
      "key": "base_url",
      "value": "https://api.colter.ai",
      "type": "string"
    },
    {
      "key": "workspace",
      "value": "",
      "type": "string"
    },
    {
      "key": "service_key",
      "value": "support_case_investigation",
      "type": "string"
    },
    {
      "key": "service_version",
      "value": "1",
      "type": "string"
    },
    {
      "key": "purchase_key",
      "value": "",
      "type": "string"
    },
    {
      "key": "correlation_id",
      "value": "",
      "type": "string"
    },
    {
      "key": "max_price_microcents",
      "value": "",
      "type": "string"
    },
    {
      "key": "input_payload",
      "value": "{\"question\":\"What is the appropriate next step for case 42?\"}",
      "type": "string"
    },
    {
      "key": "context_refs",
      "value": "[]",
      "type": "string"
    },
    {
      "key": "quote_key",
      "value": "",
      "type": "string"
    },
    {
      "key": "job_key",
      "value": "",
      "type": "string"
    },
    {
      "key": "submission_id",
      "value": "",
      "type": "string"
    },
    {
      "key": "operation_mode",
      "value": "inspect",
      "type": "string"
    },
    {
      "key": "review_verdict",
      "value": "",
      "type": "string"
    },
    {
      "key": "review_rationale",
      "value": "",
      "type": "string"
    }
  ],
  "item": [
    {
      "name": "1. Discover services",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          }
        ],
        "url": "{{base_url}}/api/v2/services",
        "description": "Discover services available to this workspace"
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "2. Inspect service",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          }
        ],
        "url": "{{base_url}}/api/v2/services/{{service_key}}",
        "description": "Inspect the current service contract"
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "3. Request a quote (operation_mode=quote)",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{base_url}}/api/v2/quotes",
        "description": "Request a quote without starting work",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"service_key\": \"{{service_key}}\",\n  \"service_version\": {{service_version}},\n  \"input_payload\": {{input_payload}},\n  \"idempotency_key\": \"{{purchase_key}}\",\n  \"max_price_microcents\": {{max_price_microcents}},\n  \"correlation_id\": \"{{correlation_id}}\",\n  \"context_refs\": {{context_refs}},\n  \"auto_accept\": false\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (pm.variables.get(\"operation_mode\") !== \"quote\") throw new Error(\"Select operation_mode=quote only after reviewing this action.\");",
              "for (const key of [\"purchase_key\", \"workspace\", \"max_price_microcents\", \"service_version\"]) { if (!pm.variables.get(key)) throw new Error(\"Configure and persist \" + key + \" before sending.\"); }",
              "const ceiling = Number(pm.variables.get(\"max_price_microcents\")); if (!Number.isSafeInteger(ceiling) || ceiling < 0) throw new Error(\"Price ceiling must be a nonnegative integer.\");"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "4. Inspect quote",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          }
        ],
        "url": "{{base_url}}/api/v2/quotes/{{quote_key}}",
        "description": "Inspect quote terms and expiry"
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "5. Accept reviewed quote (operation_mode=accept)",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{base_url}}/api/v2/quotes/{{quote_key}}/accept",
        "description": "Requires appropriate delegated spend authority or an authorized workspace manager. Acceptance starts the purchased job; do not accept expired or unreviewed terms."
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (pm.variables.get(\"operation_mode\") !== \"accept\") throw new Error(\"Select operation_mode=accept only after reviewing this action.\");"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "6. Observe job",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          }
        ],
        "url": "{{base_url}}/api/v2/jobs/{{job_key}}",
        "description": "Observe durable job and execution state"
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "7. Retrieve result and receipt",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          }
        ],
        "url": "{{base_url}}/api/v2/jobs/{{job_key}}/outcome",
        "description": "Execution completion is separate from customer acceptance and collection. Poll this route after interruption. Customer-reviewed pilot work remains advisory. A finalized charge is not proof that payment was collected."
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "8. Customer review (operation_mode=review)",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{base_url}}/api/v2/jobs/{{job_key}}/submissions/{{submission_id}}/resolution",
        "description": "Use only the designated reviewer's identity and the submission ID from the outcome. A machine's purchasing token does not confer customer-review authority. Acceptance can finalize the agreed charge; inconclusive requires attention. Rejection follows the service's remedy terms.",
        "auth": {
          "type": "bearer",
          "bearer": [
            {
              "key": "token",
              "value": "{{reviewer_token}}",
              "type": "string"
            }
          ]
        },
        "body": {
          "mode": "raw",
          "raw": "{{review_body}}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (pm.variables.get(\"operation_mode\") !== \"review\") throw new Error(\"Select operation_mode=review only after reviewing this action.\");",
              "if (![\"accepted\", \"rejected\", \"inconclusive\"].includes(pm.variables.get(\"review_verdict\"))) throw new Error(\"Choose the customer review verdict explicitly.\");",
              "if (!pm.variables.get(\"review_rationale\") || !pm.variables.get(\"submission_id\")) throw new Error(\"A reviewed submission and rationale are required.\");",
              "pm.variables.set(\"review_body\", JSON.stringify({verdict: pm.variables.get(\"review_verdict\"), rationale: pm.variables.get(\"review_rationale\")}));"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "9. Inspect financial ledger",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          }
        ],
        "url": "{{base_url}}/api/v2/jobs/{{job_key}}/ledger",
        "description": "Inspect financial events and reconciliation"
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    },
    {
      "name": "Alternative: bounded purchase (operation_mode=purchase)",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "X-Colter-Workspace",
            "value": "{{workspace}}"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{base_url}}/api/v2/jobs/purchase",
        "description": "Persist the key and exact payload before sending. Returns a job when auto-authorized, otherwise a quote with job null. A transport timeout does not cancel work. Resume with the same payload/key; changed fields produce a conflict. The example ceiling is not an advertised price. Required case/account/policy sources must be configured for the pilot.",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"service_key\": \"{{service_key}}\",\n  \"service_version\": {{service_version}},\n  \"input_payload\": {{input_payload}},\n  \"idempotency_key\": \"{{purchase_key}}\",\n  \"max_price_microcents\": {{max_price_microcents}},\n  \"correlation_id\": \"{{correlation_id}}\",\n  \"context_refs\": {{context_refs}}\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (pm.variables.get(\"operation_mode\") !== \"purchase\") throw new Error(\"Select operation_mode=purchase only after reviewing this action.\");",
              "for (const key of [\"purchase_key\", \"workspace\", \"max_price_microcents\", \"service_version\"]) { if (!pm.variables.get(key)) throw new Error(\"Configure and persist \" + key + \" before sending.\"); }",
              "const ceiling = Number(pm.variables.get(\"max_price_microcents\")); if (!Number.isSafeInteger(ceiling) || ceiling < 0) throw new Error(\"Price ceiling must be a nonnegative integer.\");"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Response is successful\", () => pm.expect(pm.response.code).to.be.within(200, 299));",
              "if (pm.response.code >= 200 && pm.response.code < 300) {",
              "  const body = pm.response.json();",
              "  if (body.quote?.quote_key) pm.collectionVariables.set(\"quote_key\", body.quote.quote_key);",
              "  if (body.job?.job_key) pm.collectionVariables.set(\"job_key\", body.job.job_key);",
              "  if (body.outcome?.submission?.id) pm.collectionVariables.set(\"submission_id\", String(body.outcome.submission.id));",
              "}"
            ]
          }
        }
      ]
    }
  ]
}
