Skip to documentation

Generic examplesSign in to personalize workspace URLs.

Download OpenAPI

Investigations, notes and packages

A case reviews an accessible project and bounded period. Graph gaps and inferred relationships remain explicit; confidence is not proof of complete coverage.

List delivery investigations

Operation: investigations.list · GET /investigations

Read cases filtered by existing project/customer. Open cases sort before resolved/filed cases, then period and creation newest first. No pagination. Availability is independent of a measured zero. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:read. Current creator action: investigations.read. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "11111111-1111-4111-8111-111111111111",
    "in": "query",
    "name": "projectId",
    "required": false,
    "schema": {
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "in": "query", "name": "clientId", "required": false, "schema": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } } ]

Success statuses: 200. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "canManage": true,
  "cases": [
    {
      "clientId": "22222222-2222-4222-8222-222222222222",
      "closedAt": null,
      "confidence": 25,
      "createdAt": "2026-10-01T07:59:39.642Z",
      "flagCount": 2,
      "graphState": {
        "overlay": "all",
        "panelOpen": true,
        "positions": {},
        "selected": null
      },
      "id": "33333333-3333-4333-8333-333333333333",
      "ownerName": "Example owner",
      "ownerUserId": "00000000-0000-4000-8000-000000000008",
      "periodEnd": "2026-03-31",
      "periodStart": "2026-01-01",
      "projectId": "11111111-1111-4111-8111-111111111111",
      "status": "Investigating",
      "subtitle": "Establish the chain of evidence",
      "timeZone": "UTC",
      "title": "Example delivery review",
      "typology": null,
      "unresolvedFlagCount": 2,
      "updatedAt": "2026-10-01T07:59:39.642Z",
      "version": 1
    }
  ]
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request GET "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations?projectId=11111111-1111-4111-8111-111111111111" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY"

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations?projectId=11111111-1111-4111-8111-111111111111", {
  method: "GET",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`
},
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"]}
response = requests.request("GET", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations?projectId=11111111-1111-4111-8111-111111111111", headers=headers, timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Retrieve an investigation and its evidence

Operation: investigations.read · GET /investigations/:caseId

Read case, sourced flags, dispositions, notes, packages and audit history. Opaque case IDs retain the application's full-scope authorization; passing a project hint does not broaden a restricted grant. Evidence absence and inference remain visible. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:read. Current creator action: investigations.read. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "33333333-3333-4333-8333-333333333333",
    "in": "path",
    "name": "caseId",
    "required": true,
    "schema": {
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } } ]

Success statuses: 200. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "audit": [
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.645Z",
      "id": "00000000-0000-4000-8000-000000000012",
      "kind": "investigation.case.opened",
      "payload": {
        "clientId": "22222222-2222-4222-8222-222222222222",
        "periodEnd": "2026-03-31",
        "periodStart": "2026-01-01",
        "projectId": "11111111-1111-4111-8111-111111111111",
        "title": "Example delivery review",
        "typology": null
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.648Z",
      "id": "00000000-0000-4000-8000-000000000013",
      "kind": "investigation.flag.seeded",
      "payload": {
        "count": 2,
        "signalKeys": [
          "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
          "added-after-lock:wi-00000000-0000-4000-8000-000000000011"
        ]
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.780Z",
      "id": "00000000-0000-4000-8000-000000000014",
      "kind": "investigation.case.updated",
      "payload": {
        "after": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example evidence review"
        },
        "before": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example delivery review"
        }
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.797Z",
      "id": "00000000-0000-4000-8000-000000000015",
      "kind": "investigation.note.added",
      "payload": {
        "after": {
          "body": "Delivery evidence supports this observation; inference remains separate."
        },
        "noteId": "55555555-5555-4555-8555-555555555555",
        "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.814Z",
      "id": "00000000-0000-4000-8000-000000000017",
      "kind": "investigation.note.edited",
      "payload": {
        "after": {
          "body": "Correction: retain the evidence link and state the remaining uncertainty."
        },
        "before": {
          "body": "Delivery evidence supports this observation; inference remains separate."
        },
        "noteId": "55555555-5555-4555-8555-555555555555"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.852Z",
      "id": "00000000-0000-4000-8000-000000000019",
      "kind": "investigation.flag.dispositioned",
      "payload": {
        "after": {
          "disposition": "inscope",
          "rationale": "Reviewed the synthetic delivery evidence"
        },
        "before": {
          "disposition": null,
          "rationale": null
        },
        "flagId": "44444444-4444-4444-8444-444444444444",
        "nodeIds": [
          "wi-00000000-0000-4000-8000-000000000009"
        ],
        "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.893Z",
      "id": "00000000-0000-4000-8000-000000000020",
      "kind": "investigation.flag.dispositioned",
      "payload": {
        "after": {
          "disposition": "inscope",
          "rationale": "Reviewed the synthetic delivery evidence"
        },
        "before": {
          "disposition": null,
          "rationale": null
        },
        "flagId": "00000000-0000-4000-8000-000000000010",
        "nodeIds": [
          "wi-00000000-0000-4000-8000-000000000011"
        ],
        "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:40.047Z",
      "id": "00000000-0000-4000-8000-000000000023",
      "kind": "investigation.package.created",
      "payload": {
        "claims": 2,
        "contentHash": "3de1f3ff28b41bca9750f4ecc4583b697a3ce58bd5785ea06a00c9c7b3719bf4",
        "draft": false,
        "engine": "template",
        "kind": "memo",
        "packageId": "66666666-6666-4666-8666-666666666666"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:40.254Z",
      "id": "00000000-0000-4000-8000-000000000024",
      "kind": "investigation.package.attached",
      "payload": {
        "packageId": "66666666-6666-4666-8666-666666666666",
        "reportId": "77777777-7777-4777-8777-777777777777",
        "reportSnapshotId": "00000000-0000-4000-8000-000000000021"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    }
  ],
  "canManage": true,
  "case": {
    "clientId": "22222222-2222-4222-8222-222222222222",
    "closedAt": "2026-10-01T07:59:39.890Z",
    "confidence": 25,
    "createdAt": "2026-10-01T07:59:39.642Z",
    "flagCount": 2,
    "graphState": {
      "overlay": "all",
      "panelOpen": true,
      "positions": {},
      "selected": null
    },
    "id": "33333333-3333-4333-8333-333333333333",
    "ownerName": "Example owner",
    "ownerUserId": "00000000-0000-4000-8000-000000000008",
    "periodEnd": "2026-03-31",
    "periodStart": "2026-01-01",
    "projectId": "11111111-1111-4111-8111-111111111111",
    "status": "Filed",
    "subtitle": "Establish the chain of evidence",
    "timeZone": "UTC",
    "title": "Example evidence review",
    "typology": null,
    "unresolvedFlagCount": 0,
    "updatedAt": "2026-10-01T07:59:40.043Z",
    "version": 7
  },
  "flags": [
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
      "disposition": "inscope",
      "history": [
        {
          "actorName": "Example owner",
          "actorUserId": "00000000-0000-4000-8000-000000000008",
          "at": "2026-10-01T07:59:39.849Z",
          "auditEventId": "00000000-0000-4000-8000-000000000019",
          "from": null,
          "id": "00000000-0000-4000-8000-000000000018",
          "rationale": "Reviewed the synthetic delivery evidence",
          "to": "inscope"
        }
      ],
      "id": "44444444-4444-4444-8444-444444444444",
      "impact": "$1,800",
      "impactCents": 180000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000009"
      ],
      "rationale": "Reviewed the synthetic delivery evidence",
      "resolvedAt": "2026-10-01T07:59:39.849Z",
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
      "title": "Refunds fail for split tender added after lock",
      "typology": "added-after-lock",
      "version": 2
    },
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
      "disposition": "inscope",
      "history": [
        {
          "actorName": "Example owner",
          "actorUserId": "00000000-0000-4000-8000-000000000008",
          "at": "2026-10-01T07:59:39.890Z",
          "auditEventId": "00000000-0000-4000-8000-000000000020",
          "from": null,
          "id": "00000000-0000-4000-8000-000000000022",
          "rationale": "Reviewed the synthetic delivery evidence",
          "to": "inscope"
        }
      ],
      "id": "00000000-0000-4000-8000-000000000010",
      "impact": "$4,800",
      "impactCents": 480000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000011"
      ],
      "rationale": "Reviewed the synthetic delivery evidence",
      "resolvedAt": "2026-10-01T07:59:39.890Z",
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
      "title": "Loyalty points at checkout added after lock",
      "typology": "added-after-lock",
      "version": 2
    }
  ],
  "notes": [
    {
      "authorName": "Example owner",
      "authorUserId": "00000000-0000-4000-8000-000000000008",
      "body": "Correction: retain the evidence link and state the remaining uncertainty.",
      "caseId": "33333333-3333-4333-8333-333333333333",
      "createdAt": "2026-10-01T07:59:39.794Z",
      "editedAt": "2026-10-01T07:59:39.812Z",
      "history": [
        {
          "at": "2026-10-01T07:59:39.812Z",
          "body": "Delivery evidence supports this observation; inference remains separate.",
          "editedByName": "Example owner",
          "editedByUserId": "00000000-0000-4000-8000-000000000008",
          "id": "00000000-0000-4000-8000-000000000016"
        }
      ],
      "id": "55555555-5555-4555-8555-555555555555",
      "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
    }
  ],
  "packages": [
    {
      "attachedAt": "2026-10-01T07:59:40.228Z",
      "caseId": "33333333-3333-4333-8333-333333333333",
      "contentHash": "3de1f3ff28b41bca9750f4ecc4583b697a3ce58bd5785ea06a00c9c7b3719bf4",
      "createdAt": "2026-10-01T07:59:40.043Z",
      "createdByName": "Example owner",
      "createdByUserId": "00000000-0000-4000-8000-000000000008",
      "id": "66666666-6666-4666-8666-666666666666",
      "kind": "memo",
      "reportId": "77777777-7777-4777-8777-777777777777",
      "reportSnapshotId": "00000000-0000-4000-8000-000000000021",
      "snapshot": {
        "case": {
          "agencyName": "Synthetic investigations",
          "clientName": "example Retail",
          "confidence": 25,
          "id": "33333333-3333-4333-8333-333333333333",
          "periodEnd": "2026-03-31",
          "periodLabel": "Q1 2026",
          "periodStart": "2026-01-01",
          "projectName": "example Checkout Replatform",
          "status": "Filed",
          "subtitle": "Establish the chain of evidence",
          "title": "Example evidence review",
          "typology": null
        },
        "claims": [
          {
            "auditEventIds": [
              "00000000-0000-4000-8000-000000000019"
            ],
            "id": "claim:44444444-4444-4444-8444-444444444444",
            "nodeIds": [
              "wi-00000000-0000-4000-8000-000000000009"
            ],
            "text": "Refunds fail for split tender added after lock — In scope: Reviewed the synthetic delivery evidence ($1,800)"
          },
          {
            "auditEventIds": [
              "00000000-0000-4000-8000-000000000020"
            ],
            "id": "claim:00000000-0000-4000-8000-000000000010",
            "nodeIds": [
              "wi-00000000-0000-4000-8000-000000000011"
            ],
            "text": "Loyalty points at checkout added after lock — In scope: Reviewed the synthetic delivery evidence ($4,800)"
          }
        ],
        "custody": {
          "wi-00000000-0000-4000-8000-000000000009": [
            {
              "id": "EXAMPLE-42",
              "kind": "jira",
              "meta": "Added Feb 20 · post-lock",
              "t": "Refunds fail for split tender"
            },
            {
              "id": "MR !7",
              "kind": "pr",
              "meta": "Merged Mar 02",
              "t": "Split tender refund path"
            }
          ],
          "wi-00000000-0000-4000-8000-000000000011": [
            {
              "id": "EXAMPLE-77",
              "kind": "jira",
              "meta": "Added Mar 05 · post-lock",
              "t": "Loyalty points at checkout"
            }
          ]
        },
        "draft": false,
        "engine": "template",
        "flags": [
          {
            "auditEventIds": [
              "00000000-0000-4000-8000-000000000019"
            ],
            "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
            "disposition": "inscope",
            "dispositionLabel": "In scope",
            "evidenceMissing": false,
            "id": "44444444-4444-4444-8444-444444444444",
            "impact": "$1,800",
            "impactCents": 180000,
            "nodeIds": [
              "wi-00000000-0000-4000-8000-000000000009"
            ],
            "rationale": "Reviewed the synthetic delivery evidence",
            "resolvedAt": "2026-10-01T07:59:39.849Z",
            "severity": "amber",
            "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
            "title": "Refunds fail for split tender added after lock",
            "typology": "added-after-lock"
          },
          {
            "auditEventIds": [
              "00000000-0000-4000-8000-000000000020"
            ],
            "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
            "disposition": "inscope",
            "dispositionLabel": "In scope",
            "evidenceMissing": false,
            "id": "00000000-0000-4000-8000-000000000010",
            "impact": "$4,800",
            "impactCents": 480000,
            "nodeIds": [
              "wi-00000000-0000-4000-8000-000000000011"
            ],
            "rationale": "Reviewed the synthetic delivery evidence",
            "resolvedAt": "2026-10-01T07:59:39.890Z",
            "severity": "amber",
            "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
            "title": "Loyalty points at checkout added after lock",
            "typology": "added-after-lock"
          }
        ],
        "generatedAt": "2026-10-01T07:59:40.042Z",
        "kind": "memo",
        "notes": [
          {
            "at": "2026-10-01T07:59:39.794Z",
            "auditEventIds": [
              "00000000-0000-4000-8000-000000000015",
              "00000000-0000-4000-8000-000000000017"
            ],
            "authorName": "Example owner",
            "body": "Correction: retain the evidence link and state the remaining uncertainty.",
            "id": "55555555-5555-4555-8555-555555555555",
            "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
          }
        ],
        "prose": {
          "sections": [
            {
              "body": "Evidence is traced node by node from the scope locked on 2026-01-01 through 1 release; case confidence stands at 25%.",
              "heading": "What moved after the lock"
            },
            {
              "body": "Confirmed in scope and absorbed: $6,600.",
              "heading": "Dispositions"
            },
            {
              "body": "Each claim links back to the source records and to the audit events that produced it. The subject throughout is the delivery and the scope, never an individual.",
              "heading": "How to read this memo"
            }
          ],
          "summary": "$6,600 of delivery investment on example Checkout Replatform for example Retail during Q1 2026 is accounted for line by line below. Every one of the 2 flags carries a disposition with a rationale.",
          "title": "Invoice-defense memo · example Checkout Replatform · Q1 2026"
        },
        "provenance": {
          "graphBuild": null,
          "lock": {
            "approvalRef": null,
            "authority": null,
            "effectiveAt": "2026-01-02T00:00:00.000Z",
            "lockedOn": "2026-01-01",
            "lockId": null,
            "memberCount": null,
            "provenance": "engagement_starts_on",
            "reconstructed": true,
            "resolverVersion": "lock-resolver@1",
            "timeZone": "UTC",
            "version": null
          }
        },
        "version": 1,
        "watermark": null
      },
      "status": "final"
    }
  ]
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request GET "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY"

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333", {
  method: "GET",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`
},
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"]}
response = requests.request("GET", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333", headers=headers, timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Open a delivery investigation

Operation: investigations.create · POST /investigations

Create a case for an existing customer/project pair and ordered reporting interval. Flags seed from the existing deterministic forensics graph, with current baseline provenance. No source evidence or AI grouping is invented. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:write. Current creator action: investigations.manage. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "example-investigations.create",
    "in": "header",
    "name": "idempotency-key",
    "required": true,
    "schema": {
      "pattern": "^[\\x21-\\x7e]{1,200}
quot;
, "type": "string" } } ]

