API Reference · Your Data

Scan Delta

What changed between this scan and the previous scan of the same target (new and removed hosts, ports, services, certificates, findings) as a precomputed summary plus an ordered event list. The diff is computed by the platform when a scan completes; this endpoint returns it, it never computes on the fly.

Combined with GET /my/scans, this is the cheapest way to stay current: notice a new scan (1 credit), read its delta (1 credit), and only fetch the full document when the delta says something you care about moved.

GET
/v1/my/scans/{scan_id}/delta

Cost: 1 credit per successful call · Scope: api:org

Path parameters

scan_idstring (uuid)required

The newer scan of the pair. The delta compares it against the previous scan of the same target, named in from_scan_id.

Request

curl "https://api.edgeprotect.io/functions/v1/my/scans/f63285e2-9c78-4020-b2bb-5c8bd2ca51ed/delta" \
  -H "Authorization: Bearer $EDGEPROTECT_API_KEY"

Response

{
  "data": {
    "scan_id": "f63285e2-9c78-4020-b2bb-5c8bd2ca51ed",
    "from_scan_id": "226f9d98-9974-2db7-c307-28f3c5203d10",
    "has_delta": true,
    "computed_at": "2026-08-06T06:45:12+00:00",
    "summary": {
      "added": 5, "removed": 0, "changed": 0, "total_changes": 5,
      "by_category": {
        "ports":                { "added": 2, "removed": 0, "changed": 0, "total_before": 34, "total_after": 36 },
        "hosts":                { "added": 1, "removed": 0, "changed": 0, "total_before": 15, "total_after": 16 },
        "vulnerabilities":      { "added": 2, "removed": 0, "changed": 0, "total_before": 13, "total_after": 15 }
      }
    },
    "events": [
      {
        "category": "hosts",
        "categoryLabel": "Hosts",
        "icon": "fas fa-server",
        "type": "added",
        "key": "staging.acme-corp.example",
        "label": "staging.acme-corp.example",
        "message": "New host discovered: staging.acme-corp.example",
        "weight": 60,
        "changes": null
      }
    ]
  },
  "meta": {
    "request_id": "8b16efb8-9a6c-4ace-b817-11cbee626d08",
    "api_version": "1.3.0",
    "credits": { "charged": 1, "remaining": 9996 }
  }
}

Response fields

data.has_deltabooleanoptional

false is a real answer, not an error: it means this is the first scan of its target, or the platform has not computed the diff. When false, summary, events, from_scan_id and computed_at are all null.

data.from_scan_idstring | nulloptional

The older scan the comparison ran against.

data.summaryobject | nulloptional

Overall added / removed / changed / total_changes counts, plus a by_category breakdown (categories: ports, hosts, ip_addresses, services, ssl_certificates, domains, subdomains, dns_records, network_ranges, vulnerabilities, vulnerability_instances, exposed_credentials) with before/after totals per category.

data.eventsarray | nulloptional

The individual changes. Each event has category, type (added / removed / changed), key (stable identity of the thing that changed), label, a human-readable message, a significance weight (higher = more attention-worthy; an exposed credential outranks a TTL change), and changes (the changed fields, on type: "changed" events).

A scan that isn't yours looks exactly like one that doesn't exist

An unknown scan_id (or another organisation's) returns 200 OK with data set to null, and the credit is still charged. Take scan ids from GET /my/scans.

Errors

Status error When
400 invalid_scan_id The path segment is not a UUID. Free: rejected before billing.
401 invalid_authorization Missing or malformed Authorization header.
401 unauthorized Invalid/revoked key, IP not allowlisted, or the key lacks the api:org scope.
402 insufficient_credits Organisation credit balance is below 1.
405 method_not_allowed Only GET and OPTIONS are accepted.
500 internal Unexpected server error (credit auto-refunded).

See Errors for the full error reference.