{
  "auth": {
    "apikey": [
      {
        "key": "key",
        "type": "string",
        "value": "X-API-Key"
      },
      {
        "key": "value",
        "type": "string",
        "value": "{{api_key}}"
      },
      {
        "key": "in",
        "type": "string",
        "value": "header"
      }
    ],
    "type": "apikey"
  },
  "info": {
    "_postman_id": "secretag-integrations-v1",
    "description": "Server-to-server endpoints of the SecreTag API, plus sandbox endpoints for testing with the tags assigned to you. The OpenAPI document at https://docs.secretag.co/openapi.json is the contract; every request description here is taken from it.\n\n## Setup\n1. Set `api_key` to your key. Keys are issued by SecreTag support (support@secretag.co): `st_test_...` for sandbox-api.secretag.co, `st_live_...` for api.secretag.co. A key on the other host answers 401.\n2. Set `base_url` to `https://sandbox-api.secretag.co` (sandbox) or `https://api.secretag.co` (production).\n3. For sandbox requests, set `sandbox_tag_id` to the printed ID of a tag assigned to you for testing (for example `093-8PDZ`).\n\nThe `X-API-Key` header is applied at collection level: every request inherits it.",
    "name": "SecreTag Integrations API",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "item": [
    {
      "description": "Your organization's tags: list, detail, journey, evidence, disputes and updates.",
      "item": [
        {
          "name": "List Tags",
          "request": {
            "description": "List your organization's tags.\n\nYour organization's tags with their last known location. Filters: `state`, `search`, `order_id` and `include_archived`. Only the filters documented here are forwarded; any other query parameter is ignored. `page` is 1-based (default 1) and `limit` is 1 to 200 (default 50); any other value answers 400. `pagination` counts only your organization's items. A filter that matches more than 5,000 items on the tracking network, or a list that takes more than 20 seconds to read, answers 503 `List too large, add filters`: narrow the filters and retry.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "tags"
              ],
              "query": [
                {
                  "description": "Page number, 1-based. Default 1.",
                  "key": "page",
                  "value": "1"
                },
                {
                  "description": "Items per page, 1 to 200. Default 50.",
                  "key": "limit",
                  "value": "50"
                },
                {
                  "description": "Lifecycle state: `awaiting_first_ping`, `at_origin`, `in_transit`, `approaching`, `delivered`, `delivery_verification`, `disputed_in_transit` or `completed`.",
                  "disabled": true,
                  "key": "state",
                  "value": ""
                },
                {
                  "description": "Free-text search across the tag's printed ID, recipient name and email, and order ID.",
                  "disabled": true,
                  "key": "search",
                  "value": ""
                },
                {
                  "description": "Exact order ID.",
                  "disabled": true,
                  "key": "order_id",
                  "value": ""
                }
              ],
              "raw": "{{base_url}}/v1/integrations/tags?page=1&limit=50"
            }
          }
        },
        {
          "name": "Get Tag",
          "request": {
            "description": "Get one of your tags.\n\nThe tag with `ping_count`, `last_ping` and `recent_pings`.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "tags",
                ":id"
              ],
              "raw": "{{base_url}}/v1/integrations/tags/:id",
              "variable": [
                {
                  "description": "The tag's printed ID (for example `0938NYH`), BLE identifier or uuid. A tag not assigned to your organization answers 404.",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Get Tag Journey",
          "request": {
            "description": "Get the ping journey of one of your tags.\n\nThe tag's ping locations, in order. Not paginated.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "tags",
                ":id",
                "journey"
              ],
              "raw": "{{base_url}}/v1/integrations/tags/:id/journey",
              "variable": [
                {
                  "description": "The tag's printed ID (for example `0938NYH`), BLE identifier or uuid. A tag not assigned to your organization answers 404.",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Get Tag Evidence",
          "request": {
            "description": "Get the evidence data of one of your tags.\n\nEverything the evidence PDF of the tag's most recent dispute with generated evidence contains, as JSON: the dispute, delivery metrics, carrier data and location proof. Answers 404 when no evidence has been generated for the tag, and when the tag's evidence belongs to a dispute opened before the tag was assigned to you.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "tags",
                ":id",
                "evidence"
              ],
              "raw": "{{base_url}}/v1/integrations/tags/:id/evidence",
              "variable": [
                {
                  "description": "The tag's printed ID (for example `0938NYH`), BLE identifier or uuid. A tag not assigned to your organization answers 404.",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Update Tag",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"order_id\": \"ORD-001\",\n  \"recipient_name\": \"Jane Smith\",\n  \"recipient_email\": \"jane@example.com\",\n  \"recipient_phone\": \"+15551234567\",\n  \"origin_address\": \"456 Warehouse Ave, Dallas TX 75201\",\n  \"destination_address\": \"123 Main St, Austin TX 78701\"\n}"
            },
            "description": "Update one of your tags.\n\nUpdates the recipient, address, order or metadata fields. All fields are optional; omitted fields are left unchanged. If the tag is linked to a shipment, matching fields are mirrored to the shipment.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "PATCH",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "tags",
                ":id"
              ],
              "raw": "{{base_url}}/v1/integrations/tags/:id",
              "variable": [
                {
                  "description": "The tag's printed ID (for example `0938NYH`), BLE identifier or uuid. A tag not assigned to your organization answers 404.",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "List Tag Disputes",
          "request": {
            "description": "List the disputes of one of your tags.\n\nDisputes opened on the tag while it was assigned to you: a dispute opened before then is not listed. Only the filters documented here are forwarded; any other query parameter is ignored. `page` is 1-based (default 1) and `limit` is 1 to 200 (default 50); any other value answers 400. `pagination` counts only your organization's items. A filter that matches more than 5,000 items on the tracking network, or a list that takes more than 20 seconds to read, answers 503 `List too large, add filters`: narrow the filters and retry.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "tags",
                ":id",
                "disputes"
              ],
              "query": [
                {
                  "description": "Page number, 1-based. Default 1.",
                  "disabled": true,
                  "key": "page",
                  "value": ""
                },
                {
                  "description": "Items per page, 1 to 200. Default 50.",
                  "disabled": true,
                  "key": "limit",
                  "value": ""
                }
              ],
              "raw": "{{base_url}}/v1/integrations/tags/:id/disputes",
              "variable": [
                {
                  "description": "The tag's printed ID (for example `0938NYH`), BLE identifier or uuid. A tag not assigned to your organization answers 404.",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        }
      ],
      "name": "Tags"
    },
    {
      "description": "List, retrieve, create and update your shipments. A shipment groups one or more of your tags under one carrier tracking number and can carry a declared value (`insurance`).",
      "item": [
        {
          "name": "List Shipments",
          "request": {
            "description": "List your organization's shipments.\n\nYour organization's shipments, each with its `insurance` (null when none is declared). Filters: `q`, `carrier`, `package_id` and `state`. `data` is always `{ items, pagination }`. Only the filters documented here are forwarded; any other query parameter is ignored. `page` is 1-based (default 1) and `limit` is 1 to 200 (default 50); any other value answers 400. `pagination` counts only your organization's items. A filter that matches more than 5,000 items on the tracking network, or a list that takes more than 20 seconds to read, answers 503 `List too large, add filters`: narrow the filters and retry.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "shipments"
              ],
              "query": [
                {
                  "description": "Page number, 1-based. Default 1.",
                  "key": "page",
                  "value": "1"
                },
                {
                  "description": "Items per page, 1 to 200. Default 50.",
                  "key": "limit",
                  "value": "50"
                },
                {
                  "description": "Free-text search across master tracking number, order ID, recipient\nname/email, carrier, and child (package) tracking numbers.",
                  "disabled": true,
                  "key": "q",
                  "value": ""
                },
                {
                  "description": "Filter by carrier (case-insensitive, e.g. \"fedex\", \"ups\", \"usps\").",
                  "disabled": true,
                  "key": "carrier",
                  "value": ""
                },
                {
                  "description": "Filter to shipments that have at least one tag with this lifecycle state.",
                  "disabled": true,
                  "key": "state",
                  "value": ""
                },
                {
                  "description": "Return only the shipment that contains this package ID.",
                  "disabled": true,
                  "key": "package_id",
                  "value": ""
                }
              ],
              "raw": "{{base_url}}/v1/integrations/shipments?page=1&limit=50"
            }
          }
        },
        {
          "name": "Get Shipment",
          "request": {
            "description": "Get one of your shipments with its packages.\n\nIncludes `insurance`. Any id that is not one of your organization's shipments answers 404.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "shipments",
                ":id"
              ],
              "raw": "{{base_url}}/v1/integrations/shipments/:id",
              "variable": [
                {
                  "description": "Shipment id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Update Shipment",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"carrier\": \"fedex\",\n  \"master_tracking_number\": \"123456789012\",\n  \"order_id\": \"ORD-001\",\n  \"recipient_name\": \"Jane Smith\",\n  \"recipient_email\": \"jane@example.com\",\n  \"recipient_phone\": \"+15551234567\",\n  \"destination_address\": \"123 Main St, Austin TX 78701\",\n  \"origin_address\": \"456 Warehouse Ave, Dallas TX 75201\",\n  \"service_level\": \"ground\",\n  \"insurance\": {\n    \"declared_value\": \"1250.00\",\n    \"currency\": \"USD\"\n  }\n}"
            },
            "description": "Update one of your shipments.\n\nUpdates the tracking number, carrier, addresses or recipient fields. All fields are optional; omitted fields are left unchanged. `insurance` sets the declared value and `\"insurance\": null` clears it; a body with only `insurance` changes nothing on the tracking network. The answer carries `insurance`.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "PATCH",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "shipments",
                ":id"
              ],
              "raw": "{{base_url}}/v1/integrations/shipments/:id",
              "variable": [
                {
                  "description": "Shipment id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Create Shipment",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"carrier\": \"fedex\",\n  \"master_tracking_number\": \"123456789012\",\n  \"order_id\": \"ORD-001\",\n  \"recipient_name\": \"Jane Smith\",\n  \"recipient_email\": \"jane@example.com\",\n  \"recipient_phone\": \"+15551234567\",\n  \"destination_address\": \"123 Main St, Austin TX 78701\",\n  \"origin_address\": \"456 Warehouse Ave, Dallas TX 75201\",\n  \"service_level\": \"ground\",\n  \"packages\": [\n    {\n      \"tag_identifier\": \"0938NYH\",\n      \"child_tracking_number\": \"CHILD-TRACK-001\"\n    }\n  ],\n  \"insurance\": {\n    \"declared_value\": \"1250.00\",\n    \"currency\": \"USD\"\n  }\n}"
            },
            "description": "Create a shipment with one or more packages, linking tags already assigned to the caller's organization.\n\nCreates a shipment and links your tags as its packages; it does not create tags. `carrier` and `packages` (at least one) are required; each `packages[].tag_identifier` is the printed ID, BLE identifier or uuid of a tag assigned to your organization. An unknown tag, or one that is not yours, answers 404 naming it, and a tag named twice answers 400, both before anything is sent. `origin_location_id` is not supported and answers 400. Add `insurance` to declare a value (see the field); `null` is refused on create. The 201 answer carries `insurance`. If the tracking network does not answer in time, SecreTag checks whether the shipment was created and answers 201 when it was, 502 otherwise.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "shipments"
              ],
              "raw": "{{base_url}}/v1/integrations/shipments"
            }
          }
        }
      ],
      "name": "Shipments"
    },
    {
      "description": "Your webhook subscriptions. SecreTag signs every delivery with `X-SecreTag-Signature: sha256=<hex HMAC-SHA256 of the raw body>`; verify it with the secret returned when the subscription was created.",
      "item": [
        {
          "name": "List Webhooks",
          "request": {
            "description": "List your webhook subscriptions.\n\nSecreTag's own subscriptions for your organization in this environment, active ones first and newest first within each group, as a bare array (not paginated).",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "webhooks"
              ],
              "raw": "{{base_url}}/v1/integrations/webhooks"
            }
          }
        },
        {
          "name": "Create Webhook",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"target_url\": \"https://your-server.com/webhooks/secretag\",\n  \"label\": \"My integration\",\n  \"event_types\": [\n    \"tag.state_changed\",\n    \"tag.delivered\",\n    \"shipment.created\"\n  ]\n}"
            },
            "description": "Create a webhook subscription.\n\n`target_url` must be an HTTPS URL on a public address. `event_types` lists the events to receive; omit it or send `null` for every event. The ten event types: `tag.state_changed`, `tag.delivered`, `tag.approaching`, `tag.carrier_updated`, `dispute.opened`, `dispute.resolved`, `dispute.evidence_submitted`, `shipment.created`, `shipment.delivered`, `risk.high_score`. The signing `secret` is returned once, in this response only: store it. Every delivery carries `X-SecreTag-Signature: sha256=<hex HMAC-SHA256 of the raw body>` keyed with that secret, with `X-SecreTag-Event` and `X-SecreTag-Delivery`. A delivery succeeds only on a 2xx answer and is retried up to 8 attempts in all (waits of 30 s, 2 min, 10 min, 30 min, 1 h, 3 h and 8 h).",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "webhooks"
              ],
              "raw": "{{base_url}}/v1/integrations/webhooks"
            }
          }
        },
        {
          "name": "List Webhook Deliveries",
          "request": {
            "description": "List the deliveries of one of your webhook subscriptions.\n\nSecreTag's own delivery log for the subscription, newest first. `page` is 1-based (default 1) and `limit` is 1 to 200 (default 50); any other value answers 400.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "webhooks",
                ":id",
                "deliveries"
              ],
              "query": [
                {
                  "description": "Page number, 1-based. Default 1.",
                  "key": "page",
                  "value": "1"
                },
                {
                  "description": "Items per page, 1 to 200. Default 50.",
                  "key": "limit",
                  "value": "50"
                }
              ],
              "raw": "{{base_url}}/v1/integrations/webhooks/:id/deliveries?page=1&limit=50",
              "variable": [
                {
                  "description": "Webhook subscription id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Delete Webhook",
          "request": {
            "description": "Deactivate one of your webhook subscriptions.\n\nThe subscription stops receiving events and its pending deliveries are cancelled. Answers 204 with no body.",
            "method": "DELETE",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "webhooks",
                ":id"
              ],
              "raw": "{{base_url}}/v1/integrations/webhooks/:id",
              "variable": [
                {
                  "description": "Webhook subscription id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        }
      ],
      "name": "Webhooks"
    },
    {
      "description": "Read and manage your delivery alerts.",
      "item": [
        {
          "name": "List Alerts",
          "request": {
            "description": "List your organization's alerts.\n\nAlerts raised on your tags while they were assigned to you. Filters: `type`, `severity`, `unread_only`, `read` and `tag_id`. Only the filters documented here are forwarded; any other query parameter is ignored. `page` is 1-based (default 1) and `limit` is 1 to 200 (default 50); any other value answers 400. `pagination` counts only your organization's items. A filter that matches more than 5,000 items on the tracking network, or a list that takes more than 20 seconds to read, answers 503 `List too large, add filters`: narrow the filters and retry.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "alerts"
              ],
              "query": [
                {
                  "description": "Page number, 1-based. Default 1.",
                  "key": "page",
                  "value": "1"
                },
                {
                  "description": "Items per page, 1 to 200. Default 50.",
                  "key": "limit",
                  "value": "50"
                },
                {
                  "description": "Alert type, for example `geofence`, `delivery`, `dispute`, `system`, `package_separation` or `gps_carrier_mismatch`.",
                  "disabled": true,
                  "key": "type",
                  "value": ""
                },
                {
                  "description": "`info`, `warning` or `critical`.",
                  "disabled": true,
                  "key": "severity",
                  "value": ""
                },
                {
                  "description": "`false` for unread alerts, `true` for read ones; omit for all.",
                  "disabled": true,
                  "key": "read",
                  "value": "false"
                },
                {
                  "description": "A tag's uuid, printed ID or BLE identifier. A tag not assigned to your organization returns an empty page.",
                  "disabled": true,
                  "key": "tag_id",
                  "value": ""
                }
              ],
              "raw": "{{base_url}}/v1/integrations/alerts?page=1&limit=50"
            }
          }
        },
        {
          "name": "Alert Summary",
          "request": {
            "description": "Alert counts for your organization.\n\nComputed by SecreTag from your organization's alerts: `total` is the number of your alerts, `unread` those without `read_at`, and `critical_unread` the unread ones of severity `critical`. Reading your alerts takes at most 20 seconds and 5,000 items on the tracking network; past either the answer is 502, never a partial count.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "alerts",
                "summary"
              ],
              "raw": "{{base_url}}/v1/integrations/alerts/summary"
            }
          }
        },
        {
          "name": "Mark Alert Read",
          "request": {
            "description": "Mark one of your alerts as read.\n\nAny id that is not one of your organization's alerts answers 404 and nothing is changed.",
            "method": "PATCH",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "alerts",
                ":id",
                "read"
              ],
              "raw": "{{base_url}}/v1/integrations/alerts/:id/read",
              "variable": [
                {
                  "description": "Alert id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Mark All Alerts Read",
          "request": {
            "description": "Mark all your unread alerts as read.\n\nComputed by SecreTag: each of your organization's unread alerts is marked read, one by one, and `marked_read` is how many were marked. Reading and updating share a 20 second deadline and the 5,000-item limit; a failure part way answers 502, the alerts already marked stay read, and a retry marks only what is still unread.",
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "alerts",
                "read-all"
              ],
              "raw": "{{base_url}}/v1/integrations/alerts/read-all"
            }
          }
        }
      ],
      "name": "Alerts"
    },
    {
      "description": "Read your disputes, view their statistics, resolve them, and generate and download evidence.",
      "item": [
        {
          "name": "List Disputes",
          "request": {
            "description": "List your organization's disputes.\n\nDisputes opened on your tags while they were assigned to you. Filters: `status`, `type` and `tag_id`. Only the filters documented here are forwarded; any other query parameter is ignored. `page` is 1-based (default 1) and `limit` is 1 to 200 (default 50); any other value answers 400. `pagination` counts only your organization's items. A filter that matches more than 5,000 items on the tracking network, or a list that takes more than 20 seconds to read, answers 503 `List too large, add filters`: narrow the filters and retry.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "disputes"
              ],
              "query": [
                {
                  "description": "Page number, 1-based. Default 1.",
                  "key": "page",
                  "value": "1"
                },
                {
                  "description": "Items per page, 1 to 200. Default 50.",
                  "key": "limit",
                  "value": "50"
                },
                {
                  "description": "`open`, `investigating` or `resolved`.",
                  "disabled": true,
                  "key": "status",
                  "value": ""
                },
                {
                  "description": "Dispute type: `not_delivered`, `damaged`, `wrong_location` or `other`.",
                  "disabled": true,
                  "key": "type",
                  "value": ""
                },
                {
                  "description": "A tag's uuid, printed ID or BLE identifier. A tag not assigned to your organization returns an empty page.",
                  "disabled": true,
                  "key": "tag_id",
                  "value": ""
                }
              ],
              "raw": "{{base_url}}/v1/integrations/disputes?page=1&limit=50"
            }
          }
        },
        {
          "name": "Get Dispute",
          "request": {
            "description": "Get one of your disputes.\n\nAny id that is not one of your organization's disputes answers 404.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "disputes",
                ":id"
              ],
              "raw": "{{base_url}}/v1/integrations/disputes/:id",
              "variable": [
                {
                  "description": "Dispute id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Dispute Stats",
          "request": {
            "description": "Dispute statistics for your organization.\n\nComputed by SecreTag from your organization's disputes, never forwarded:\n- `total`: your disputes. `open`, `investigating` and `resolved`: those with that status (a dispute with another status counts in `total` only).\n- `shopify_submitted`: your disputes that carry a `shopify_submitted_at`.\n- `avg_resolution_hours`: the mean of `resolved_at` minus `opened_at` in hours, rounded to two decimals, over your resolved disputes that carry both times; `null` when none is resolved.\n- `evidence_generated`: the number of your disputes for which SecreTag recorded a successful `generate_evidence` call through this API.\n- `amount_at_risk`: the sum of the declared values (`insurance.declared_value`) of your insured shipments that have an `open` or `investigating` dispute, as a number with two decimals, in your organization's currency. A dispute's shipment is your latest shipment carrying the dispute's tag created at or before `opened_at`; each shipment counts once, and a cleared or replaced declared value does not count.\n\nReading your disputes takes at most 20 seconds and 5,000 items on the tracking network; past either the answer is 502, never a partial figure.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "disputes",
                "stats"
              ],
              "raw": "{{base_url}}/v1/integrations/disputes/stats"
            }
          }
        },
        {
          "name": "Resolve Dispute",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"resolution\": \"Confirmed delivered: package located at rear entrance.\",\n  \"evidence_score\": 85\n}"
            },
            "description": "Resolve one of your disputes.\n\n`resolution` is required free text; `evidence_score` is optional (0 to 100). An API key carries no user, so `resolved_by` stays null.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "disputes",
                ":id",
                "resolve"
              ],
              "raw": "{{base_url}}/v1/integrations/disputes/:id/resolve",
              "variable": [
                {
                  "description": "Dispute id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Generate Evidence",
          "request": {
            "description": "Generate the evidence PDF for one of your disputes.\n\nThe evidence report is produced by the tracking network; `evidence_pdf_key` names where it stored the PDF. Download it with `get_evidence_pdf`. A successful call counts toward `dispute_stats.evidence_generated`.",
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "disputes",
                ":id",
                "evidence",
                "generate"
              ],
              "raw": "{{base_url}}/v1/integrations/disputes/:id/evidence/generate",
              "variable": [
                {
                  "description": "Dispute id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Download Evidence PDF",
          "request": {
            "description": "Download the evidence PDF for one of your disputes.\n\nReturns the PDF bytes as the tracking network rendered them, typed `application/pdf` and not wrapped in the envelope. Call `generate_evidence` first: until then this answers 404.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "disputes",
                ":id",
                "evidence",
                "pdf"
              ],
              "raw": "{{base_url}}/v1/integrations/disputes/:id/evidence/pdf",
              "variable": [
                {
                  "description": "Dispute id",
                  "key": "id",
                  "value": ""
                }
              ]
            }
          }
        }
      ],
      "name": "Disputes"
    },
    {
      "description": "Sandbox-only operations for the tags assigned to you for testing (set `sandbox_tag_id`). They simulate a tag's lifecycle without live hardware and run only on sandbox-api.secretag.co.\n\nRecommended flow:\n1. Inject a mock journey (stage `started`, `in_transit`, `approaching` or `complete`).\n2. Check the tag's state and journey with the Tags requests.\n3. Send a test webhook to verify your receiver.\n4. Reset the tag to replay the scenario.",
      "item": [
        {
          "name": "Inject Mock Journey",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"stage\": \"complete\"\n}"
            },
            "description": "Inject a mock Los Angeles to Dallas ping route into one of your sandbox tags.\n\nSets the tag's origin (Los Angeles, Arcadia) and destination (Dallas) coordinates and injects pings along the route. `stage` sets how far the journey goes: `started` (3 pings), `in_transit` (8), `approaching` (13) or `complete` (all 15, the default). Send `{}` for the complete journey.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "sandbox",
                "tags",
                "{{sandbox_tag_id}}",
                "mock-journey"
              ],
              "raw": "{{base_url}}/v1/integrations/sandbox/tags/{{sandbox_tag_id}}/mock-journey"
            }
          }
        },
        {
          "name": "Force Tag State",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"state\": \"in_transit\"\n}"
            },
            "description": "Force one of your sandbox tags into a state.\n\nSets the tag's lifecycle state directly, skipping the normal transitions. Valid `state`: `awaiting_first_ping`, `at_origin`, `in_transit`, `approaching`, `delivered`, `delivery_verification`, `disputed_in_transit`, `completed`. `data` is `{ tag_id, state }`.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "sandbox",
                "tags",
                "{{sandbox_tag_id}}",
                "state"
              ],
              "raw": "{{base_url}}/v1/integrations/sandbox/tags/{{sandbox_tag_id}}/state"
            }
          }
        },
        {
          "name": "Reset Tag",
          "request": {
            "description": "Reset one of your sandbox tags.\n\nClears the tag's pings, recipient, addresses, order ID and metadata, deletes its linked shipment and packages, and sets its state to `awaiting_first_ping`. SecreTag also clears the declared value of the deleted shipment. No request body is needed. `data` is `{ tag_id, pings_deleted, shipment_deleted, state }`.",
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "sandbox",
                "tags",
                "{{sandbox_tag_id}}",
                "reset"
              ],
              "raw": "{{base_url}}/v1/integrations/sandbox/tags/{{sandbox_tag_id}}/reset"
            }
          }
        },
        {
          "name": "Inject Alert",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"alert_type\": \"delivery\",\n  \"severity\": \"warning\"\n}"
            },
            "description": "Inject a fake alert on one of your sandbox tags.\n\nCreates an alert on the tag so you can test your alert handling. Send `{}` for an alert of type `delivery` and severity `warning`. Valid `alert_type`: `geofence`, `delivery`, `dispute`, `system`, `package_separation`, `gps_carrier_mismatch`. Valid `severity`: `info`, `warning`, `critical`. The alert appears in `list_alerts`.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "sandbox",
                "tags",
                "{{sandbox_tag_id}}",
                "alert"
              ],
              "raw": "{{base_url}}/v1/integrations/sandbox/tags/{{sandbox_tag_id}}/alert"
            }
          }
        },
        {
          "name": "Open Dispute",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"dispute_type\": \"not_delivered\",\n  \"customer_claim\": \"Customer reports the package was not delivered.\"\n}"
            },
            "description": "Open a fake dispute on one of your sandbox tags.\n\nOpens a dispute with status `open`. Send `{}` for a `not_delivered` dispute with a default claim. Valid `dispute_type`: `not_delivered`, `damaged`, `wrong_location`, `other`; `customer_claim` is at most 1000 characters. Use it to test the dispute flow: open, generate evidence, download the PDF, resolve.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "sandbox",
                "tags",
                "{{sandbox_tag_id}}",
                "dispute"
              ],
              "raw": "{{base_url}}/v1/integrations/sandbox/tags/{{sandbox_tag_id}}/dispute"
            }
          }
        },
        {
          "name": "Inject Carrier Event",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"status\": \"in_transit\"\n}"
            },
            "description": "Inject a fake carrier status on the tag's shipment package.\n\nThe tag must already be linked to a shipment (through `create_shipment`); otherwise the answer is 400. Valid `status`: `in_transit`, `out_for_delivery`, `delivered`, `exception`.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "sandbox",
                "tags",
                "{{sandbox_tag_id}}",
                "carrier-event"
              ],
              "raw": "{{base_url}}/v1/integrations/sandbox/tags/{{sandbox_tag_id}}/carrier-event"
            }
          }
        },
        {
          "name": "Emit Risk Score",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"score\": 85,\n  \"risk_factors\": [\n    \"route_deviation\",\n    \"dispute_history\"\n  ]\n}"
            },
            "description": "Emit a risk.high_score event for one of your sandbox tags.\n\nRaises a `risk.high_score` event for the tag; SecreTag relays it to your subscriptions like any other event. Send `{}` for a score of 85 with the factors `route_deviation` and `dispute_history`; `score` must be 0 to 100. No risk score record is stored. `data` is `{ tag_id, score, risk_factors, subscriptions_enqueued }`, where `subscriptions_enqueued` is the tracking network's own count for SecreTag's relay (one subscription), not the number of your subscriptions.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "sandbox",
                "tags",
                "{{sandbox_tag_id}}",
                "risk-score"
              ],
              "raw": "{{base_url}}/v1/integrations/sandbox/tags/{{sandbox_tag_id}}/risk-score"
            }
          }
        },
        {
          "name": "Fire Test Webhook",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"event_type\": \"tag.state_changed\"\n}"
            },
            "description": "Send a sample event to your webhook subscriptions.\n\nSecreTag builds its own sample event of `event_type` for your organization (realistic sample objects carrying your `organization_id`, on your first assigned tag when you have one) and queues it to each of your active subscriptions that takes that event. `subscriptions_enqueued` is the number of your matching active subscriptions. The deliveries are signed and retried like real events and appear in `list_webhook_deliveries`. Nothing is sent to the tracking network. Event types: `tag.state_changed`, `tag.delivered`, `tag.approaching`, `tag.carrier_updated`, `dispute.opened`, `dispute.resolved`, `dispute.evidence_submitted`, `shipment.created`, `shipment.delivered`, `risk.high_score`.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "integrations",
                "sandbox",
                "webhooks",
                "test"
              ],
              "raw": "{{base_url}}/v1/integrations/sandbox/webhooks/test"
            }
          }
        }
      ],
      "name": "Sandbox"
    },
    {
      "description": "Address risk scoring.",
      "item": [
        {
          "name": "Get Address Score",
          "request": {
            "description": "Get a stored risk score by address hash.\n\nAnswers 404 unless your organization assessed this address hash before, with `assess_address` or `assess_batch`. The score is the tracking network's one record for the address: `created_at` and `updated_at` are when the network first and last scored the address for any of its customers, and `address_input` is the input it keeps. The dispute-history signal of a score is computed by the tracking network over the history of every SecreTag customer.",
            "method": "GET",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "risk",
                "address",
                ":hash"
              ],
              "raw": "{{base_url}}/v1/risk/address/:hash",
              "variable": [
                {
                  "description": "Normalized address hash, as returned in `address_hash`",
                  "key": "hash",
                  "value": ""
                }
              ]
            }
          }
        },
        {
          "name": "Assess Address",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"street\": \"123 Main St\",\n  \"street2\": \"Apt 4\",\n  \"city\": \"Austin\",\n  \"state\": \"TX\",\n  \"zip\": \"78701\"\n}"
            },
            "description": "Score one delivery address.\n\nReturns the address's risk score and its six signals; the `address_hash` is recorded for your organization, so `get_address_score` can read it later. The dispute-history signal of a score is computed by the tracking network over the history of every SecreTag customer.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "risk",
                "assess"
              ],
              "raw": "{{base_url}}/v1/risk/assess"
            }
          }
        },
        {
          "name": "Assess Batch",
          "request": {
            "body": {
              "mode": "raw",
              "options": {
                "raw": {
                  "language": "json"
                }
              },
              "raw": "{\n  \"addresses\": [\n    {\n      \"street\": \"123 Main St\",\n      \"street2\": \"Apt 4\",\n      \"city\": \"Austin\",\n      \"state\": \"TX\",\n      \"zip\": \"78701\"\n    },\n    {\n      \"street\": \"456 Warehouse Ave\",\n      \"city\": \"Dallas\",\n      \"state\": \"TX\",\n      \"zip\": \"75201\"\n    }\n  ]\n}"
            },
            "description": "Score up to 100 addresses.\n\n`addresses` must hold 1 to 100 addresses; anything else answers 400 before anything is sent. `cached` counts the results whose address hash your organization had assessed before this call. The dispute-history signal of a score is computed by the tracking network over the history of every SecreTag customer.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "method": "POST",
            "url": {
              "host": [
                "{{base_url}}"
              ],
              "path": [
                "v1",
                "risk",
                "batch"
              ],
              "raw": "{{base_url}}/v1/risk/batch"
            }
          }
        }
      ],
      "name": "Risk"
    }
  ],
  "variable": [
    {
      "description": "Base URL: https://sandbox-api.secretag.co for the sandbox, https://api.secretag.co for production.",
      "key": "base_url",
      "type": "string",
      "value": "https://sandbox-api.secretag.co"
    },
    {
      "description": "Your st_test_... key",
      "key": "api_key",
      "type": "string",
      "value": ""
    },
    {
      "description": "The printed ID (for example 093-8PDZ) of a tag assigned to you for sandbox testing.",
      "key": "sandbox_tag_id",
      "type": "string",
      "value": ""
    }
  ]
}