Request body schema:

View schema or synthetic response
JSON

{
  "content": {
    "application/json": {
      "examples": {
        "synthetic1": {
          "value": {
            "clientId": "22222222-2222-4222-8222-222222222222",
            "end": "2026-03-31",
            "projectId": "11111111-1111-4111-8111-111111111111",
            "start": "2026-01-01",
            "title": "Example delivery review",
            "tz": "UTC"
          }
        }
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "clientId": {
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" }, "end": { "format": "date", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))
quot;
, "type": "string" }, "projectId": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" }, "start": { "format": "date", "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))
quot;
, "type": "string" }, "title": { "maxLength": 300, "minLength": 1, "type": "string" }, "typology": { "anyOf": [ { "enum": [ "expansion", "acdrift", "rework", "untraced", "cost" ], "type": "string" }, { "type": "null" } ], "default": null }, "tz": { "maxLength": 64, "minLength": 1, "type": "string" } }, "required": [ "start", "end", "projectId", "clientId" ], "type": "object" } } }, "required": true }

Success statuses: 201. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "audit": [
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.645Z",
      "id": "00000000-0000-4000-8000-000000000012",
      "kind": "investigation.case.opened",
      "payload": {
        "clientId": "22222222-2222-4222-8222-222222222222",
        "periodEnd": "2026-03-31",
        "periodStart": "2026-01-01",
        "projectId": "11111111-1111-4111-8111-111111111111",
        "title": "Example delivery review",
        "typology": null
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.648Z",
      "id": "00000000-0000-4000-8000-000000000013",
      "kind": "investigation.flag.seeded",
      "payload": {
        "count": 2,
        "signalKeys": [
          "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
          "added-after-lock:wi-00000000-0000-4000-8000-000000000011"
        ]
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    }
  ],
  "canManage": true,
  "case": {
    "clientId": "22222222-2222-4222-8222-222222222222",
    "closedAt": null,
    "confidence": 25,
    "createdAt": "2026-10-01T07:59:39.642Z",
    "flagCount": 2,
    "graphState": {
      "overlay": "all",
      "panelOpen": true,
      "positions": {},
      "selected": null
    },
    "id": "33333333-3333-4333-8333-333333333333",
    "ownerName": "Example owner",
    "ownerUserId": "00000000-0000-4000-8000-000000000008",
    "periodEnd": "2026-03-31",
    "periodStart": "2026-01-01",
    "projectId": "11111111-1111-4111-8111-111111111111",
    "status": "Investigating",
    "subtitle": "Establish the chain of evidence",
    "timeZone": "UTC",
    "title": "Example delivery review",
    "typology": null,
    "unresolvedFlagCount": 2,
    "updatedAt": "2026-10-01T07:59:39.642Z",
    "version": 1
  },
  "flags": [
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "44444444-4444-4444-8444-444444444444",
      "impact": "$1,800",
      "impactCents": 180000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000009"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
      "title": "Refunds fail for split tender added after lock",
      "typology": "added-after-lock",
      "version": 1
    },
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "00000000-0000-4000-8000-000000000010",
      "impact": "$4,800",
      "impactCents": 480000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000011"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
      "title": "Loyalty points at checkout added after lock",
      "typology": "added-after-lock",
      "version": 1
    }
  ],
  "notes": [],
  "packages": []
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request POST "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: example-operation-attempt-1' \
  --data-raw '{"start":"2026-01-01","end":"2026-03-31","projectId":"11111111-1111-4111-8111-111111111111","clientId":"22222222-2222-4222-8222-222222222222","tz":"UTC","typology":null,"title":"Example delivery review"}'

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations", {
  method: "POST",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`,
  "Content-Type": "application/json",
  "Idempotency-Key": "example-operation-attempt-1"
},
  body: JSON.stringify({
  "start": "2026-01-01",
  "end": "2026-03-31",
  "projectId": "11111111-1111-4111-8111-111111111111",
  "clientId": "22222222-2222-4222-8222-222222222222",
  "tz": "UTC",
  "typology": null,
  "title": "Example delivery review"
}),
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"],"Content-Type":"application/json","Idempotency-Key":"example-operation-attempt-1"}
response = requests.request("POST", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations", headers=headers, json=__import__("json").loads("{\"start\":\"2026-01-01\",\"end\":\"2026-03-31\",\"projectId\":\"11111111-1111-4111-8111-111111111111\",\"clientId\":\"22222222-2222-4222-8222-222222222222\",\"tz\":\"UTC\",\"typology\":null,\"title\":\"Example delivery review\"}"), timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Save the returned case ID/version. Read its graph, flags and notes before editing.

Update a case or shared canvas

Operation: investigations.update · PATCH /investigations/:caseId

Supply current case version. Title, subtitle or status needs investigations.manage; a canvas-only change needs investigations.note, including on receipt replay. Stale versions return 409. Existing status transitions and package gates apply. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:write. Current creator action: investigations.note. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "33333333-3333-4333-8333-333333333333",
    "in": "path",
    "name": "caseId",
    "required": true,
    "schema": {
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "example-investigations.update", "in": "header", "name": "idempotency-key", "required": true, "schema": { "pattern": "^[\\x21-\\x7e]{1,200}
quot;
, "type": "string" } } ]

Request body schema:

View schema or synthetic response
JSON

{
  "content": {
    "application/json": {
      "examples": {
        "synthetic1": {
          "value": {
            "title": "Example evidence review",
            "version": 1
          }
        }
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "graphState": {
            "properties": {
              "overlay": {
                "enum": [
                  "all",
                  "expansion",
                  "acdrift",
                  "rework",
                  "untraced",
                  "cost"
                ],
                "type": "string"
              },
              "panelOpen": {
                "type": "boolean"
              },
              "positions": {
                "additionalProperties": {
                  "properties": {
                    "x": {
                      "type": "number"
                    },
                    "y": {
                      "type": "number"
                    }
                  },
                  "required": [
                    "x",
                    "y"
                  ],
                  "type": "object"
                },
                "propertyNames": {
                  "type": "string"
                },
                "type": "object"
              },
              "selected": {
                "anyOf": [
                  {
                    "maxLength": 900,
                    "type": "string"
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "type": "object"
          },
          "status": {
            "enum": [
              "Open",
              "Investigating",
              "Evidence gathered",
              "Disposition",
              "Resolved",
              "Filed"
            ],
            "type": "string"
          },
          "subtitle": {
            "maxLength": 300,
            "type": "string"
          },
          "title": {
            "maxLength": 300,
            "minLength": 1,
            "type": "string"
          },
          "version": {
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "type": "integer"
          }
        },
        "required": [
          "version"
        ],
        "type": "object"
      }
    }
  },
  "required": true
}

Success statuses: 200. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "audit": [
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.645Z",
      "id": "00000000-0000-4000-8000-000000000012",
      "kind": "investigation.case.opened",
      "payload": {
        "clientId": "22222222-2222-4222-8222-222222222222",
        "periodEnd": "2026-03-31",
        "periodStart": "2026-01-01",
        "projectId": "11111111-1111-4111-8111-111111111111",
        "title": "Example delivery review",
        "typology": null
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.648Z",
      "id": "00000000-0000-4000-8000-000000000013",
      "kind": "investigation.flag.seeded",
      "payload": {
        "count": 2,
        "signalKeys": [
          "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
          "added-after-lock:wi-00000000-0000-4000-8000-000000000011"
        ]
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.780Z",
      "id": "00000000-0000-4000-8000-000000000014",
      "kind": "investigation.case.updated",
      "payload": {
        "after": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example evidence review"
        },
        "before": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example delivery review"
        }
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    }
  ],
  "canManage": true,
  "case": {
    "clientId": "22222222-2222-4222-8222-222222222222",
    "closedAt": null,
    "confidence": 25,
    "createdAt": "2026-10-01T07:59:39.642Z",
    "flagCount": 2,
    "graphState": {
      "overlay": "all",
      "panelOpen": true,
      "positions": {},
      "selected": null
    },
    "id": "33333333-3333-4333-8333-333333333333",
    "ownerName": "Example owner",
    "ownerUserId": "00000000-0000-4000-8000-000000000008",
    "periodEnd": "2026-03-31",
    "periodStart": "2026-01-01",
    "projectId": "11111111-1111-4111-8111-111111111111",
    "status": "Investigating",
    "subtitle": "Establish the chain of evidence",
    "timeZone": "UTC",
    "title": "Example evidence review",
    "typology": null,
    "unresolvedFlagCount": 2,
    "updatedAt": "2026-10-01T07:59:39.777Z",
    "version": 2
  },
  "flags": [
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "44444444-4444-4444-8444-444444444444",
      "impact": "$1,800",
      "impactCents": 180000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000009"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
      "title": "Refunds fail for split tender added after lock",
      "typology": "added-after-lock",
      "version": 1
    },
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "00000000-0000-4000-8000-000000000010",
      "impact": "$4,800",
      "impactCents": 480000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000011"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
      "title": "Loyalty points at checkout added after lock",
      "typology": "added-after-lock",
      "version": 1
    }
  ],
  "notes": [],
  "packages": []
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request PATCH "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: example-operation-attempt-1' \
  --data-raw '{"version":1,"title":"Example evidence review"}'

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333", {
  method: "PATCH",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`,
  "Content-Type": "application/json",
  "Idempotency-Key": "example-operation-attempt-1"
},
  body: JSON.stringify({
  "version": 1,
  "title": "Example evidence review"
}),
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"],"Content-Type":"application/json","Idempotency-Key":"example-operation-attempt-1"}
response = requests.request("PATCH", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333", headers=headers, json=__import__("json").loads("{\"version\":1,\"title\":\"Example evidence review\"}"), timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Record a sourced flag disposition

Operation: investigations.disposition · POST /investigations/:caseId/flags/:flagId/disposition

Supply the current flag version, disposition and required rationale. The flag must belong to this case and tenant. Existing confidence/status calculation and append-only disposition history apply; inference does not become source evidence. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:write. Current creator action: investigations.manage. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "33333333-3333-4333-8333-333333333333",
    "in": "path",
    "name": "caseId",
    "required": true,
    "schema": {
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "44444444-4444-4444-8444-444444444444", "in": "path", "name": "flagId", "required": true, "schema": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "example-investigations.disposition", "in": "header", "name": "idempotency-key", "required": true, "schema": { "pattern": "^[\\x21-\\x7e]{1,200}
quot;
, "type": "string" } } ]

