{
  "info": {
    "name": "PrintHook v1 \u2014 guided raw HTTP",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "Manual guided requests. Configure a 20000 ms request timeout and disable automatic redirects in Postman Settings. Imports contain no secrets. Mutations are blocked until allow_mutations=true. Creating a job can print on real hardware. No automatic loops. Save the generated webhook secret directly to your secret manager; this collection deliberately does not capture it."
  },
  "auth": {
    "type": "bearer",
    "bearer": [
      {
        "key": "token",
        "value": "{{api_key}}",
        "type": "string"
      }
    ]
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "if (!pm.environment.get(\"api_key\")) { pm.execution.skipRequest(); throw new Error(\"Set a private local api_key value before sending\"); }",
          "if (!/^https:\\/\\//.test(pm.environment.get(\"api_url\") || \"\")) { pm.execution.skipRequest(); throw new Error(\"Use a trusted HTTPS API origin\"); }"
        ]
      }
    }
  ],
  "item": [
    {
      "name": "01 Check identity",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/me",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print."
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(200));"
            ]
          }
        }
      ]
    },
    {
      "name": "02 Discover limits",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/meta",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print."
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(200));"
            ]
          }
        }
      ]
    },
    {
      "name": "03 List online printers \u2014 choose one manually",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/printers?status=online&limit=25",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print."
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(200));"
            ]
          }
        }
      ]
    },
    {
      "name": "04 Create PDF job \u2014 REAL PRINT",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          },
          {
            "key": "Idempotency-Key",
            "value": "{{idempotency_key}}"
          }
        ],
        "url": "{{api_url}}/v1/jobs",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print.",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"printer_id\": \"{{printer_id}}\",\n  \"title\": \"Postman example\",\n  \"source\": \"postman\",\n  \"content\": {\n    \"type\": \"pdf\",\n    \"url\": \"{{document_url}}\"\n  }\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (pm.environment.get(\"allow_mutations\") !== \"true\") { pm.execution.skipRequest(); throw new Error(\"Set allow_mutations=true only after reviewing the target and side effects\"); }",
              "if (!pm.environment.get(\"printer_id\") || pm.environment.get(\"printer_id\").startsWith(\"replace-\")) { pm.execution.skipRequest(); throw new Error(\"Set printer_id before sending\"); }",
              "if (!pm.environment.get(\"document_url\") || pm.environment.get(\"document_url\").startsWith(\"replace-\")) { pm.execution.skipRequest(); throw new Error(\"Set document_url before sending\"); }",
              "if (!pm.environment.get(\"idempotency_key\") || pm.environment.get(\"idempotency_key\").startsWith(\"replace-\")) { pm.execution.skipRequest(); throw new Error(\"Set idempotency_key before sending\"); }"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(201));",
              "if (pm.response.code === 201) pm.environment.set(\"job_id\", pm.response.json().id);"
            ]
          }
        }
      ]
    },
    {
      "name": "05 Read job \u2014 single poll",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/jobs/{{job_id}}",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print."
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (!pm.environment.get(\"job_id\") || pm.environment.get(\"job_id\").startsWith(\"replace-\")) { pm.execution.skipRequest(); throw new Error(\"Set job_id before sending\"); }"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(200));",
              "if (pm.response.code === 200) pm.test(\"Terminal is boolean\", () => pm.expect(pm.response.json().terminal).to.be.a(\"boolean\"));"
            ]
          }
        }
      ]
    },
    {
      "name": "06 Read job timeline",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/jobs/{{job_id}}/timeline",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print."
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (!pm.environment.get(\"job_id\") || pm.environment.get(\"job_id\").startsWith(\"replace-\")) { pm.execution.skipRequest(); throw new Error(\"Set job_id before sending\"); }"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(200));"
            ]
          }
        }
      ]
    },
    {
      "name": "07 Event catalog",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/event-types",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print."
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(200));"
            ]
          }
        }
      ]
    },
    {
      "name": "08 List job events",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/events?type=job.*&order=asc&limit=25",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print."
      },
      "event": [
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(200));"
            ]
          }
        }
      ]
    },
    {
      "name": "09 Create signed webhook \u2014 REAL SUBSCRIPTION",
      "request": {
        "method": "POST",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          },
          {
            "key": "Content-Type",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/webhooks",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print.",
        "body": {
          "mode": "raw",
          "raw": "{\n  \"url\": \"{{webhook_url}}\",\n  \"event_types\": [\n    \"job.*\"\n  ]\n}",
          "options": {
            "raw": {
              "language": "json"
            }
          }
        }
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (pm.environment.get(\"allow_mutations\") !== \"true\") { pm.execution.skipRequest(); throw new Error(\"Set allow_mutations=true only after reviewing the target and side effects\"); }",
              "if (!pm.environment.get(\"webhook_url\") || pm.environment.get(\"webhook_url\").startsWith(\"replace-\")) { pm.execution.skipRequest(); throw new Error(\"Set webhook_url before sending\"); }"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(201));",
              "if (pm.response.code === 201) pm.environment.set(\"webhook_id\", pm.response.json().id);"
            ]
          }
        }
      ]
    },
    {
      "name": "10 List webhook deliveries",
      "request": {
        "method": "GET",
        "header": [
          {
            "key": "Accept",
            "value": "application/json"
          }
        ],
        "url": "{{api_url}}/v1/webhook-deliveries?webhook_id={{webhook_id}}&limit=25",
        "description": "Send manually. No automatic retry or polling loop. Never change the saved key/body to retry an uncertain print."
      },
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "if (!pm.environment.get(\"webhook_id\") || pm.environment.get(\"webhook_id\").startsWith(\"replace-\")) { pm.execution.skipRequest(); throw new Error(\"Set webhook_id before sending\"); }"
            ]
          }
        },
        {
          "listen": "test",
          "script": {
            "type": "text/javascript",
            "exec": [
              "pm.test(\"Expected HTTP status\", () => pm.expect(pm.response.code).to.eql(200));"
            ]
          }
        }
      ]
    }
  ]
}
