{
  "info": {
    "name": "Ordinavo Connect",
    "description": "Postman collection for Ordinavo Connect API v1: health, inbound targets, customer mapping, batch imports, import jobs, route suggestions, webhook payload examples and HMAC signature verification.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    { "key": "baseUrl", "value": "https://ordinavo.de/api/connect/v1" },
    { "key": "apiKey", "value": "<your-api-key>" },
    { "key": "webhookSecret", "value": "<your-webhook-secret>" },
    { "key": "webhookReceiverUrl", "value": "http://localhost:5005" },
    { "key": "importJobId", "value": "" },
    { "key": "targetId", "value": "" },
    { "key": "routeSuggestionId", "value": "" },
    { "key": "customerExternalId", "value": "CUST-10042" },
    { "key": "locationExternalId", "value": "LOC-ESSEN-01" },
    { "key": "contactExternalId", "value": "CONT-44" },
    { "key": "targetExternalId", "value": "JOB-2026-000918" },
    { "key": "idempotencyKey", "value": "" },
    { "key": "computedSignature", "value": "" }
  ],
  "item": [
    {
      "name": "01 Health",
      "item": [
        {
          "name": "Health",
          "request": {
            "method": "GET",
            "header": [
              { "key": "Authorization", "value": "Bearer {{apiKey}}" }
            ],
            "url": "{{baseUrl}}/integration/health"
          }
        }
      ]
    },
    {
      "name": "02 Inbound Targets",
      "item": [
        {
          "name": "Minimal Import",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "",
                  "if (json.importJobId) {",
                  "  pm.environment.set(\"importJobId\", json.importJobId);",
                  "}",
                  "",
                  "if (json.items && json.items.length && json.items[0].targetId) {",
                  "  pm.environment.set(\"targetId\", json.items[0].targetId);",
                  "}",
                  "",
                  "pm.test(\"Import accepted\", function () {",
                  "  pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Authorization", "value": "Bearer {{apiKey}}" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "Idempotency-Key", "value": "{{$guid}}" }
            ],
            "url": "{{baseUrl}}/inbound/targets",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"externalId\": \"{{targetExternalId}}\",\n  \"title\": \"Maintenance visit\",\n  \"description\": \"Check refrigeration unit and document status.\",\n  \"location\": {\n    \"name\": \"Essen Center\",\n    \"street\": \"Hachestrasse 12\",\n    \"postalCode\": \"45127\",\n    \"city\": \"Essen\",\n    \"country\": \"DE\",\n    \"latitude\": 51.451,\n    \"longitude\": 7.012\n  },\n  \"planning\": {\n    \"priority\": \"High\",\n    \"estimatedWorkMinutes\": 45,\n    \"routeDate\": \"2026-07-01\"\n  }\n}"
            }
          }
        }
      ]
    },
    {
      "name": "03 Customer Mapping",
      "item": [
        {
          "name": "Import with Customer Context",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test(\"Response has import job or target id\", function () {",
                  "  const json = pm.response.json();",
                  "  pm.expect(json).to.be.an(\"object\");",
                  "  pm.expect(Boolean(json.importJobId || json.targetId || (json.items && json.items.length))).to.eql(true);",
                  "});",
                  "",
                  "pm.test(\"Customer mapping status is present when returned\", function () {",
                  "  const json = pm.response.json();",
                  "  const firstItem = json.items && json.items.length ? json.items[0] : json;",
                  "  if (firstItem.customerMapping) {",
                  "    pm.expect(firstItem.customerMapping.status).to.be.a(\"string\");",
                  "  }",
                  "});",
                  "",
                  "const json = pm.response.json();",
                  "if (json.importJobId) { pm.environment.set(\"importJobId\", json.importJobId); }",
                  "if (json.items && json.items.length && json.items[0].targetId) { pm.environment.set(\"targetId\", json.items[0].targetId); }"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Authorization", "value": "Bearer {{apiKey}}" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "Idempotency-Key", "value": "{{$guid}}" }
            ],
            "url": "{{baseUrl}}/inbound/targets",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"externalId\": \"{{targetExternalId}}\",\n  \"title\": \"Maintenance visit\",\n  \"description\": \"Check refrigeration unit and document status.\",\n  \"customer\": {\n    \"externalId\": \"{{customerExternalId}}\",\n    \"customerNumber\": \"RRM-001\",\n    \"name\": \"Rhein-Ruhr Medical Supply\"\n  },\n  \"location\": {\n    \"externalId\": \"{{locationExternalId}}\",\n    \"name\": \"Essen Center\",\n    \"street\": \"Hachestrasse 12\",\n    \"postalCode\": \"45127\",\n    \"city\": \"Essen\",\n    \"country\": \"DE\",\n    \"latitude\": 51.451,\n    \"longitude\": 7.012,\n    \"defaultEstimatedWorkMinutes\": 45,\n    \"defaultPriority\": \"High\"\n  },\n  \"contact\": {\n    \"externalId\": \"{{contactExternalId}}\",\n    \"displayName\": \"Anna Weber\",\n    \"role\": \"Operations Manager\",\n    \"email\": \"anna.weber@example.com\",\n    \"phone\": \"+49 201 123456\"\n  },\n  \"planning\": {\n    \"priority\": \"High\",\n    \"estimatedWorkMinutes\": 45,\n    \"routeDate\": \"2026-07-01\",\n    \"timeWindowStartUtc\": \"2026-07-01T08:00:00Z\",\n    \"timeWindowEndUtc\": \"2026-07-01T14:00:00Z\"\n  },\n  \"customFields\": {\n    \"serviceType\": \"Maintenance\",\n    \"assetId\": \"FRIDGE-221\"\n  }\n}"
            }
          }
        }
      ]
    },
    {
      "name": "04 Batch Import",
      "item": [
        {
          "name": "Batch Import with Multiple Customers",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "",
                  "if (json.importJobId) {",
                  "  pm.environment.set(\"importJobId\", json.importJobId);",
                  "}",
                  "",
                  "pm.test(\"Batch accepted\", function () {",
                  "  pm.expect(pm.response.code).to.be.oneOf([200, 202]);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Authorization", "value": "Bearer {{apiKey}}" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "Idempotency-Key", "value": "{{$guid}}" }
            ],
            "url": "{{baseUrl}}/inbound/targets/batch",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"batchId\": \"BATCH-2026-07-01-AM\",\n  \"operation\": \"upsert\",\n  \"targets\": [\n    {\n      \"externalId\": \"JOB-2026-000918\",\n      \"title\": \"Maintenance visit\",\n      \"customer\": {\n        \"externalId\": \"CUST-10042\",\n        \"customerNumber\": \"RRM-001\",\n        \"name\": \"Rhein-Ruhr Medical Supply\"\n      },\n      \"location\": {\n        \"externalId\": \"LOC-ESSEN-01\",\n        \"name\": \"Essen Center\",\n        \"city\": \"Essen\",\n        \"country\": \"DE\",\n        \"latitude\": 51.451,\n        \"longitude\": 7.012\n      },\n      \"planning\": {\n        \"priority\": \"High\",\n        \"estimatedWorkMinutes\": 45\n      }\n    },\n    {\n      \"externalId\": \"JOB-2026-000919\",\n      \"title\": \"Branch inspection\",\n      \"customer\": {\n        \"externalId\": \"CUST-20019\",\n        \"customerNumber\": \"BR-019\",\n        \"name\": \"Berg Retail Group\"\n      },\n      \"location\": {\n        \"externalId\": \"LOC-BOCHUM-02\",\n        \"name\": \"Bochum Store\",\n        \"city\": \"Bochum\",\n        \"country\": \"DE\",\n        \"latitude\": 51.481,\n        \"longitude\": 7.216\n      },\n      \"planning\": {\n        \"priority\": \"Normal\",\n        \"estimatedWorkMinutes\": 30\n      }\n    }\n  ]\n}"
            }
          }
        }
      ]
    },
    {
      "name": "05 Import Jobs",
      "item": [
        {
          "name": "Import Job Details",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "",
                  "pm.test(\"Import job has status\", function () {",
                  "  pm.expect(json.status).to.be.a(\"string\");",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "GET",
            "header": [
              { "key": "Authorization", "value": "Bearer {{apiKey}}" }
            ],
            "url": "{{baseUrl}}/import-jobs/{{importJobId}}"
          }
        }
      ]
    },
    {
      "name": "06 Route Suggestions",
      "item": [
        {
          "name": "Route Suggestion from Import Job",
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const json = pm.response.json();",
                  "if (json.routeSuggestionId) {",
                  "  pm.environment.set(\"routeSuggestionId\", json.routeSuggestionId);",
                  "}",
                  "",
                  "pm.test(\"Route suggestion request accepted\", function () {",
                  "  pm.expect(pm.response.code).to.be.oneOf([200, 201, 202]);",
                  "});"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Authorization", "value": "Bearer {{apiKey}}" },
              { "key": "Content-Type", "value": "application/json" },
              { "key": "Idempotency-Key", "value": "{{$guid}}" }
            ],
            "url": "{{baseUrl}}/import-jobs/{{importJobId}}/route-suggestion",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"routeDate\": \"2026-07-01\",\n  \"employeeId\": null,\n  \"maxStops\": 8\n}"
            }
          }
        }
      ]
    },
    {
      "name": "07 Webhook Payload Examples",
      "item": [
        {
          "name": "visit_report.approved",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-Ordinavo-Event-Id", "value": "evt_01JZ8Y4EXAMPLE" },
              { "key": "X-Ordinavo-Event-Type", "value": "visit_report.approved" }
            ],
            "url": "{{webhookReceiverUrl}}/ordinavo/webhooks",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"eventId\": \"evt_01JZ8Y4EXAMPLE\",\n  \"eventType\": \"visit_report.approved\",\n  \"occurredAt\": \"2026-06-18T16:40:00Z\",\n  \"payloadVersion\": \"2026-06-18\",\n  \"customer\": {\n    \"ordinavoCustomerId\": 12,\n    \"externalId\": \"CUST-10042\",\n    \"customerNumber\": \"RRM-001\",\n    \"name\": \"Rhein-Ruhr Medical Supply\"\n  },\n  \"location\": {\n    \"ordinavoLocationId\": 34,\n    \"externalId\": \"LOC-ESSEN-01\",\n    \"name\": \"Essen Center\",\n    \"city\": \"Essen\",\n    \"country\": \"DE\",\n    \"hasCoordinates\": true\n  },\n  \"visitReport\": {\n    \"id\": 901,\n    \"title\": \"Maintenance visit - Essen Center\",\n    \"status\": \"Approved\",\n    \"result\": \"Successful\",\n    \"isBillable\": true,\n    \"billingStatus\": \"Pending\"\n  },\n  \"target\": {\n    \"id\": 455,\n    \"externalId\": \"JOB-2026-000918\",\n    \"title\": \"Maintenance visit\"\n  }\n}"
            }
          }
        },
        {
          "name": "visit_report.follow_up_required",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-Ordinavo-Event-Id", "value": "evt_01JZ8Y5EXAMPLE" },
              { "key": "X-Ordinavo-Event-Type", "value": "visit_report.follow_up_required" }
            ],
            "url": "{{webhookReceiverUrl}}/ordinavo/webhooks",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"eventId\": \"evt_01JZ8Y5EXAMPLE\",\n  \"eventType\": \"visit_report.follow_up_required\",\n  \"occurredAt\": \"2026-06-18T16:45:00Z\",\n  \"customer\": {\n    \"ordinavoCustomerId\": 12,\n    \"externalId\": \"CUST-10042\",\n    \"customerNumber\": \"RRM-001\",\n    \"name\": \"Rhein-Ruhr Medical Supply\"\n  },\n  \"location\": {\n    \"ordinavoLocationId\": 34,\n    \"externalId\": \"LOC-ESSEN-01\",\n    \"name\": \"Essen Center\"\n  },\n  \"visitReport\": {\n    \"id\": 901,\n    \"status\": \"Approved\",\n    \"result\": \"IssueFound\",\n    \"followUpRequired\": true,\n    \"followUpDueDate\": \"2026-07-02\",\n    \"followUpReason\": \"Replacement part required\"\n  }\n}"
            }
          }
        },
        {
          "name": "billing.event_created",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-Ordinavo-Event-Id", "value": "evt_01JZ8Y6EXAMPLE" },
              { "key": "X-Ordinavo-Event-Type", "value": "billing.event_created" }
            ],
            "url": "{{webhookReceiverUrl}}/ordinavo/webhooks",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"eventId\": \"evt_01JZ8Y6EXAMPLE\",\n  \"eventType\": \"billing.event_created\",\n  \"occurredAt\": \"2026-06-18T16:50:00Z\",\n  \"payloadVersion\": \"2026-06-18\",\n  \"customer\": {\n    \"ordinavoCustomerId\": 12,\n    \"externalId\": \"CUST-10042\",\n    \"customerNumber\": \"RRM-001\",\n    \"name\": \"Rhein-Ruhr Medical Supply\"\n  },\n  \"billingEvent\": {\n    \"id\": 3001,\n    \"status\": \"Pending\",\n    \"sourceType\": \"VisitReport\",\n    \"visitReportId\": 901,\n    \"targetId\": 455,\n    \"appointmentId\": 1201\n  }\n}"
            }
          }
        },
        {
          "name": "appointment.completed",
          "request": {
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-Ordinavo-Event-Id", "value": "evt_01JZ8Y7EXAMPLE" },
              { "key": "X-Ordinavo-Event-Type", "value": "appointment.completed" }
            ],
            "url": "{{webhookReceiverUrl}}/ordinavo/webhooks",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"eventId\": \"evt_01JZ8Y7EXAMPLE\",\n  \"eventType\": \"appointment.completed\",\n  \"occurredAt\": \"2026-06-18T15:30:00Z\",\n  \"customer\": {\n    \"ordinavoCustomerId\": 12,\n    \"externalId\": \"CUST-10042\",\n    \"customerNumber\": \"RRM-001\",\n    \"name\": \"Rhein-Ruhr Medical Supply\"\n  },\n  \"target\": {\n    \"id\": 455,\n    \"externalId\": \"JOB-2026-000918\",\n    \"title\": \"Maintenance visit\"\n  },\n  \"appointment\": {\n    \"id\": 1201,\n    \"status\": \"Completed\"\n  }\n}"
            }
          }
        }
      ]
    },
    {
      "name": "08 Webhook Signature Verification",
      "item": [
        {
          "name": "Signed Webhook Delivery Demo",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const secret = pm.environment.get(\"webhookSecret\");",
                  "const rawBody = pm.request.body.raw || \"\";",
                  "const hash = CryptoJS.HmacSHA256(rawBody, secret).toString(CryptoJS.enc.Hex);",
                  "pm.environment.set(\"computedSignature\", \"sha256=\" + hash);"
                ]
              }
            }
          ],
          "request": {
            "method": "POST",
            "header": [
              { "key": "Content-Type", "value": "application/json" },
              { "key": "X-Ordinavo-Event-Id", "value": "evt_01JZ8Y4EXAMPLE" },
              { "key": "X-Ordinavo-Event-Type", "value": "visit_report.approved" },
              { "key": "X-Ordinavo-Timestamp", "value": "2026-06-18T16:40:00Z" },
              { "key": "X-Ordinavo-Signature", "value": "{{computedSignature}}" }
            ],
            "url": "{{webhookReceiverUrl}}/ordinavo/webhooks",
            "body": {
              "mode": "raw",
              "raw": "{\n  \"eventId\": \"evt_01JZ8Y4EXAMPLE\",\n  \"eventType\": \"visit_report.approved\",\n  \"occurredAt\": \"2026-06-18T16:40:00Z\",\n  \"payloadVersion\": \"2026-06-18\",\n  \"customer\": {\n    \"ordinavoCustomerId\": 12,\n    \"externalId\": \"CUST-10042\",\n    \"customerNumber\": \"RRM-001\",\n    \"name\": \"Rhein-Ruhr Medical Supply\"\n  },\n  \"visitReport\": {\n    \"id\": 901,\n    \"status\": \"Approved\",\n    \"result\": \"Successful\"\n  }\n}"
            }
          }
        }
      ]
    }
  ]
}