Request body schema:

View schema or synthetic response
JSON

{
  "content": {
    "application/json": {
      "examples": {
        "synthetic1": {
          "value": {
            "disposition": "inscope",
            "rationale": "Reviewed the synthetic delivery evidence",
            "version": 1
          }
        }
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "disposition": {
            "enum": [
              "inscope",
              "cr",
              "billable",
              "writeoff",
              "decision"
            ],
            "type": "string"
          },
          "rationale": {
            "maxLength": 2000,
            "minLength": 1,
            "type": "string"
          },
          "version": {
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "type": "integer"
          }
        },
        "required": [
          "version",
          "disposition",
          "rationale"
        ],
        "type": "object"
      }
    }
  },
  "required": true
}

Success statuses: 200. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "audit": [
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.645Z",
      "id": "00000000-0000-4000-8000-000000000012",
      "kind": "investigation.case.opened",
      "payload": {
        "clientId": "22222222-2222-4222-8222-222222222222",
        "periodEnd": "2026-03-31",
        "periodStart": "2026-01-01",
        "projectId": "11111111-1111-4111-8111-111111111111",
        "title": "Example delivery review",
        "typology": null
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.648Z",
      "id": "00000000-0000-4000-8000-000000000013",
      "kind": "investigation.flag.seeded",
      "payload": {
        "count": 2,
        "signalKeys": [
          "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
          "added-after-lock:wi-00000000-0000-4000-8000-000000000011"
        ]
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.780Z",
      "id": "00000000-0000-4000-8000-000000000014",
      "kind": "investigation.case.updated",
      "payload": {
        "after": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example evidence review"
        },
        "before": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example delivery review"
        }
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.797Z",
      "id": "00000000-0000-4000-8000-000000000015",
      "kind": "investigation.note.added",
      "payload": {
        "after": {
          "body": "Delivery evidence supports this observation; inference remains separate."
        },
        "noteId": "55555555-5555-4555-8555-555555555555",
        "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.814Z",
      "id": "00000000-0000-4000-8000-000000000017",
      "kind": "investigation.note.edited",
      "payload": {
        "after": {
          "body": "Correction: retain the evidence link and state the remaining uncertainty."
        },
        "before": {
          "body": "Delivery evidence supports this observation; inference remains separate."
        },
        "noteId": "55555555-5555-4555-8555-555555555555"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.852Z",
      "id": "00000000-0000-4000-8000-000000000019",
      "kind": "investigation.flag.dispositioned",
      "payload": {
        "after": {
          "disposition": "inscope",
          "rationale": "Reviewed the synthetic delivery evidence"
        },
        "before": {
          "disposition": null,
          "rationale": null
        },
        "flagId": "44444444-4444-4444-8444-444444444444",
        "nodeIds": [
          "wi-00000000-0000-4000-8000-000000000009"
        ],
        "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    }
  ],
  "canManage": true,
  "case": {
    "clientId": "22222222-2222-4222-8222-222222222222",
    "closedAt": null,
    "confidence": 25,
    "createdAt": "2026-10-01T07:59:39.642Z",
    "flagCount": 2,
    "graphState": {
      "overlay": "all",
      "panelOpen": true,
      "positions": {},
      "selected": null
    },
    "id": "33333333-3333-4333-8333-333333333333",
    "ownerName": "Example owner",
    "ownerUserId": "00000000-0000-4000-8000-000000000008",
    "periodEnd": "2026-03-31",
    "periodStart": "2026-01-01",
    "projectId": "11111111-1111-4111-8111-111111111111",
    "status": "Disposition",
    "subtitle": "Establish the chain of evidence",
    "timeZone": "UTC",
    "title": "Example evidence review",
    "typology": null,
    "unresolvedFlagCount": 1,
    "updatedAt": "2026-10-01T07:59:39.849Z",
    "version": 5
  },
  "flags": [
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
      "disposition": "inscope",
      "history": [
        {
          "actorName": "Example owner",
          "actorUserId": "00000000-0000-4000-8000-000000000008",
          "at": "2026-10-01T07:59:39.849Z",
          "auditEventId": "00000000-0000-4000-8000-000000000019",
          "from": null,
          "id": "00000000-0000-4000-8000-000000000018",
          "rationale": "Reviewed the synthetic delivery evidence",
          "to": "inscope"
        }
      ],
      "id": "44444444-4444-4444-8444-444444444444",
      "impact": "$1,800",
      "impactCents": 180000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000009"
      ],
      "rationale": "Reviewed the synthetic delivery evidence",
      "resolvedAt": "2026-10-01T07:59:39.849Z",
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
      "title": "Refunds fail for split tender added after lock",
      "typology": "added-after-lock",
      "version": 2
    },
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "00000000-0000-4000-8000-000000000010",
      "impact": "$4,800",
      "impactCents": 480000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000011"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
      "title": "Loyalty points at checkout added after lock",
      "typology": "added-after-lock",
      "version": 1
    }
  ],
  "notes": [
    {
      "authorName": "Example owner",
      "authorUserId": "00000000-0000-4000-8000-000000000008",
      "body": "Correction: retain the evidence link and state the remaining uncertainty.",
      "caseId": "33333333-3333-4333-8333-333333333333",
      "createdAt": "2026-10-01T07:59:39.794Z",
      "editedAt": "2026-10-01T07:59:39.812Z",
      "history": [
        {
          "at": "2026-10-01T07:59:39.812Z",
          "body": "Delivery evidence supports this observation; inference remains separate.",
          "editedByName": "Example owner",
          "editedByUserId": "00000000-0000-4000-8000-000000000008",
          "id": "00000000-0000-4000-8000-000000000016"
        }
      ],
      "id": "55555555-5555-4555-8555-555555555555",
      "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
    }
  ],
  "packages": []
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request POST "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/flags/44444444-4444-4444-8444-444444444444/disposition" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: example-operation-attempt-1' \
  --data-raw '{"version":1,"disposition":"inscope","rationale":"Reviewed the synthetic delivery evidence"}'

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/flags/44444444-4444-4444-8444-444444444444/disposition", {
  method: "POST",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`,
  "Content-Type": "application/json",
  "Idempotency-Key": "example-operation-attempt-1"
},
  body: JSON.stringify({
  "version": 1,
  "disposition": "inscope",
  "rationale": "Reviewed the synthetic delivery evidence"
}),
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"],"Content-Type":"application/json","Idempotency-Key":"example-operation-attempt-1"}
response = requests.request("POST", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/flags/44444444-4444-4444-8444-444444444444/disposition", headers=headers, json=__import__("json").loads("{\"version\":1,\"disposition\":\"inscope\",\"rationale\":\"Reviewed the synthetic delivery evidence\"}"), timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Disposition needs an actual flag in this case, its current version, and a supported decision/reason. Do not manufacture resolved evidence.

Add a note on supported delivery evidence

Operation: investigations.noteCreate · POST /investigations/:caseId/notes

Attach a bounded note to a supported delivery node of this case's project. Legacy graph IDs must exist in the project graph; canonical evidence keys must name a live canonical entity. A person/client cannot be the subject. investigation.note permission is distinct from management. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:write. Current creator action: investigations.note. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "33333333-3333-4333-8333-333333333333",
    "in": "path",
    "name": "caseId",
    "required": true,
    "schema": {
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "example-investigations.noteCreate", "in": "header", "name": "idempotency-key", "required": true, "schema": { "pattern": "^[\\x21-\\x7e]{1,200}
quot;
, "type": "string" } } ]

Request body schema:

View schema or synthetic response
JSON

{
  "content": {
    "application/json": {
      "examples": {
        "synthetic1": {
          "value": {
            "body": "Delivery evidence supports this observation; inference remains separate.",
            "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
          }
        }
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "body": {
            "maxLength": 4000,
            "minLength": 1,
            "type": "string"
          },
          "targetNodeId": {
            "maxLength": 900,
            "minLength": 1,
            "type": "string"
          }
        },
        "required": [
          "targetNodeId",
          "body"
        ],
        "type": "object"
      }
    }
  },
  "required": true
}

Success statuses: 201. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "audit": [
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.645Z",
      "id": "00000000-0000-4000-8000-000000000012",
      "kind": "investigation.case.opened",
      "payload": {
        "clientId": "22222222-2222-4222-8222-222222222222",
        "periodEnd": "2026-03-31",
        "periodStart": "2026-01-01",
        "projectId": "11111111-1111-4111-8111-111111111111",
        "title": "Example delivery review",
        "typology": null
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.648Z",
      "id": "00000000-0000-4000-8000-000000000013",
      "kind": "investigation.flag.seeded",
      "payload": {
        "count": 2,
        "signalKeys": [
          "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
          "added-after-lock:wi-00000000-0000-4000-8000-000000000011"
        ]
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.780Z",
      "id": "00000000-0000-4000-8000-000000000014",
      "kind": "investigation.case.updated",
      "payload": {
        "after": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example evidence review"
        },
        "before": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example delivery review"
        }
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.797Z",
      "id": "00000000-0000-4000-8000-000000000015",
      "kind": "investigation.note.added",
      "payload": {
        "after": {
          "body": "Delivery evidence supports this observation; inference remains separate."
        },
        "noteId": "55555555-5555-4555-8555-555555555555",
        "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    }
  ],
  "canManage": true,
  "case": {
    "clientId": "22222222-2222-4222-8222-222222222222",
    "closedAt": null,
    "confidence": 25,
    "createdAt": "2026-10-01T07:59:39.642Z",
    "flagCount": 2,
    "graphState": {
      "overlay": "all",
      "panelOpen": true,
      "positions": {},
      "selected": null
    },
    "id": "33333333-3333-4333-8333-333333333333",
    "ownerName": "Example owner",
    "ownerUserId": "00000000-0000-4000-8000-000000000008",
    "periodEnd": "2026-03-31",
    "periodStart": "2026-01-01",
    "projectId": "11111111-1111-4111-8111-111111111111",
    "status": "Investigating",
    "subtitle": "Establish the chain of evidence",
    "timeZone": "UTC",
    "title": "Example evidence review",
    "typology": null,
    "unresolvedFlagCount": 2,
    "updatedAt": "2026-10-01T07:59:39.794Z",
    "version": 3
  },
  "flags": [
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "44444444-4444-4444-8444-444444444444",
      "impact": "$1,800",
      "impactCents": 180000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000009"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
      "title": "Refunds fail for split tender added after lock",
      "typology": "added-after-lock",
      "version": 1
    },
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "00000000-0000-4000-8000-000000000010",
      "impact": "$4,800",
      "impactCents": 480000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000011"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
      "title": "Loyalty points at checkout added after lock",
      "typology": "added-after-lock",
      "version": 1
    }
  ],
  "notes": [
    {
      "authorName": "Example owner",
      "authorUserId": "00000000-0000-4000-8000-000000000008",
      "body": "Delivery evidence supports this observation; inference remains separate.",
      "caseId": "33333333-3333-4333-8333-333333333333",
      "createdAt": "2026-10-01T07:59:39.794Z",
      "editedAt": null,
      "history": [],
      "id": "55555555-5555-4555-8555-555555555555",
      "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
    }
  ],
  "packages": []
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request POST "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/notes" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: example-operation-attempt-1' \
  --data-raw '{"targetNodeId":"wi-00000000-0000-4000-8000-000000000009","body":"Delivery evidence supports this observation; inference remains separate."}'

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/notes", {
  method: "POST",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`,
  "Content-Type": "application/json",
  "Idempotency-Key": "example-operation-attempt-1"
},
  body: JSON.stringify({
  "targetNodeId": "wi-00000000-0000-4000-8000-000000000009",
  "body": "Delivery evidence supports this observation; inference remains separate."
}),
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"],"Content-Type":"application/json","Idempotency-Key":"example-operation-attempt-1"}
response = requests.request("POST", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/notes", headers=headers, json=__import__("json").loads("{\"targetNodeId\":\"wi-00000000-0000-4000-8000-000000000009\",\"body\":\"Delivery evidence supports this observation; inference remains separate.\"}"), timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Target an entity in the case graph or supported canonical evidence; invented/foreign entities are refused.

Correct a note with retained history

Operation: investigations.noteUpdate · PATCH /investigations/:caseId/notes/:noteId

Supply body and the observed case version to prevent stale/concurrent edits. Only the original author or a primary owner/admin can edit the note. Previous bodies and their audit links remain in history. Note and case must match. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:write. Current creator action: investigations.note. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "33333333-3333-4333-8333-333333333333",
    "in": "path",
    "name": "caseId",
    "required": true,
    "schema": {
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "55555555-5555-4555-8555-555555555555", "in": "path", "name": "noteId", "required": true, "schema": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "example-investigations.noteUpdate", "in": "header", "name": "idempotency-key", "required": true, "schema": { "pattern": "^[\\x21-\\x7e]{1,200}
quot;
, "type": "string" } } ]

Request body schema:

View schema or synthetic response
JSON

{
  "content": {
    "application/json": {
      "examples": {
        "synthetic1": {
          "value": {
            "body": "Correction: retain the evidence link and state the remaining uncertainty.",
            "version": 3
          }
        }
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "body": {
            "maxLength": 4000,
            "minLength": 1,
            "type": "string"
          },
          "version": {
            "exclusiveMinimum": 0,
            "maximum": 9007199254740991,
            "type": "integer"
          }
        },
        "required": [
          "body",
          "version"
        ],
        "type": "object"
      }
    }
  },
  "required": true
}

Success statuses: 200. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "audit": [
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.645Z",
      "id": "00000000-0000-4000-8000-000000000012",
      "kind": "investigation.case.opened",
      "payload": {
        "clientId": "22222222-2222-4222-8222-222222222222",
        "periodEnd": "2026-03-31",
        "periodStart": "2026-01-01",
        "projectId": "11111111-1111-4111-8111-111111111111",
        "title": "Example delivery review",
        "typology": null
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.648Z",
      "id": "00000000-0000-4000-8000-000000000013",
      "kind": "investigation.flag.seeded",
      "payload": {
        "count": 2,
        "signalKeys": [
          "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
          "added-after-lock:wi-00000000-0000-4000-8000-000000000011"
        ]
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.780Z",
      "id": "00000000-0000-4000-8000-000000000014",
      "kind": "investigation.case.updated",
      "payload": {
        "after": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example evidence review"
        },
        "before": {
          "graphState": {
            "overlay": "all",
            "panelOpen": true,
            "positions": {},
            "selected": null
          },
          "status": "Investigating",
          "subtitle": "Establish the chain of evidence",
          "title": "Example delivery review"
        }
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.797Z",
      "id": "00000000-0000-4000-8000-000000000015",
      "kind": "investigation.note.added",
      "payload": {
        "after": {
          "body": "Delivery evidence supports this observation; inference remains separate."
        },
        "noteId": "55555555-5555-4555-8555-555555555555",
        "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    },
    {
      "actorName": "Example owner",
      "actorUserId": "00000000-0000-4000-8000-000000000008",
      "createdAt": "2026-10-01T07:59:39.814Z",
      "id": "00000000-0000-4000-8000-000000000017",
      "kind": "investigation.note.edited",
      "payload": {
        "after": {
          "body": "Correction: retain the evidence link and state the remaining uncertainty."
        },
        "before": {
          "body": "Delivery evidence supports this observation; inference remains separate."
        },
        "noteId": "55555555-5555-4555-8555-555555555555"
      },
      "subjectId": "33333333-3333-4333-8333-333333333333",
      "subjectKind": "investigation_case"
    }
  ],
  "canManage": true,
  "case": {
    "clientId": "22222222-2222-4222-8222-222222222222",
    "closedAt": null,
    "confidence": 25,
    "createdAt": "2026-10-01T07:59:39.642Z",
    "flagCount": 2,
    "graphState": {
      "overlay": "all",
      "panelOpen": true,
      "positions": {},
      "selected": null
    },
    "id": "33333333-3333-4333-8333-333333333333",
    "ownerName": "Example owner",
    "ownerUserId": "00000000-0000-4000-8000-000000000008",
    "periodEnd": "2026-03-31",
    "periodStart": "2026-01-01",
    "projectId": "11111111-1111-4111-8111-111111111111",
    "status": "Investigating",
    "subtitle": "Establish the chain of evidence",
    "timeZone": "UTC",
    "title": "Example evidence review",
    "typology": null,
    "unresolvedFlagCount": 2,
    "updatedAt": "2026-10-01T07:59:39.812Z",
    "version": 4
  },
  "flags": [
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "44444444-4444-4444-8444-444444444444",
      "impact": "$1,800",
      "impactCents": 180000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000009"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
      "title": "Refunds fail for split tender added after lock",
      "typology": "added-after-lock",
      "version": 1
    },
    {
      "caseId": "33333333-3333-4333-8333-333333333333",
      "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
      "disposition": null,
      "history": [],
      "id": "00000000-0000-4000-8000-000000000010",
      "impact": "$4,800",
      "impactCents": 480000,
      "nodeIds": [
        "wi-00000000-0000-4000-8000-000000000011"
      ],
      "rationale": null,
      "resolvedAt": null,
      "severity": "amber",
      "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
      "title": "Loyalty points at checkout added after lock",
      "typology": "added-after-lock",
      "version": 1
    }
  ],
  "notes": [
    {
      "authorName": "Example owner",
      "authorUserId": "00000000-0000-4000-8000-000000000008",
      "body": "Correction: retain the evidence link and state the remaining uncertainty.",
      "caseId": "33333333-3333-4333-8333-333333333333",
      "createdAt": "2026-10-01T07:59:39.794Z",
      "editedAt": "2026-10-01T07:59:39.812Z",
      "history": [
        {
          "at": "2026-10-01T07:59:39.812Z",
          "body": "Delivery evidence supports this observation; inference remains separate.",
          "editedByName": "Example owner",
          "editedByUserId": "00000000-0000-4000-8000-000000000008",
          "id": "00000000-0000-4000-8000-000000000016"
        }
      ],
      "id": "55555555-5555-4555-8555-555555555555",
      "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
    }
  ],
  "packages": []
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request PATCH "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/notes/55555555-5555-4555-8555-555555555555" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: example-operation-attempt-1' \
  --data-raw '{"body":"Correction: retain the evidence link and state the remaining uncertainty.","version":3}'

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/notes/55555555-5555-4555-8555-555555555555", {
  method: "PATCH",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`,
  "Content-Type": "application/json",
  "Idempotency-Key": "example-operation-attempt-1"
},
  body: JSON.stringify({
  "body": "Correction: retain the evidence link and state the remaining uncertainty.",
  "version": 3
}),
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"],"Content-Type":"application/json","Idempotency-Key":"example-operation-attempt-1"}
response = requests.request("PATCH", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/notes/55555555-5555-4555-8555-555555555555", headers=headers, json=__import__("json").loads("{\"body\":\"Correction: retain the evidence link and state the remaining uncertainty.\",\"version\":3}"), timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Retain the note ID and read the current case.version for its update. Author restrictions apply; write scope alone does not authorize editing another person's note.

Freeze an evidence package

Operation: investigations.packageCreate · POST /investigations/:caseId/packages

Create a memo, cr or qbr from frozen facts/custody/claims and baseline/graph provenance. A final package requires every flag dispositioned and files the case; a draft is watermarked and cannot attach. Existing opt-in/provider/budget guards and slot-only prose rules apply; unavailable/refused AI falls back to template with truthful engine. Durable operation IDs deduplicate package persistence and provider metering. An uncertain outcome is reconciled by stored package ID; it is never blindly generated again. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:write. Current creator action: investigations.manage. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "33333333-3333-4333-8333-333333333333",
    "in": "path",
    "name": "caseId",
    "required": true,
    "schema": {
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "example-investigations.packageCreate", "in": "header", "name": "idempotency-key", "required": true, "schema": { "pattern": "^[\\x21-\\x7e]{1,200}
quot;
, "type": "string" } } ]

Request body schema:

View schema or synthetic response
JSON

{
  "content": {
    "application/json": {
      "examples": {
        "synthetic1": {
          "value": {
            "draft": false,
            "kind": "memo"
          }
        }
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "draft": {
            "default": false,
            "type": "boolean"
          },
          "kind": {
            "enum": [
              "memo",
              "cr",
              "qbr"
            ],
            "type": "string"
          }
        },
        "required": [
          "kind"
        ],
        "type": "object"
      }
    }
  },
  "required": true
}

Success statuses: 201. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "gate": {
    "ok": true,
    "total": 2,
    "unresolved": 0
  },
  "package": {
    "attachedAt": null,
    "caseId": "33333333-3333-4333-8333-333333333333",
    "contentHash": "3de1f3ff28b41bca9750f4ecc4583b697a3ce58bd5785ea06a00c9c7b3719bf4",
    "createdAt": "2026-10-01T07:59:40.043Z",
    "createdByName": "Example owner",
    "createdByUserId": "00000000-0000-4000-8000-000000000008",
    "id": "66666666-6666-4666-8666-666666666666",
    "kind": "memo",
    "reportId": null,
    "reportSnapshotId": null,
    "snapshot": {
      "case": {
        "agencyName": "Synthetic investigations",
        "clientName": "example Retail",
        "confidence": 25,
        "id": "33333333-3333-4333-8333-333333333333",
        "periodEnd": "2026-03-31",
        "periodLabel": "Q1 2026",
        "periodStart": "2026-01-01",
        "projectName": "example Checkout Replatform",
        "status": "Filed",
        "subtitle": "Establish the chain of evidence",
        "title": "Example evidence review",
        "typology": null
      },
      "claims": [
        {
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000019"
          ],
          "id": "claim:44444444-4444-4444-8444-444444444444",
          "nodeIds": [
            "wi-00000000-0000-4000-8000-000000000009"
          ],
          "text": "Refunds fail for split tender added after lock — In scope: Reviewed the synthetic delivery evidence ($1,800)"
        },
        {
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000020"
          ],
          "id": "claim:00000000-0000-4000-8000-000000000010",
          "nodeIds": [
            "wi-00000000-0000-4000-8000-000000000011"
          ],
          "text": "Loyalty points at checkout added after lock — In scope: Reviewed the synthetic delivery evidence ($4,800)"
        }
      ],
      "custody": {
        "wi-00000000-0000-4000-8000-000000000009": [
          {
            "id": "EXAMPLE-42",
            "kind": "jira",
            "meta": "Added Feb 20 · post-lock",
            "t": "Refunds fail for split tender"
          },
          {
            "id": "MR !7",
            "kind": "pr",
            "meta": "Merged Mar 02",
            "t": "Split tender refund path"
          }
        ],
        "wi-00000000-0000-4000-8000-000000000011": [
          {
            "id": "EXAMPLE-77",
            "kind": "jira",
            "meta": "Added Mar 05 · post-lock",
            "t": "Loyalty points at checkout"
          }
        ]
      },
      "draft": false,
      "engine": "template",
      "flags": [
        {
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000019"
          ],
          "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
          "disposition": "inscope",
          "dispositionLabel": "In scope",
          "evidenceMissing": false,
          "id": "44444444-4444-4444-8444-444444444444",
          "impact": "$1,800",
          "impactCents": 180000,
          "nodeIds": [
            "wi-00000000-0000-4000-8000-000000000009"
          ],
          "rationale": "Reviewed the synthetic delivery evidence",
          "resolvedAt": "2026-10-01T07:59:39.849Z",
          "severity": "amber",
          "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
          "title": "Refunds fail for split tender added after lock",
          "typology": "added-after-lock"
        },
        {
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000020"
          ],
          "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
          "disposition": "inscope",
          "dispositionLabel": "In scope",
          "evidenceMissing": false,
          "id": "00000000-0000-4000-8000-000000000010",
          "impact": "$4,800",
          "impactCents": 480000,
          "nodeIds": [
            "wi-00000000-0000-4000-8000-000000000011"
          ],
          "rationale": "Reviewed the synthetic delivery evidence",
          "resolvedAt": "2026-10-01T07:59:39.890Z",
          "severity": "amber",
          "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
          "title": "Loyalty points at checkout added after lock",
          "typology": "added-after-lock"
        }
      ],
      "generatedAt": "2026-10-01T07:59:40.042Z",
      "kind": "memo",
      "notes": [
        {
          "at": "2026-10-01T07:59:39.794Z",
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000015",
            "00000000-0000-4000-8000-000000000017"
          ],
          "authorName": "Example owner",
          "body": "Correction: retain the evidence link and state the remaining uncertainty.",
          "id": "55555555-5555-4555-8555-555555555555",
          "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
        }
      ],
      "prose": {
        "sections": [
          {
            "body": "Evidence is traced node by node from the scope locked on 2026-01-01 through 1 release; case confidence stands at 25%.",
            "heading": "What moved after the lock"
          },
          {
            "body": "Confirmed in scope and absorbed: $6,600.",
            "heading": "Dispositions"
          },
          {
            "body": "Each claim links back to the source records and to the audit events that produced it. The subject throughout is the delivery and the scope, never an individual.",
            "heading": "How to read this memo"
          }
        ],
        "summary": "$6,600 of delivery investment on example Checkout Replatform for example Retail during Q1 2026 is accounted for line by line below. Every one of the 2 flags carries a disposition with a rationale.",
        "title": "Invoice-defense memo · example Checkout Replatform · Q1 2026"
      },
      "provenance": {
        "graphBuild": null,
        "lock": {
          "approvalRef": null,
          "authority": null,
          "effectiveAt": "2026-01-02T00:00:00.000Z",
          "lockedOn": "2026-01-01",
          "lockId": null,
          "memberCount": null,
          "provenance": "engagement_starts_on",
          "reconstructed": true,
          "resolverVersion": "lock-resolver@1",
          "timeZone": "UTC",
          "version": null
        }
      },
      "version": 1,
      "watermark": null
    },
    "status": "final"
  }
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request POST "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/packages" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: example-operation-attempt-1' \
  --data-raw '{"kind":"memo","draft":false}'

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/packages", {
  method: "POST",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`,
  "Content-Type": "application/json",
  "Idempotency-Key": "example-operation-attempt-1"
},
  body: JSON.stringify({
  "kind": "memo",
  "draft": false
}),
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"],"Content-Type":"application/json","Idempotency-Key":"example-operation-attempt-1"}
response = requests.request("POST", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/packages", headers=headers, json=__import__("json").loads("{\"kind\":\"memo\",\"draft\":false}"), timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Inspect draft state, mode, warnings, provenance and immutable integrity hash. A draft memo may use a template when a provider is unavailable; this does not prove live AI success. Final packages enforce review gates. Reconcile pending external work under its original attempt key rather than repeating provider work.

Attach a final package to a report snapshot

Operation: investigations.packageAttach · POST /investigations/:caseId/packages/:packageId/attach

Requires both investigations.manage and reports.create with current project access, including on replay. Final package, source case and destination report must share tenant/project. Attach creates a new immutable report snapshot with frozen package evidence, retaining previous snapshots. Draft/already attached/stale destinations conflict. No email, delivery or public sharing is performed. Explicit scope plus current creator actions, tenant identity and RLS apply. Identical successful retries preserve the original response without repeated rows/history/audit; changed input conflicts. Current authorization applies again on replay. Case deletion and new AI grouping/interpretation are unavailable.

Required key scope: investigations:write. Current creator action: investigations.manage. Eligible plans: free, starter, growth, scale; legacy contracts: free, entry, growth. stable contract. These badges do not override current role, evidence window, quotas or target ownership.

  • Cases, flags, notes, packages and attached reports belong to the same authorized tenant/project and their declared parent.

  • Case/flag changes require the observed version; API note edits additionally carry the observed case version.

  • Narrative is inference around sourced facts; numerical facts are deterministic and package custody/provenance is frozen.

  • Uncertain external outcomes retain a durable operation for reconciliation; use the original idempotency header, never issue an automatic new request.

Parameters (required flags, defaults, units and bounds are the canonical schema):

View schema or synthetic response
JSON

[
  {
    "example": "33333333-3333-4333-8333-333333333333",
    "in": "path",
    "name": "caseId",
    "required": true,
    "schema": {
      "format": "uuid",
      "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "66666666-6666-4666-8666-666666666666", "in": "path", "name": "packageId", "required": true, "schema": { "format": "uuid", "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, { "example": "example-investigations.packageAttach", "in": "header", "name": "idempotency-key", "required": true, "schema": { "pattern": "^[\\x21-\\x7e]{1,200}
quot;
, "type": "string" } } ]

Request body schema:

View schema or synthetic response
JSON

{
  "content": {
    "application/json": {
      "examples": {
        "synthetic1": {
          "value": {
            "reportId": "77777777-7777-4777-8777-777777777777"
          }
        }
      },
      "schema": {
        "$schema": "https://json-schema.org/draft/2020-12/schema",
        "properties": {
          "reportId": {
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)
quot;
, "type": "string" } }, "required": [ "reportId" ], "type": "object" } } }, "required": true }

Success statuses: 200. The JSON response is the saved/read representation. Synthetic examples below show shape, not customer evidence.

Synthetic response:

View schema or synthetic response
JSON

{
  "package": {
    "attachedAt": "2026-10-01T07:59:40.228Z",
    "caseId": "33333333-3333-4333-8333-333333333333",
    "contentHash": "3de1f3ff28b41bca9750f4ecc4583b697a3ce58bd5785ea06a00c9c7b3719bf4",
    "createdAt": "2026-10-01T07:59:40.043Z",
    "createdByName": "Example owner",
    "createdByUserId": "00000000-0000-4000-8000-000000000008",
    "id": "66666666-6666-4666-8666-666666666666",
    "kind": "memo",
    "reportId": "77777777-7777-4777-8777-777777777777",
    "reportSnapshotId": "00000000-0000-4000-8000-000000000021",
    "snapshot": {
      "case": {
        "agencyName": "Synthetic investigations",
        "clientName": "example Retail",
        "confidence": 25,
        "id": "33333333-3333-4333-8333-333333333333",
        "periodEnd": "2026-03-31",
        "periodLabel": "Q1 2026",
        "periodStart": "2026-01-01",
        "projectName": "example Checkout Replatform",
        "status": "Filed",
        "subtitle": "Establish the chain of evidence",
        "title": "Example evidence review",
        "typology": null
      },
      "claims": [
        {
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000019"
          ],
          "id": "claim:44444444-4444-4444-8444-444444444444",
          "nodeIds": [
            "wi-00000000-0000-4000-8000-000000000009"
          ],
          "text": "Refunds fail for split tender added after lock — In scope: Reviewed the synthetic delivery evidence ($1,800)"
        },
        {
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000020"
          ],
          "id": "claim:00000000-0000-4000-8000-000000000010",
          "nodeIds": [
            "wi-00000000-0000-4000-8000-000000000011"
          ],
          "text": "Loyalty points at checkout added after lock — In scope: Reviewed the synthetic delivery evidence ($4,800)"
        }
      ],
      "custody": {
        "wi-00000000-0000-4000-8000-000000000009": [
          {
            "id": "EXAMPLE-42",
            "kind": "jira",
            "meta": "Added Feb 20 · post-lock",
            "t": "Refunds fail for split tender"
          },
          {
            "id": "MR !7",
            "kind": "pr",
            "meta": "Merged Mar 02",
            "t": "Split tender refund path"
          }
        ],
        "wi-00000000-0000-4000-8000-000000000011": [
          {
            "id": "EXAMPLE-77",
            "kind": "jira",
            "meta": "Added Mar 05 · post-lock",
            "t": "Loyalty points at checkout"
          }
        ]
      },
      "draft": false,
      "engine": "template",
      "flags": [
        {
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000019"
          ],
          "detail": "EXAMPLE-42 entered the cycle on Feb 20, after the Jan 01 baseline.",
          "disposition": "inscope",
          "dispositionLabel": "In scope",
          "evidenceMissing": false,
          "id": "44444444-4444-4444-8444-444444444444",
          "impact": "$1,800",
          "impactCents": 180000,
          "nodeIds": [
            "wi-00000000-0000-4000-8000-000000000009"
          ],
          "rationale": "Reviewed the synthetic delivery evidence",
          "resolvedAt": "2026-10-01T07:59:39.849Z",
          "severity": "amber",
          "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000009",
          "title": "Refunds fail for split tender added after lock",
          "typology": "added-after-lock"
        },
        {
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000020"
          ],
          "detail": "EXAMPLE-77 entered the cycle on Mar 05, after the Jan 01 baseline.",
          "disposition": "inscope",
          "dispositionLabel": "In scope",
          "evidenceMissing": false,
          "id": "00000000-0000-4000-8000-000000000010",
          "impact": "$4,800",
          "impactCents": 480000,
          "nodeIds": [
            "wi-00000000-0000-4000-8000-000000000011"
          ],
          "rationale": "Reviewed the synthetic delivery evidence",
          "resolvedAt": "2026-10-01T07:59:39.890Z",
          "severity": "amber",
          "signalKey": "added-after-lock:wi-00000000-0000-4000-8000-000000000011",
          "title": "Loyalty points at checkout added after lock",
          "typology": "added-after-lock"
        }
      ],
      "generatedAt": "2026-10-01T07:59:40.042Z",
      "kind": "memo",
      "notes": [
        {
          "at": "2026-10-01T07:59:39.794Z",
          "auditEventIds": [
            "00000000-0000-4000-8000-000000000015",
            "00000000-0000-4000-8000-000000000017"
          ],
          "authorName": "Example owner",
          "body": "Correction: retain the evidence link and state the remaining uncertainty.",
          "id": "55555555-5555-4555-8555-555555555555",
          "targetNodeId": "wi-00000000-0000-4000-8000-000000000009"
        }
      ],
      "prose": {
        "sections": [
          {
            "body": "Evidence is traced node by node from the scope locked on 2026-01-01 through 1 release; case confidence stands at 25%.",
            "heading": "What moved after the lock"
          },
          {
            "body": "Confirmed in scope and absorbed: $6,600.",
            "heading": "Dispositions"
          },
          {
            "body": "Each claim links back to the source records and to the audit events that produced it. The subject throughout is the delivery and the scope, never an individual.",
            "heading": "How to read this memo"
          }
        ],
        "summary": "$6,600 of delivery investment on example Checkout Replatform for example Retail during Q1 2026 is accounted for line by line below. Every one of the 2 flags carries a disposition with a rationale.",
        "title": "Invoice-defense memo · example Checkout Replatform · Q1 2026"
      },
      "provenance": {
        "graphBuild": null,
        "lock": {
          "approvalRef": null,
          "authority": null,
          "effectiveAt": "2026-01-02T00:00:00.000Z",
          "lockedOn": "2026-01-01",
          "lockId": null,
          "memberCount": null,
          "provenance": "engagement_starts_on",
          "reconstructed": true,
          "resolverVersion": "lock-resolver@1",
          "timeZone": "UTC",
          "version": null
        }
      },
      "version": 1,
      "watermark": null
    },
    "status": "final"
  },
  "reportId": "77777777-7777-4777-8777-777777777777",
  "reportSnapshotId": "00000000-0000-4000-8000-000000000021"
}

Use IDs and versions from your own preceding responses. Replace the synthetic UUIDs, dates and names in these independent examples. Set SCOPEWORTH_API_BASE and SCOPEWORTH_API_KEY only on your server.

cURL

cURL / shell
curl --request POST "$SCOPEWORTH_API_BASE/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/packages/66666666-6666-4666-8666-666666666666/attach" \
  --header "Authorization: Bearer $SCOPEWORTH_API_KEY" \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: example-operation-attempt-1' \
  --data-raw '{"reportId":"77777777-7777-4777-8777-777777777777"}'

JavaScript fetch

JavaScript
// Run on your server. API_BASE ends in /api/v1 (combined host) or /v1 (verified cell).
const response = await fetch(process.env.SCOPEWORTH_API_BASE + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/packages/66666666-6666-4666-8666-666666666666/attach", {
  method: "POST",
  headers: {
  "Authorization": `Bearer ${process.env.SCOPEWORTH_API_KEY}`,
  "Content-Type": "application/json",
  "Idempotency-Key": "example-operation-attempt-1"
},
  body: JSON.stringify({
  "reportId": "77777777-7777-4777-8777-777777777777"
}),
});
if (!response.ok) throw new Error(`ScopeWorth refused request: ${response.status}`);
const result = await response.json();

Python requests

Python
import os, requests
headers = {"Authorization":"Bearer " + os.environ["SCOPEWORTH_API_KEY"],"Content-Type":"application/json","Idempotency-Key":"example-operation-attempt-1"}
response = requests.request("POST", os.environ["SCOPEWORTH_API_BASE"] + "/organizations/example-org/workspaces/example-workspace/investigations/33333333-3333-4333-8333-333333333333/packages/66666666-6666-4666-8666-666666666666/attach", headers=headers, json=__import__("json").loads("{\"reportId\":\"77777777-7777-4777-8777-777777777777\"}"), timeout=30)
response.raise_for_status()
result = response.json()

For refusals, follow error recovery. A scope or plan badge is eligibility, not proof of authorization or available evidence. Read current directory IDs and versions before correcting a request. Keep an idempotency key for one unchanged mutation attempt; never blindly retry uncertain external work.

Attach only to a same-workspace/project report snapshot with current report-create permission. Attachment does not make a draft final. Later case edits do not mutate frozen package content. See reports.

Search documentation

Enter a word or phrase to search documentation.